Встретили в логах или в отчёте пентеста строку `) AND EXTRACTVALUE(3148,CONCAT(0x7e,((SELECT (ELT(3148=3148,1)))),0x7e))-- -? Это не случайный набор символов, а классический пример error-based SQL-инъекции через функцию EXTRACTVALUE в MySQL. Разберём, как она работает, зачем нужны все части и как от неё защититься.

Что такое EXTRACTVALUE?

EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), которая извлекает значение из XML-документа по заданному XPath-выражению. Синтаксис:

EXTRACTVALUE(XML_фрагмент, XPath_выражение)

Функция возвращает текст узла, соответствующего XPath. Если XPath синтаксически некорректен, MySQL генерирует ошибку XPATH syntax error. Именно эту особенность эксплуатируют злоумышленники: они заставляют базу данных выдать содержимое запроса в тексте ошибки.

Разбор инъекции по частям

Рассмотрим строку целиком:

`) AND EXTRACTVALUE(3148,CONCAT(0x7e,((SELECT (ELT(3148=3148,1)))),0x7e))-- -
  • `) — закрывает предыдущее выражение в уязвимом запросе. Символ обратной кавычки и скобка завершают условие, после чего можно добавить своё.
  • AND — логический оператор, присоединяющий полезную нагрузку к оригинальному запросу.
  • EXTRACTVALUE(3148, ...) — первый аргумент (3148) — произвольное число, которое выступает как «XML-документ». Второй аргумент — XPath-выражение, которое мы конструируем.
  • CONCAT(0x7e, ..., 0x7e) — объединяет строки. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как маркер, чтобы отделить выводимые данные от служебного текста ошибки.
  • ((SELECT (ELT(3148=3148,1)))) — подзапрос, который возвращает результат выражения. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь ELT(3148=3148, 1) — условие 3148=3148 всегда истинно (1), поэтому ELT вернёт строку «1». В реальной атаке вместо этого подзапроса подставляют извлечение данных, например, версию БД или имя пользователя.
  • -- - — комментарий, который «отрезает» оставшуюся часть оригинального SQL-запроса, чтобы не нарушать синтаксис.

В результате MySQL пытается выполнить XPath-выражение, которое начинается с тильды и содержит результат подзапроса. Поскольку такой XPath некорректен, СУБД возвращает ошибку вида:

XPATH syntax error: '~1~'

В этом сообщении и «утекает» информация. Меняя подзапрос, атакующий может посимвольно извлекать данные из базы.

Почему это работает?

Уязвимость возникает, когда приложение подставляет пользовательский ввод в SQL-запрос без параметризации. В данном случае злоумышленник смог внедрить конструкцию с EXTRACTVALUE, потому что разработчик не использовал подготовленные выражения (prepared statements).

Error-based инъекции особенно опасны тем, что не требуют вывода данных на экран — достаточно, чтобы сообщение об ошибке попало в ответ сервера или в лог, доступный атакующему.

Как защититься?

  1. Используйте параметризованные запросы (prepared statements) — это самый надёжный способ. Никогда не склеивайте SQL из строк.
  2. Отключите вывод ошибок СУБД в продакшене. Пользователь не должен видеть текст XPATH syntax error.
  3. Применяйте ORM или библиотеки, которые экранируют ввод автоматически.
  4. Регулярно проводите аудит кода и пентесты.
  5. Настройте WAF (Web Application Firewall) для фильтрации подозрительных конструкций, хотя полагаться только на него нельзя.

Заключение

Строка `) AND EXTRACTVALUE(3148,CONCAT(0x7e,((SELECT (ELT(3148=3148,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию EXTRACTVALUE. Она демонстрирует, как небрежная работа с SQL может привести к утечке данных. Если вы разработчик — всегда используйте параметризацию. Если вы пентестер — помните, что такие векторы всё ещё встречаются в старых приложениях.

Источники