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

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Существует несколько разновидностей таких атак: union-based, boolean-based, time-based и error-based. Именно к последней относится инъекция через функцию ExtractValue в СУБД MySQL.

Функция ExtractValue() предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, в тексте которой может отображаться переданный фрагмент. Этим и пользуются хакеры: они подставляют в XPath результат подзапроса, и СУБД возвращает его в сообщении об ошибке.

Разбор запроса %")) OR EXTRACTVALUE(1040,CONCAT(0x7e,((SELECT (ELT(1040=1040,1)))),0x7e))-- -

Рассмотрим этот конкретный пример. Он представляет собой классическую error-based инъекцию, нацеленную на MySQL. Разберём его по частям.

1. Закрытие исходного запроса

Начинается всё с последовательности %")). Символ % часто используется как wildcard в LIKE-запросах, а " и )) закрывают строку и скобки исходного SQL-запроса, делая его синтаксически завершённым. Это позволяет внедрить собственный код после легитимной части.

2. Логическое условие OR

Оператор OR гарантирует, что даже если первая часть условия ложна, выполнение продолжится. В error-based инъекциях это нужно, чтобы запрос не прервался раньше времени.

3. Функция EXTRACTVALUE(1040, ...)

Первый аргумент — произвольное число (1040), второй — XPath-выражение. MySQL ожидает, что второй аргумент будет корректным XPath. Если он содержит недопустимые символы, возникает ошибка вида: XPATH syntax error: '~...~'. В этой ошибке и будет выведен результат подзапроса.

4. CONCAT(0x7e, ((SELECT (ELT(1040=1040,1)))),0x7e)

Здесь формируется строка, которая станет «неправильным» XPath. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как маркер, чтобы легко найти выводимые данные в тексте ошибки. Внутри вызывается подзапрос SELECT (ELT(1040=1040,1)).

5. Функция ELT(1040=1040,1)

ELT() возвращает N-й элемент из списка. Первый аргумент — 1040=1040 — всегда истинно (равно 1). Второй аргумент — 1. То есть ELT(1,1) вернёт 1. Это простейшая проверка работоспособности инъекции. В реальной атаке вместо 1040=1040 подставляются условия для извлечения данных (например, SUBSTRING(user(),1,1)='r'), а вместо 1 — возвращаемое значение.

6. Комментарий -- -

Двойной дефис с пробелом — стандартный комментарий в SQL, который отсекает оставшуюся часть оригинального запроса. Пробел после -- обязателен в MySQL.

Как работает эксплуатация на практике

В реальной атаке злоумышленник постепенно извлекает данные. Например, чтобы узнать имя пользователя базы, он может использовать такой запрос:

' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT user()), 0x7e))-- -

В ответе сервера появится ошибка с именем пользователя. Аналогично можно извлекать имена таблиц, столбцов и содержимое полей, используя подзапросы с LIMIT и CONCAT.

Меры защиты

Главный способ борьбы с SQL-инъекциями — использование параметризованных запросов (prepared statements). Это исключает возможность внедрения кода, так как данные передаются отдельно от SQL-структуры.

  • Экранирование специальных символов — устаревший, но всё ещё применяемый метод. Однако он не гарантирует полной защиты.
  • Валидация входных данных — проверка типов, длины, допустимых символов.
  • Ограничение прав пользователя БД — не давайте приложению прав на чтение системных таблиц.
  • Использование ORM — современные ORM-библиотеки автоматически параметризуют запросы.
  • Регулярное обновление СУБД — в новых версиях MySQL некоторые функции могут быть отключены или изменены.

Также рекомендуется настроить логирование ошибок так, чтобы детальные сообщения не попадали в ответ клиенту. Это усложнит эксплуатацию error-based инъекций.

Заключение

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

Источники