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

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, позволяющий злоумышленнику вмешиваться в выполнение SQL-запросов. Среди множества техник особое место занимает инъекция через функцию EXTRACTVALUE — встроенную функцию СУБД MySQL для работы с XML. Её используют для извлечения данных из базы путём провоцирования ошибок, которые выводят нужную информацию в сообщении об ошибке.

Запрос пользователя: "") OR EXTRACTVALUE(1109,CONCAT(0x7e,((SELECT (ELT(1109=1109,1)))),0x7e))-- - — это классический пример такой инъекции. Давайте разберём его по частям.

Анатомия эксплойта

Рассматриваемая строка состоит из нескольких логических блоков:

  • "") — закрывает предыдущие кавычки и скобки в уязвимом запросе, подготавливая почву для внедрения.
  • OR — логический оператор, который делает условие всегда истинным (если правая часть верна).
  • EXTRACTVALUE(1109, CONCAT(0x7e, ((SELECT (ELT(1109=1109,1)))), 0x7e)) — вызов функции, который намеренно вызывает ошибку, содержащую результат подзапроса.
  • -- - — комментарий, отсекающий остаток оригинального запроса.

Ключевой элемент — функция EXTRACTVALUE(XML_fragment, XPath_expression). Она извлекает значение из XML-фрагмента по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку и выводит его в тексте сообщения. Это и используется для эксфильтрации данных.

Как работает CONCAT и ELT

Внутри EXTRACTVALUE мы видим CONCAT(0x7e, ((SELECT (ELT(1109=1109,1)))), 0x7e):

  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить чтение вывода в ошибке.
  • (SELECT (ELT(1109=1109,1))) — подзапрос, возвращающий результат выражения ELT(1109=1109,1). Функция ELT возвращает N-й элемент из списка. Здесь 1109=1109 — всегда истина (1), поэтому ELT(1,1) вернёт 1. В реальной атаке вместо этой заглушки подставляется запрос к таблицам базы данных, например, SELECT username FROM users LIMIT 1.
  • CONCAT склеивает тильду, результат подзапроса и ещё одну тильду, формируя строку вида ~результат~.

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

Пример работы на уязвимом приложении

Предположим, веб-приложение выполняет запрос:

SELECT * FROM articles WHERE id = '" + user_input + "'

Злоумышленник передаёт в параметр user_input строку:

" OR EXTRACTVALUE(1109,CONCAT(0x7e,((SELECT version())),0x7e))-- -

В результате итоговый запрос становится:

SELECT * FROM articles WHERE id = '" OR EXTRACTVALUE(1109,CONCAT(0x7e,((SELECT version())),0x7e))-- -'

MySQL выполняет подзапрос SELECT version(), получает, например, 8.0.32, формирует строку ~8.0.32~ и пытается интерпретировать её как XPath. Возникает ошибка, и в ответе сервера (если вывод ошибок включён) появляется сообщение с версией СУБД. Так злоумышленник может извлекать любые данные: имена таблиц, логины, пароли.

Почему это опасно?

Атака через EXTRACTVALUE позволяет обходить многие фильтры, так как не требует UNION SELECT и не зависит от количества столбцов в запросе. Она эксплуатирует ошибки, которые часто выводятся в отладочном режиме. В реальных атаках злоумышленники комбинируют её с слепыми инъекциями, когда вывод ошибок отключён, но даже тогда можно использовать временные задержки.

Согласно практическим руководствам по SQL-инъекциям (например, MySQL SQL Injection Practical Cheat Sheet), EXTRACTVALUE и её аналог UPDATEXML — популярные инструменты для извлечения данных через ошибки. Они особенно эффективны в MySQL версий 5.1 и выше.

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

Основной метод — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому ввод пользователя никогда не интерпретируется как SQL-код.

  • Параметризация — самый надёжный способ.
  • Экранирование — используйте функции экранирования, предоставляемые драйвером БД (например, mysqli_real_escape_string).
  • Отключение вывода ошибок — не показывайте пользователям сообщения об ошибках СУБД.
  • Ограничение прав — учётная запись приложения должна иметь минимально необходимые привилегии.
  • WAF — веб-application firewall может блокировать известные шаблоны атак, но не является панацеей.

Важно регулярно обновлять СУБД и использовать средства статического анализа кода для выявления уязвимостей.

Заключение

Инъекция через EXTRACTVALUE — яркий пример того, как функции, предназначенные для работы с XML, могут быть использованы во вред. Понимание механики таких атак помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: любая передача пользовательских данных в SQL-запрос без обработки — потенциальная брешь.

Источники