Что такое SQL-инъекция через EXTRACTVALUE?

Строка " ) AND EXTRACTVALUE(1405,CONCAT(0x7e,((SELECT (ELT(1405=1405,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах пентестеров и в логах веб-серверов, когда злоумышленник пытается проэксплуатировать уязвимость на сайте.

В основе атаки лежит функция EXTRACTVALUE(), которая извлекает фрагмент XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, в тексте которой может оказаться переданная строка. Злоумышленник использует это, чтобы заставить базу данных «выкрикнуть» нужные данные — например, версию СУБД, имя текущей базы, логины и пароли пользователей.

Как работает EXTRACTVALUE в MySQL

Функция EXTRACTVALUE(XML_fragment, XPath_expression) принимает два строковых аргумента:

  • XML_fragment — фрагмент XML-разметки.
  • XPath_expression — выражение XPath (локатор).

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

Именно эта особенность делает EXTRACTVALUE мощным инструментом для error-based инъекций. Злоумышленник конструирует XPath так, чтобы в текст ошибки попало значение, полученное из подзапроса. Например, в приведённой строке используется CONCAT(0x7e, (SELECT ...), 0x7e) — символы 0x7e (тильда) служат маркерами начала и конца извлекаемых данных, чтобы их было легко найти в сообщении об ошибке.

Разбор конкретной строки

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

" ) AND EXTRACTVALUE(1405,CONCAT(0x7e,((SELECT (ELT(1405=1405,1)))),0x7e))-- -
  • " ) — закрывающие кавычка и скобка, которые завершают предыдущее выражение в уязвимом SQL-запросе. Это позволяет внедрить собственный код.
  • AND EXTRACTVALUE(...) — добавляет условие, которое вызовет ошибку, если функция EXTRACTVALUE получит некорректный XPath.
  • 1405 — произвольное число, первый аргумент функции. Может быть любым, главное — чтобы XPath был синтаксически неверным.
  • CONCAT(0x7e, ((SELECT (ELT(1405=1405,1)))), 0x7e) — формирует строку, которая будет использована как XPath. ELT(1405=1405,1) возвращает 1, так как условие истинно. Это простейший пример; на практике вместо ELT подставляют подзапросы, извлекающие данные (например, SELECT version() или SELECT password FROM users LIMIT 1).
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса.

В результате MySQL попытается выполнить XPath-выражение, начинающееся с символа ~ (0x7e), что вызовет ошибку вида: XPATH syntax error: '~1~'. Если вместо 1 подставить полезные данные, они окажутся в тексте ошибки и будут возвращены атакующему.

Зачем это нужно злоумышленнику?

Error-based инъекции через EXTRACTVALUE (а также через функцию UPDATEXML) позволяют извлекать информацию из базы данных, даже если веб-приложение не выводит результаты SQL-запроса на страницу. Это особенно удобно в слепых инъекциях, когда данные нельзя получить напрямую, но можно судить о них по сообщениям об ошибках.

С помощью таких атак можно получить:

  • версию MySQL и операционной системы;
  • имя текущей базы данных и пользователя;
  • список таблиц и колонок;
  • логины, пароли, хеши, номера кредитных карт и другую конфиденциальную информацию.

Всё это делает error-based SQL-инъекции одним из самых опасных классов уязвимостей веб-приложений.

Как защититься от SQL-инъекций через EXTRACTVALUE

Основная причина успеха подобных атак — недостаточная фильтрация пользовательского ввода и динамическое построение SQL-запросов. Чтобы предотвратить эксплуатацию, необходимо:

  1. Использовать параметризованные запросы (prepared statements). Это самый надёжный способ, при котором данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
  2. Применять ORM или хранимые процедуры. Они также снижают риск инъекций при правильном использовании.
  3. Проводить валидацию и экранирование ввода. Например, приводить типы данных, отклонять подозрительные символы (кавычки, скобки, комментарии).
  4. Ограничивать права пользователя базы данных. Веб-приложение должно работать с минимально необходимыми привилегиями — обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц.
  5. Отключить вывод подробных ошибок в production. Сообщения об ошибках СУБД не должны показываться пользователю, чтобы не давать злоумышленнику обратную связь.
  6. Регулярно обновлять СУБД и использовать WAF. Хотя это не панацея, но снижает риск эксплуатации известных уязвимостей.

Важно понимать, что EXTRACTVALUE — не единственная функция, используемая для error-based инъекций. Аналогичным образом работают UPDATEXML, GTID_SUBSET, JSON_KEYS и другие. Поэтому защита должна быть комплексной и не полагаться только на чёрные списки функций.

Заключение

Строка с EXTRACTVALUE — это не случайный набор символов, а тщательно сконструированный эксплойт для извлечения данных из MySQL через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости и защищать конфиденциальную информацию пользователей.

Если вы нашли подобную строку в логах своего сайта, это серьёзный повод провести аудит безопасности и проверить, не осталось ли в коде мест, где пользовательский ввод попадает в SQL-запрос без должной обработки.

Источники