Введение в проблему
В запросе пользователя указана строка: ")) OR EXTRACTVALUE(9210,CONCAT(0x7e,((SELECT (ELT(9210=9210,1)))),0x7e))-- -. Это типичный пример error-based SQL-инъекции через функцию EXTRACTVALUE в СУБД MySQL. Такие payload'ы используются злоумышленниками для извлечения данных из базы через сообщения об ошибках. В этой статье мы детально разберём, как работает данный код, почему он приводит к ошибке, и как защититься от подобных атак.
Что такое ExtractValue и XPATH-инъекция
EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может отображаться часть переданного выражения. Это и стало основой для error-based SQL-инъекций через XPATH.
Аналогичная функция — UPDATEXML — также подвержена этой уязвимости. Злоумышленник может внедрить в XPath специальные символы (например, ~), чтобы вызвать ошибку и вывести в ней результат подзапроса.
Разбор конкретного payload
Рассмотрим строку по частям:
"))— закрывает предыдущие кавычки и скобки в оригинальном SQL-запросе, чтобы внедрить свой код.OR EXTRACTVALUE(9210,CONCAT(0x7e,((SELECT (ELT(9210=9210,1)))),0x7e))— внедряемая конструкция. Она вызывает функциюEXTRACTVALUEс произвольными аргументами.-- -— комментарий, обрезающий остаток оригинального запроса.
Внутри EXTRACTVALUE используется CONCAT, который объединяет символ ~ (0x7e), результат подзапроса и снова ~. Подзапрос SELECT (ELT(9210=9210,1)) — это упрощённый пример. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 9210=9210 — всегда истина (1), поэтому ELT(1,1) вернёт 1. В реальной атаке вместо этого подзапроса внедряется запрос к системным таблицам, например, SELECT version() или SELECT table_name FROM information_schema.tables.
Функция EXTRACTVALUE ожидает первым аргументом XML-документ. Число 9210 не является валидным XML, поэтому MySQL попытается его обработать и выдаст ошибку, в тексте которой будет содержаться переданное XPath-выражение, включая результат подзапроса. Таким образом, злоумышленник может читать данные из базы.
Почему это работает: механизм ошибки
MySQL при вызове EXTRACTVALUE(9210, ...) пытается интерпретировать первый аргумент как XML. Поскольку это не XML, возникает ошибка вида: XPATH syntax error: '~1~'. В этой ошибке отображается второй аргумент — XPath-выражение, которое мы сформировали. Если вместо 1 подставить, например, SELECT database(), то в ошибке появится имя текущей базы данных. Это и есть эксплойт.
Важно: начиная с MySQL 5.7.9 и в MariaDB, функция EXTRACTVALUE была удалена или изменена, что делает этот вектор атаки неработоспособным на новых версиях. Однако многие устаревшие системы всё ещё уязвимы.
Пошаговый пример эксплуатации
- Злоумышленник находит параметр, уязвимый к SQL-инъекции, например,
?id=1. - Внедряет payload:
1")) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -. - Сервер выполняет запрос, и в ответе возвращается ошибка с версией MySQL.
- Далее можно извлекать имена таблиц, столбцов и данные, используя подзапросы с
LIMITи смещениями.
В нашем случае с ELT(9210=9210,1) это демонстрационный пример, показывающий, что подзапрос может быть любым. Число 9210 — просто случайный идентификатор, не несущий смысла.
Меры защиты
Чтобы предотвратить эксплуатацию подобных уязвимостей, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ.
- Проводить строгую валидацию всех входных данных, особенно тех, что попадают в SQL-запросы.
- Обновить MySQL до версии 5.7.9+ или использовать MariaDB, где
EXTRACTVALUEудалена. - Отключить вывод подробных ошибок СУБД на продакшене, чтобы злоумышленник не мог получить данные через сообщения об ошибках.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Также рекомендуется проводить регулярные аудиты безопасности и пентесты.
Заключение
Payload ")) OR EXTRACTVALUE(9210,CONCAT(0x7e,((SELECT (ELT(9210=9210,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции через XPATH. Он демонстрирует, как небрежная обработка пользовательского ввода может привести к утечке данных. Понимание механизма работы таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости. Всегда используйте параметризованные запросы и следите за актуальностью версий СУБД.
Комментарии
—Войдите, чтобы оставить комментарий