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

SQL-инъекция — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет произвольный SQL-код в запрос к базе данных. Существует несколько разновидностей таких атак, и одна из них — error-based SQL-инъекция, основанная на анализе сообщений об ошибках СУБД.

Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако из-за особенностей обработки ошибок она часто используется в атаках для получения данных через текст ошибки. Рассматриваемый запрос:

)) OR EXTRACTVALUE(5822,CONCAT(0x7e,((SELECT (ELT(5822=5822,1)))),0x7e))-- -

представляет собой классический пример такой инъекции.

Разбор структуры запроса

Разберём запрос по частям, чтобы понять логику атакующего.

  • )) — закрывающие скобки, которые завершают ранее открытые конструкции в уязвимом запросе приложения. Это позволяет «выйти» из исходного контекста и добавить собственный код.
  • OR — логический оператор, который делает условие истинным независимо от левой части, что часто используется для обхода аутентификации или внедрения подзапроса.
  • EXTRACTVALUE(5822, CONCAT(...)) — вызов функции с двумя аргументами: первый (5822) — произвольное число, которое фактически не используется, второй — результат конкатенации, содержащий XPath-выражение.
  • CONCAT(0x7e, ((SELECT (ELT(5822=5822,1)))), 0x7e) — объединение символа тильды (~, код 0x7e), результата подзапроса и ещё одной тильды.
  • SELECT (ELT(5822=5822,1)) — подзапрос, возвращающий значение. ELT — функция, возвращающая N-й элемент из списка. Здесь условие 5822=5822 всегда истинно, поэтому возвращается 1.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.

Как работает механизм ошибки

Функция EXTRACTVALUE() ожидает, что второй аргумент будет корректным XPath-выражением. Если передать строку, начинающуюся с символа, не являющегося допустимым XPath (например, тильда ~), MySQL генерирует ошибку вида:

XPATH syntax error: '~1~'

В этом сообщении содержится переданная строка. Атакующий специально формирует XPath так, чтобы в тексте ошибки оказались данные, которые он хочет извлечь. В данном примере это просто число 1, но в реальной атаке вместо ELT(5822=5822,1) могла бы стоять, например, SELECT version() или SELECT password FROM users LIMIT 1.

Таким образом, error-based инъекция позволяет пошагово извлекать информацию из базы данных, если приложение выводит сообщения об ошибках СУБД пользователю.

Зачем нужны CONCAT и ELT

Функция CONCAT объединяет несколько строк в одну. Тильды (0x7e) добавляются в качестве маркеров, чтобы облегчить поиск нужных данных в тексте ошибки. ELT используется для выбора конкретного значения из списка по индексу. В простейшем случае ELT(5822=5822,1) всегда возвращает 1, так как условие истинно. Это демонстрационный пример, показывающий, что подзапрос может возвращать произвольные данные.

Уязвимость и её последствия

Если веб-приложение не фильтрует входные данные и выводит ошибки базы данных, злоумышленник может:

  • получить версию СУБД, имена таблиц и колонок;
  • извлечь логины, пароли, персональные данные пользователей;
  • в некоторых случаях выполнить произвольные команды на сервере.

Особенно опасна комбинация error-based инъекции с другими техниками, например UNION-инъекцией, когда атакующий может объединять результаты своего запроса с легитимным.

Примеры других запросов

Часто для error-based инъекций используют не только EXTRACTVALUE, но и функцию UPDATEXML(), которая работает аналогично. Например:

AND UPDATEXML(1,CONCAT(0x7e,(SELECT user()),0x7e),1)

Также встречаются конструкции с GTID_SUBSET или EXP, но EXTRACTVALUE и UPDATEXML наиболее популярны из-за простоты.

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

Основные меры защиты:

  1. Использование подготовленных выражений (prepared statements) — параметризация запросов исключает возможность внедрения SQL-кода.
  2. Экранирование специальных символов — если параметризация невозможна, следует применять функции экранирования, например mysqli_real_escape_string.
  3. Отключение вывода ошибок СУБД — сообщения об ошибках не должны показываться пользователю, их следует логировать.
  4. Ограничение прав пользователя БД — учётная запись приложения должна иметь минимально необходимые привилегии.
  5. Регулярное обновление СУБД и фреймворков — исправление известных уязвимостей.

Также рекомендуется использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов, но это не заменяет основные методы защиты.

Заключение

Запрос )) OR EXTRACTVALUE(5822,CONCAT(0x7e,((SELECT (ELT(5822=5822,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как через функцию EXTRACTVALUE можно заставить базу данных выдать данные в сообщении об ошибке. Понимание таких техник необходимо специалистам по безопасности для аудита и защиты веб-приложений.

Источники