Что это за строка?
Строка %')) AND EXTRACTVALUE(2802,CONCAT(0x7e,((SELECT (ELT(2802=2802,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные полезные нагрузки (payload) часто встречаются в отчётах пентестеров и в базах эксплойтов.
Внешне это выглядит как случайный набор символов, но на самом деле каждый элемент здесь имеет чёткое назначение. Разберём его по частям.
Анатомия полезной нагрузки
Начнём с начала строки:
%'— символ процента и одинарная кавычка. В URL-кодировании%часто предшествует hex-коду, но здесь это, скорее всего, часть исходного ввода, который должен закрыть строковый литерал в уязвимом SQL-запросе. Одинарная кавычка завершает строку, куда внедряется атакующий.))— две закрывающие скобки. Они нужны, чтобы закрыть скобки исходного запроса (например, в конструкцияхWHERE id = ('...')).AND— логический оператор, присоединяющий наше условие к оригинальному запросу.EXTRACTVALUE(2802, CONCAT(...))— ключевая функция. EXTRACTVALUE извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL выдаёт ошибку, в текст которой попадает переданная строка. Это и есть канал утечки данных.CONCAT(0x7e, ((SELECT (ELT(2802=2802,1)))), 0x7e)— конкатенация.0x7e— это hex-код символа~(тильда). Тильды служат маркерами, чтобы в сообщении об ошибке было легко найти внедрённые данные.ELT(2802=2802, 1)— функция ELT возвращает N-й элемент из списка. Здесь2802=2802— всегда истина (1), поэтому ELT(1, 1) вернёт1. В реальной атаке вместо этого выражения подставляется подзапрос, извлекающий нужные данные (например, версию БД, имя пользователя, хеши паролей).-- -— комментарий. Два дефиса с пробелом (или-- -) закомментируют остаток оригинального запроса, чтобы синтаксис остался корректным.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = ('%')) AND EXTRACTVALUE(...)-- -');
После подстановки полезной нагрузки запрос становится синтаксически целым, но при выполнении функция EXTRACTVALUE получает на вход строку, которая не является валидным XPath. MySQL выбрасывает ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В этом сообщении между тильдами оказывается результат подзапроса. Атакующий может заменять 1 на любой другой SQL-запрос и пошагово извлекать данные — по одному значению за раз. Это медленно, но надёжно, особенно когда другие методы (UNION, blind) недоступны.
Важно: в примере из условия ELT(2802=2802,1) возвращает просто 1 — это тестовая нагрузка для проверки, что инъекция работает. В реальной атаке вместо 1 подставляется, например, (SELECT version()) или (SELECT password FROM users LIMIT 1).
Почему используется EXTRACTVALUE, а не другие функции?
Error-based инъекции в MySQL традиционно опираются на функции, которые генерируют ошибки с контролируемым содержимым. До версии 5.7 популярностью пользовались EXTRACTVALUE и UPDATEXML. Обе принимают XML и XPath; при неверном XPath в текст ошибки попадает переданная строка.
Начиная с MySQL 5.7.23 и выше, а также в MariaDB, эти функции были изменены: теперь они не выводят пользовательские данные в сообщении об ошибке. Поэтому данная полезная нагрузка на современных серверах может не сработать. Однако на устаревших инсталляциях (MySQL 5.5, 5.6, ранние 5.7) она по-прежнему эффективна.
Чем опасна такая инъекция?
Error-based SQL-инъекция позволяет злоумышленнику:
- получить версию СУБД, имя текущего пользователя, имя базы данных;
- читать содержимое таблиц (логины, пароли, персональные данные);
- в некоторых случаях — записывать файлы на сервер или выполнять команды ОС.
Даже если приложение не выводит ошибки пользователю, они могут попадать в логи, которые иногда доступны атакующему. Поэтому экранирование и параметризация запросов обязательны.
Как защититься
Главное правило: никогда не конкатенировать пользовательский ввод в SQL-запрос. Используйте подготовленные выражения (prepared statements) с параметрами. В PHP это PDO или mysqli с bind_param; в Python — параметризованные запросы в psycopg2 или SQLAlchemy; в Java — PreparedStatement.
Дополнительные меры:
- Валидация входных данных по белому списку (например, ID должен быть числом).
- Отключение вывода подробных ошибок СУБД в продакшене.
- Использование WAF (веб-фаервола) для фильтрации подозрительных конструкций.
- Регулярное обновление MySQL/MariaDB — в новых версиях EXTRACTVALUE и UPDATEXML уже не светят данные в ошибках.
- Принцип наименьших привилегий для учётной записи БД, к которой подключается приложение.
Итог
Строка %')) AND EXTRACTVALUE(2802,CONCAT(0x7e,((SELECT (ELT(2802=2802,1)))),0x7e))-- - — это не случайный мусор, а тщательно сконструированный эксплойт для извлечения данных из MySQL через ошибку XPath. Понимание таких payload'ов помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы встретили подобную строку в логах — это явный признак попытки взлома.
Комментарии
—Войдите, чтобы оставить комментарий