Что такое SQL-инъекция с EXTRACTVALUE?
Встречая в логах или в поле ввода строку вида %')))) AND EXTRACTVALUE(7002,CONCAT(0x7e,((SELECT (ELT(7002=7002,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на базы данных MySQL. Злоумышленник пытается внедрить вредоносный код в SQL-запрос, чтобы получить доступ к данным или вызвать ошибку, раскрывающую информацию.
В данной статье мы подробно разберём этот payload, объясним, как работает функция EXTRACTVALUE, и расскажем, как защититься от подобных атак.
Как работает SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Она возникает, когда пользовательские данные попадают в SQL-запрос без должной обработки. В результате атакующий может изменить логику запроса, выполнить произвольные команды или извлечь конфиденциальную информацию.
Пример уязвимого кода на PHP:
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = '$id'";
Если передать в параметр id строку 1' OR '1'='1, запрос вернёт всех пользователей. Более сложные payload'ы позволяют извлекать данные посимвольно или вызывать ошибки для получения информации.
Разбор payload с EXTRACTVALUE
Рассмотрим строку:
%')))) AND EXTRACTVALUE(7002,CONCAT(0x7e,((SELECT (ELT(7002=7002,1)))),0x7e))-- -
Разберём её по частям:
%'))))— попытка закрыть кавычки и скобки в исходном запросе, чтобы внедрить свой код. Символ%может быть частью URL-кодирования.AND EXTRACTVALUE(7002, ...)— вызов функции EXTRACTVALUE с двумя аргументами: число 7002 и строка, формируемая черезCONCAT.CONCAT(0x7e, ((SELECT (ELT(7002=7002,1)))), 0x7e)— конкатенация символа~(0x7e), результата подзапроса и снова~.ELT(7002=7002,1)— функция ELT возвращает N-й элемент из списка. Здесь условие7002=7002истинно (1), поэтому возвращается первый элемент — число 1.-- -— комментарий, который игнорирует остаток исходного запроса.
Таким образом, payload заставляет базу данных выполнить EXTRACTVALUE с некорректным XPath-выражением (символ ~ не является допустимым), что приводит к ошибке. В сообщении об ошибке MySQL выводит переданную строку, в данном случае ~1~. Если вместо 1 подставить подзапрос, например (SELECT version()), то в ошибке появится версия СУБД. Это классическая error-based SQL-инъекция.
Функция EXTRACTVALUE в MySQL
Функция EXTRACTVALUE() предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис:
EXTRACTVALUE(xml_frag, xpath_expr)
Она принимает фрагмент XML-разметки и XPath-локатор, возвращая текст первого узла, соответствующего выражению. Например:
SELECT EXTRACTVALUE('текст', '/a/b');
-- Результат: текст
Однако при передаче некорректного XPath (например, содержащего символ ~) MySQL генерирует ошибку XPATH syntax error, в тексте которой отображается переданное значение. Это и используется злоумышленниками для извлечения данных.
Начиная с MySQL 5.7.9 функция EXTRACTVALUE считается устаревшей, а в MySQL 8.0 удалена. Тем не менее, многие системы до сих пор работают на старых версиях, поэтому атака остаётся актуальной.
Цели и последствия атаки
Основные цели злоумышленника:
- Получение версии базы данных, имён таблиц и колонок.
- Извлечение учётных данных пользователей, хешей паролей, персональной информации.
- Модификация или удаление данных.
- Обход аутентификации и получение прав администратора.
Успешная SQL-инъекция может привести к полной компрометации базы данных, утечке конфиденциальной информации и финансовым потерям.
Как защититься от SQL-инъекций?
Основные меры защиты:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не смешиваются с кодом запроса.
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string()(для MySQL). - Валидация и фильтрация входных данных — проверка типов, длины, допустимых символов.
- Ограничение прав пользователя базы данных — не использовать root для веб-приложений.
- Регулярное обновление СУБД и фреймворков — устранение известных уязвимостей.
- Использование WAF (Web Application Firewall) — для блокировки подозрительных запросов.
Также рекомендуется проводить аудит кода и пентесты для выявления уязвимостей.
Пример безопасного кода на PHP
Вместо конкатенации используйте подготовленные выражения:
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $id]);
$user = $stmt->fetch();
Такой подход гарантирует, что пользовательский ввод не изменит структуру запроса.
Заключение
Строка с EXTRACTVALUE — это не случайный набор символов, а тщательно сконструированный payload для эксплуатации уязвимости SQL-инъекции в MySQL. Понимание принципов работы таких атак помогает разработчикам и администраторам своевременно принимать меры защиты. Помните: безопасность базы данных — это не только техническая, но и организационная задача, требующая постоянного внимания.
Комментарии
—Войдите, чтобы оставить комментарий