Введение

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

Что такое ExtractValue?

EXTRACTVALUE — это функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-строки по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Если XPath-выражение некорректно, MySQL генерирует ошибку, содержащую переданные данные. Именно это свойство эксплуатируется злоумышленниками для error-based SQL-инъекций.

Например, запрос SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) вызовет ошибку вида XPATH syntax error: '~5.7.33~', раскрывая версию СУБД.

Разбор вредоносного запроса

Рассмотрим payload по частям:

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

В данном примере полезная нагрузка тривиальна: она просто возвращает 1. Однако на месте ELT(6432=6432,1) может быть любой запрос, например (SELECT user()) или (SELECT password FROM users LIMIT 1). Тогда ошибка ExtractValue раскроет эти данные.

Принцип работы error-based инъекции

Механизм атаки основан на том, что СУБД возвращает детализированные сообщения об ошибках. Когда XPath-выражение в ExtractValue содержит недопустимые символы (например, ~), MySQL выбрасывает ошибку с текстом этого выражения. Злоумышленник конструирует выражение так, чтобы в него попадали результаты подзапросов. Таким образом, база данных сама «рассказывает» атакующему содержимое таблиц.

Важно: для успешной эксплуатации веб-приложение должно выводить сообщения об ошибках СУБД пользователю. В противном случае инъекция не сработает.

Примеры извлечения данных

Рассмотрим более реалистичный сценарий. Допустим, есть таблица users с полями username и password. Чтобы извлечь имя пользователя, можно использовать:

AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT username FROM users LIMIT 0,1), 0x7e))-- -

Если приложение уязвимо, в ответе появится ошибка с именем пользователя. Для перебора других записей меняют LIMIT 0,1 на LIMIT 1,1 и так далее.

Аналогично можно извлекать имена таблиц и колонок из INFORMATION_SCHEMA:

AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x7e))-- -

Сравнение с другими техниками

ExtractValue — не единственная функция для error-based инъекций. Также часто используют:

  • UpdateXML — аналогична ExtractValue, но работает с XML-документами иначе.
  • Floor + Rand + Group By — классический способ вызова ошибки дублирования ключа.
  • Exp — переполнение через экспоненту.

ExtractValue удобна тем, что позволяет напрямую передавать подзапрос в XPath и получать его результат в тексте ошибки. Однако в новых версиях MySQL (начиная с 5.7) некоторые ошибки стали менее информативными, что усложняет эксплуатацию.

Как защититься от таких атак

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

  • Отключение вывода ошибок СУБД в production-окружении.
  • Применение ORM и фреймворков с встроенной защитой.
  • Регулярное обновление СУБД и веб-приложений.
  • Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов.
  • Проведение аудита кода и пентестов.

Важно понимать, что экранирование спецсимволов не всегда надёжно. Только параметризация даёт гарантированный результат.

Заключение

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

Источники