Что это за строка?
Строка %' AND EXTRACTVALUE (2015,CONCAT (0x7e, ( (SELECT (ELT (2015=2015,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для внедрения в уязвимый SQL-запрос с целью заставить базу данных выдать сообщение об ошибке, содержащее полезные данные. Подобные конструкции часто используются пентестерами и злоумышленниками для извлечения информации из базы данных, когда прямой вывод данных невозможен.
В запросе пользователя фигурирует вариант с числом 4442, но суть от этого не меняется: это попытка эксплуатации функции EXTRACTVALUE() через внедрение в параметр, который не проходит должную фильтрацию. Давайте разберём, как это работает и почему это опасно.
Как работает EXTRACTVALUE в MySQL
Функция EXTRACTVALUE() принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath. Она возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению. Например, запрос:
SELECT EXTRACTVALUE('<a>текст</a>', '/a');
вернёт текст. Однако если XPath-выражение некорректно, MySQL генерирует ошибку XPATH syntax error. Именно на этом строится атака: злоумышленник конструирует XPath так, чтобы в тексте ошибки отобразились данные из базы.
Разбор полезной нагрузки
Рассмотрим строку по частям:
%'— закрывающая кавычка (в URL-кодировке), которая завершает строковый литерал в уязвимом запросе.AND EXTRACTVALUE(2015, CONCAT(0x7e, ((SELECT (ELT(2015=2015,1)))), 0x7e))— вызов функции с двумя аргументами. Первый аргумент (2015) — произвольное число, которое будет использовано как XML-фрагмент. Второй аргумент — результат конкатенации символа~(0x7e), подзапроса и снова~.-- -— комментарий, который обрезает остаток оригинального SQL-запроса.
Подзапрос SELECT (ELT(2015=2015,1)) всегда возвращает 1, так как условие 2015=2015 истинно. Это тестовый пример: в реальной атаке вместо этого подзапроса подставляется выражение для извлечения данных, например, версии СУБД, имени базы или хешей паролей.
Функция CONCAT объединяет тильды и результат подзапроса в строку вида ~1~. Затем EXTRACTVALUE пытается интерпретировать эту строку как XPath-выражение. Поскольку строка не является валидным XPath, MySQL выбрасывает ошибку, в тексте которой фигурирует переданная строка. Таким образом, данные из подзапроса попадают в сообщение об ошибке, которое злоумышленник может прочитать.
Почему используется 0x7e?
Символ ~ (тильда) выбран в качестве разделителя, чтобы облегчить автоматическое извлечение данных из текста ошибки. Злоумышленник может искать в сообщении подстроку между двумя тильдами и таким образом получать нужную информацию.
Цели атаки
Error-based SQL-инъекции через EXTRACTVALUE позволяют извлекать произвольные данные из базы. В первую очередь злоумышленников интересует:
- версия MySQL и операционной системы;
- имя текущей базы данных и пользователя;
- список таблиц и столбцов;
- учётные данные пользователей (логины, хеши паролей);
- персональные данные клиентов.
Получив эту информацию, атакующий может развить атаку: украсть конфиденциальные сведения, изменить или удалить данные, получить доступ к админ-панели.
Пример уязвимого кода
Рассмотрим фрагмент на PHP, который может быть уязвим:
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = '$id'";
$result = mysqli_query($link, $query);
Если параметр id не фильтруется, злоумышленник может передать строку 1' AND EXTRACTVALUE(4442,CONCAT(0x7e,((SELECT (ELT(4442=4442,1)))),0x7e))-- - и выполнить произвольный SQL-код.
Как защититься от SQL-инъекций
Основной метод защиты — использование подготовленных выражений (prepared statements) с параметризацией запросов. В PHP это делается через PDO или mysqli с плейсхолдерами. Например:
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = :id');
$stmt->execute(['id' => $id]);
Дополнительные меры:
- валидация и фильтрация всех входных данных (приведение к ожидаемому типу);
- экранирование специальных символов с помощью
mysqli_real_escape_string(но это не панацея); - использование ORM, которые автоматически параметризуют запросы;
- ограничение прав пользователя базы данных (не использовать root для веб-приложений);
- включение логирования и мониторинга ошибок СУБД;
- регулярное обновление MySQL и веб-приложений.
Также рекомендуется отключить вывод детальных ошибок базы данных на продакшене, чтобы злоумышленник не мог получить информацию через сообщения об ошибках.
Заключение
Строка с EXTRACTVALUE — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для эксплуатации уязвимости SQL-инъекции. Понимание принципов её работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы обнаружили подобные строки в логах, это сигнал о попытке взлома. Немедленно проверьте свой код на наличие уязвимостей и внедрите практики безопасной разработки.
Комментарии
—Войдите, чтобы оставить комментарий