Что это за строка?
Строка %" ) AND EXTRACTVALUE(7989,CONCAT(0x7e,((SELECT (ELT(7989=7989,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Подобные конструкции используются злоумышленниками для извлечения данных из базы через вывод сообщения об ошибке. Внешне она может показаться набором случайных символов, но каждый элемент здесь имеет строгое назначение.
Такие строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в базах данных уязвимостей. Понимание их структуры помогает разработчикам и специалистам по безопасности быстрее распознавать атаки и правильно настраивать защиту.
Разбор по частям
Рассмотрим каждый фрагмент подробно.
%"— это часть исходного запроса, которая «ломает» его синтаксис. Символ%часто используется в URL-кодировании, а"закрывает строковый литерал в SQL-запросе. Вместе они позволяют злоумышленнику выйти за пределы ожидаемых данных и внедрить свой код.AND— логический оператор, который присоединяет вредоносное условие к оригинальному запросу. Если исходный запрос был истинным, то и всё выражение останется истинным, что позволяет инъекции выполниться.EXTRACTVALUE(7989, CONCAT(...))— функция MySQL для работы с XML. Она извлекает значение из XML-документа по указанному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может отображаться переданный фрагмент. Это и есть основа error-based инъекции.CONCAT(0x7e, ..., 0x7e)— функция конкатенации строк.0x7e— это шестнадцатеричное представление символа~(тильда). Тильды используются как маркеры, чтобы облегчить поиск выведенных данных в сообщении об ошибке.(SELECT (ELT(7989=7989,1)))— подзапрос, который возвращает результат.ELT()— функция MySQL, возвращающая N-й элемент из списка. В данном случае7989=7989— всегда истинное условие (1), поэтомуELT(1,1)вернёт строку '1'. Это простейший пример; на практике вместо '1' подставляются имена таблиц, столбцов или другие данные.-- -— комментарий в SQL. Всё, что идёт после--, игнорируется базой данных. Пробел после двух дефисов обязателен в некоторых СУБД, а дополнительный дефис часто добавляют для надёжности.
Как работает error-based инъекция через EXTRACTVALUE
MySQL-функция EXTRACTVALUE() принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение содержит синтаксическую ошибку, MySQL возвращает сообщение вида:
XPATH syntax error: '~1~'
Злоумышленник может подставить в XPath результат подзапроса, и этот результат отобразится в тексте ошибки. Таким образом, база данных сама «расскажет» атакующему нужную информацию — версию СУБД, имена таблиц, логины, пароли и т.д.
В нашем примере подзапрос возвращает '1', поэтому в ошибке появится '~1~'. Если заменить ELT(7989=7989,1) на, например, SELECT version(), то в ошибке отобразится версия MySQL. Это демонстрирует, насколько опасной может быть такая инъекция.
Почему это работает и когда возможно
Уязвимость возникает, когда веб-приложение передаёт пользовательский ввод в SQL-запрос без должной обработки. Если ввод не экранируется и не используется подготовленных выражений (prepared statements), злоумышленник может внедрить произвольный SQL-код.
Error-based инъекция особенно эффективна, когда приложение выводит сообщения об ошибках базы данных на страницу. Даже если вывод отключён, атакующий может использовать слепые методы, но error-based даёт быстрый результат.
Стоит отметить, что функция EXTRACTVALUE была удалена в MySQL 8.0.17 и заменена на UPDATEXML и другие функции. Однако на старых версиях (5.7 и ниже) она по-прежнему доступна и активно используется в эксплойтах.
Примеры других подобных строк
В интернете можно встретить множество вариаций:
%'))) AND EXTRACTVALUE(3720,CONCAT(0x7e,((SELECT (ELT(3720=3720,1)))),0x7e))-- -OR EXTRACTVALUE(7974,CONCAT(0x7e,((SELECT (ELT(7974=7974,1)))),0x7e))-- -
Все они используют один и тот же принцип: вызвать ошибку через XPath и вывести в ней данные. Числа в аргументах могут быть любыми — они не влияют на логику, а служат для уникальности или обхода фильтров.
Как защититься от SQL-инъекций
Основные меры защиты:
- Использовать подготовленные выражения (prepared statements). Это самый надёжный способ, так как данные и код разделяются на уровне драйвера.
- Экранировать специальные символы. Если prepared statements недоступны, применяйте функции экранирования, например
mysqli_real_escape_string. - Ограничить права пользователя базы данных. Не давайте веб-приложению прав на чтение системных таблиц или выполнение опасных функций.
- Отключить вывод ошибок СУБД на продакшене. Ошибки должны логироваться, а не показываться пользователю.
- Использовать WAF (Web Application Firewall). Современные WAF умеют распознавать сигнатуры error-based инъекций.
- Регулярно обновлять СУБД и библиотеки. В новых версиях многие опасные функции удалены или исправлены.
Также рекомендуется проводить регулярные аудиты безопасности и сканирование уязвимостей.
Заключение
Строка с EXTRACTVALUE — это не случайный набор символов, а тщательно сконструированный эксплойт для извлечения данных из MySQL. Понимание её структуры помогает специалистам по безопасности и разработчикам лучше защищать свои приложения. Если вы встретили такую строку в логах, это верный признак попытки взлома. Немедленно проверьте свой код на наличие уязвимостей и примите меры.
Комментарии
—Войдите, чтобы оставить комментарий