Что это за строка?

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

Внешне она выглядит как бессмысленный набор символов, но на самом деле это тщательно сконструированный запрос, который заставляет MySQL выдать часть информации, которую злоумышленник не должен видеть. Давайте разберём её по частям.

Разбор конструкции по элементам

1. Начало: %") )

Символы %")) — это попытка закрыть предыдущий SQL-запрос, который выполнялся на сервере. Знак процента и кавычки часто используются для обхода простых фильтров и завершения строкового литерала. Двойная закрывающая скобка указывает на то, что в исходном запросе было несколько вложенных условий или функций.

2. AND EXTRACTVALUE(9254,CONCAT(0x7e,((SELECT (ELT(9254=9254,1)))),0x7e))

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

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

3. Завершение: -- -

Два дефиса и пробел (или дефис) — это комментарий в SQL. Всё, что идёт после --, игнорируется базой данных. Это позволяет «отрезать» остаток оригинального запроса, чтобы он не вызвал синтаксическую ошибку.

Как работает error-based инъекция через EXTRACTVALUE?

Механизм следующий:

  1. Злоумышленник находит точку входа, где пользовательский ввод попадает в SQL-запрос без должной фильтрации.
  2. Он внедряет конструкцию, подобную приведённой. База данных выполняет подзапрос (SELECT ...), который извлекает нужные данные (например, версию СУБД, имя текущей базы, логин администратора).
  3. Результат подзапроса передаётся в EXTRACTVALUE как часть XPath-выражения. Поскольку это выражение синтаксически неверно (содержит посторонние символы), MySQL выбрасывает ошибку.
  4. В тексте ошибки MySQL отображает переданное значение — то есть извлечённые данные. Злоумышленник видит их в ответе сервера.

Таким образом, даже если приложение не выводит данные напрямую, ошибки базы данных могут стать каналом утечки информации.

Почему используется именно EXTRACTVALUE?

Функция EXTRACTVALUE доступна в MySQL и MariaDB. Она часто применяется в error-based инъекциях, потому что:

  • Выдаёт подробные сообщения об ошибках, содержащие переданные аргументы.
  • Может быть использована в конструкциях с AND, OR, UNION.
  • Позволяет извлекать данные посимвольно или целыми строками, в зависимости от подзапроса.

Аналогичными функциями являются UPDATEXML и EXP (в старых версиях MySQL).

Пример реальной атаки

Предположим, есть уязвимый параметр id, который подставляется в запрос:

SELECT * FROM products WHERE id = '$id'

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

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

Если приложение уязвимо, в ответе появится ошибка вида:

XPATH syntax error: '~5.7.34~'

Так злоумышленник узнаёт версию MySQL. Затем он может извлекать имена таблиц, столбцов и сами данные.

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

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

Дополнительные меры:

  • Валидация входных данных: проверяйте, что параметры соответствуют ожидаемому формату (число, дата, email).
  • Экранирование специальных символов: если параметризация невозможна, используйте функции экранирования, предоставляемые драйвером БД.
  • Отключение подробных ошибок: настройте сервер так, чтобы сообщения об ошибках не отображались пользователям. Это усложнит эксплуатацию error-based инъекций.
  • Использование WAF: веб-приложения-экраны могут блокировать подозрительные конструкции, но не являются надёжной заменой правильному кодированию.
  • Регулярные аудиты безопасности: сканеры уязвимостей и ручное тестирование помогают выявить проблемы до атакующих.

Заключение

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

Источники