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

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

Подобные payload'ы часто встречаются в логах веб-серверов, в полях ввода форм, в параметрах URL. Они выглядят устрашающе, но на самом деле представляют собой чётко структурированный запрос, нацеленный на получение информации от уязвимого приложения.

Разбор по частям

1. Начало: %' AND ...

Символ % часто используется как подстановочный знак в SQL-запросах с LIKE. Кавычка ' закрывает строковый литерал, в который пытается встроиться злоумышленник. Далее идёт AND — логический оператор, который добавляет условие к исходному запросу. Если исходный запрос был, например, SELECT * FROM users WHERE name LIKE '%...%', то после подстановки получается нечто вроде SELECT * FROM users WHERE name LIKE '%%' AND EXTRACTVALUE(...)-- -'.

2. Функция EXTRACTVALUE(7233, CONCAT(...))

EXTRACTVALUE — это встроенная функция MySQL (до версии 8.0), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(xml_fragment, xpath_expression).

Здесь первый аргумент — число 7233, которое не является корректным XML. Второй аргумент — результат CONCAT. Когда XPath-выражение содержит недопустимые символы (например, тильду ~), MySQL генерирует ошибку, в тексте которой отображается переданное значение. Это и есть основа error-based инъекции.

3. Конкатенация: CONCAT(0x7e, ((SELECT ...)), 0x7e)

0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда добавляется с обеих сторон, чтобы отделить полезную нагрузку в сообщении об ошибке. Внутри CONCAT находится подзапрос ((SELECT (ELT(7233=7233,1)))).

4. Подзапрос: SELECT (ELT(7233=7233,1))

ELT — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, str1, str2, ...). Если N=1, возвращается первая строка.

Выражение 7233=7233 всегда истинно, то есть равно 1. Значит, ELT(1, 1) вернёт строку '1'. Это простейшая проверка: если инъекция выполняется, сервер вернёт ошибку с символом ~1~. В реальных атаках вместо 1 подставляют подзапросы, извлекающие имена таблиц, колонок, хэши паролей и т.д.

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

Два дефиса с пробелом — это комментарий в SQL. Он «отрезает» остаток исходного запроса, чтобы синтаксис остался корректным. Пробел после -- обязателен в MySQL (в отличие от некоторых других СУБД).

Как это работает на практике

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

SELECT * FROM articles WHERE title LIKE '%ЗАПРОС%';

После подстановки payload'а получаем:

SELECT * FROM articles WHERE title LIKE '%%' AND EXTRACTVALUE(7233,CONCAT(0x7e,((SELECT (ELT(7233=7233,1)))),0x7e))-- -%';

MySQL выполняет EXTRACTVALUE, пытается разобрать XPath ~1~, терпит неудачу и возвращает ошибку вида:

XPATH syntax error: '~1~'

Эта ошибка отображается пользователю (если включён вывод ошибок), и атакующий видит результат выполнения подзапроса. Меняя ELT(7233=7233,1) на, например, (SELECT database()), можно получить имя текущей базы данных.

Зачем это нужно злоумышленнику?

  • Извлечение структуры БД: имена таблиц, колонок через information_schema.
  • Получение данных: логины, пароли, персональные сведения.
  • Обход фильтров: error-based инъекции часто проходят там, где не работает UNION-based.
  • Проверка уязвимости: простой payload с ELT(1=1,1) помогает быстро определить, есть ли SQL-инъекция.

Опасность и защита

Error-based SQL-инъекции — один из самых быстрых способов украсть данные. Для защиты необходимо:

  1. Использовать подготовленные выражения (prepared statements) с параметризацией — это самый надёжный способ.
  2. Отключить вывод ошибок СУБД на продакшене, чтобы сообщения не попадали к пользователю.
  3. Применять ORM и фреймворки, которые автоматически экранируют опасные символы.
  4. Регулярно обновлять MySQL: в версии 8.0 функции EXTRACTVALUE и UPDATEXML удалены, что снижает риск подобных атак.
  5. Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Вывод

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

Источники