Строка AND EXTRACTVALUE(4091,CONCAT(0x7e,((SELECT (ELT(4091=4091,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через вывод сообщения об ошибке. В данном случае запрос не крадёт данные напрямую, а проверяет саму возможность инъекции: он заставляет MySQL вернуть ошибку, содержащую результат подзапроса.
Что такое error-based SQL-инъекция
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения. Злоумышленник вставляет в пользовательский ввод специальные символы и SQL-код, чтобы изменить исходный запрос к базе данных. Error-based инъекция — это техника, при которой атакующий намеренно вызывает ошибку СУБД, а в тексте ошибки пытается вывести нужные данные (например, версию MySQL, имена таблиц, логины и пароли).
MySQL-функция EXTRACTVALUE(XML_document, XPath_expression) извлекает значение из XML-документа по XPath-выражению. Если переданный XPath-выражение синтаксически некорректно, MySQL возвращает ошибку вида XPATH syntax error: '...'. Эта особенность и используется для вывода данных: в текст ошибки подставляется результат подзапроса.
Разбор строки по частям
Рассмотрим запрос детально:
- AND — логический оператор, который добавляется к исходному условию
WHERE. Если исходный запрос был истинным, добавлениеANDс заведомо ложным или ошибочным выражением меняет поведение приложения. - EXTRACTVALUE(4091, CONCAT(0x7e, ((SELECT (ELT(4091=4091,1)))), 0x7e)) — вызов функции
EXTRACTVALUE. Первый аргумент — число 4091 (может быть любым), второй — конкатенация символов~(0x7e — шестнадцатеричный код тильды) и результата подзапроса. - CONCAT(0x7e, ..., 0x7e) — оборачивает результат в тильды, чтобы в тексте ошибки было легко найти выводимые данные.
- SELECT (ELT(4091=4091,1)) — подзапрос, который возвращает 1, если условие
4091=4091истинно. ФункцияELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь список состоит из одной строки «1», поэтому результат — «1». - -- - — комментарий, который отсекает оставшуюся часть исходного SQL-запроса. Пробел после
--обязателен для MySQL, а дефис в конце часто используется для обхода фильтров.
В итоге MySQL пытается выполнить EXTRACTVALUE(4091, '~1~'). Поскольку '~1~' не является корректным XPath-выражением (начинается с тильды), СУБД возвращает ошибку: XPATH syntax error: '~1~'. В этой ошибке и «утекает» результат подзапроса.
Зачем это нужно атакующему
На первом этапе такая конструкция используется для проверки уязвимости: если приложение возвращает ошибку MySQL с текстом XPATH syntax error, значит, параметр уязвим для error-based инъекции. Далее атакующий заменяет ELT(4091=4091,1) на подзапросы, извлекающие реальные данные:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -
Так можно получить версию СУБД, имя текущей базы, список таблиц и столбцов, а затем — логины, хеши паролей и другую конфиденциальную информацию. Поскольку данные выводятся в сообщении об ошибке, атакующему не нужны дополнительные каналы связи — достаточно, чтобы приложение отображало ошибки.
Почему EXTRACTVALUE, а не другие функции
В MySQL есть несколько функций, вызывающих ошибки с подстановкой данных: EXTRACTVALUE, UPDATEXML, GTID_SUBSET, JSON_KEYS и другие. EXTRACTVALUE и UPDATEXML — самые популярные, так как они доступны в большинстве версий MySQL и MariaDB и стабильно возвращают текст с переданным значением. С выходом MySQL 8.0 некоторые функции были изменены, но error-based техники по-прежнему работают через другие вызовы.
Как защититься от error-based SQL-инъекций
Главный принцип — никогда не доверять пользовательскому вводу и не конкатенировать его с SQL-запросами. Конкретные меры:
- Параметризованные запросы (prepared statements). Это самый надёжный способ. Данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Отключение вывода ошибок СУБД в production. Если приложение не показывает текст ошибки MySQL, error-based инъекция теряет смысл. Ошибки нужно писать в лог, а пользователю показывать общее сообщение.
- Экранирование специальных символов. Если параметризация невозможна, используйте функции экранирования (например,
mysqli_real_escape_string), но помните, что это менее надёжно. - Ограничение прав пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми правами — без доступа к
INFORMATION_SCHEMAи системным таблицам, если это не требуется. - WAF и сигнатуры. Веб-приложения-экраны могут блокировать запросы, содержащие
EXTRACTVALUE,CONCAT(0x7eи подобные шаблоны, но это лишь дополнительный барьер. - Регулярный аудит кода и пентесты. Автоматические сканеры и ручное тестирование помогают находить уязвимости до атакующих.
Итог
Строка AND EXTRACTVALUE(4091,CONCAT(0x7e,((SELECT (ELT(4091=4091,1)))),0x7e))-- - — это не случайный набор символов, а рабочий инструмент SQL-инъекции. Она показывает, как с помощью штатной функции MySQL можно вывести данные в сообщение об ошибке. Для разработчиков это напоминание: используйте параметризованные запросы, скрывайте ошибки и следите за правами доступа к базе. Для специалистов по безопасности — пример того, как простые конструкции обходят недостаточную фильтрацию ввода.
Комментарии
—Войдите, чтобы оставить комментарий