Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых и опасных видов атак на веб-приложения. Злоумышленник внедряет вредоносный SQL-код в пользовательский ввод, чтобы получить несанкционированный доступ к базе данных. Среди множества техник особое место занимает error-based SQL-инъекция, при которой атакующий извлекает информацию через сообщения об ошибках, возвращаемые СУБД.
Запрос, который вы видите в заголовке — %')))) AND EXTRACTVALUE(4831,CONCAT(0x7e,((SELECT (ELT(4831=4831,1)))),0x7e))-- - — это классический учебный пример эксплуатации уязвимости через функцию EXTRACTVALUE в MySQL. Давайте разберём его по частям.
Как работает функция EXTRACTVALUE
Функция EXTRACTVALUE(XML_frag, XPath_expr) появилась в MySQL 5.1. Она предназначена для извлечения значения из фрагмента XML по заданному XPath-выражению. Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, текст которой содержит переданные данные. Именно это свойство и используют злоумышленники для вывода информации.
Например, запрос SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)); вызовет ошибку вида XPATH syntax error: '~5.7.33~', раскрывая версию СУБД.
В нашем примере используется CONCAT(0x7e, ..., 0x7e), где 0x7e — это шестнадцатеричный код символа тильды (~). Тильда служит маркером, по которому атакующий легко находит извлечённые данные в тексте ошибки.
Разбор запроса по частям
- %')))) — часть, которая «закрывает» исходный SQL-запрос приложения. Символ
%часто используется в LIKE-запросах, а последовательность кавычек и скобок позволяет разорвать легитимный запрос и внедрить свой код. - AND EXTRACTVALUE(4831, CONCAT(...)) — вызов уязвимой функции. Первый аргумент (4831) — произвольное число, второй — конкатенация тильды, подзапроса и ещё одной тильды.
- ((SELECT (ELT(4831=4831,1)))) — подзапрос, который возвращает 1, если условие
4831=4831истинно. ФункцияELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь она используется как заглушка для демонстрации. - -- - — комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы не вызвать синтаксическую ошибку.
В реальной атаке вместо ELT(4831=4831,1) подставляются подзапросы, извлекающие имена таблиц, столбцов или конкретные данные, например: SELECT table_name FROM information_schema.tables LIMIT 1.
Почему это работает: механизм error-based инъекции
MySQL при вызове EXTRACTVALUE с некорректным XPath-выражением возвращает ошибку, в которой отображается переданная строка. Если в эту строку внедрить результат подзапроса, он попадёт в сообщение об ошибке, которое затем отобразится на странице (если приложение не подавляет ошибки). Таким образом, атакующий может посимвольно извлекать любые данные.
Аналогичные функции: UPDATEXML, GTID_SUBSET, EXP (в старых версиях). Все они относятся к классу error-based SQL-инъекций.
Пример реальной эксплуатации
Предположим, на сайте есть страница product.php?id=1, где параметр id подставляется в SQL-запрос без фильтрации. Злоумышленник может отправить:
1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))
В ответе сервера появится ошибка с именем текущей базы данных. Далее можно извлекать таблицы, столбцы и записи.
Как защититься от error-based SQL-инъекций
Основная причина уязвимости — отсутствие фильтрации пользовательского ввода и вывод ошибок СУБД на страницу. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ. Параметры запроса передаются отдельно от SQL-кода, что исключает инъекцию.
- Отключите вывод ошибок MySQL в production. Настройте
display_errors = Offв PHP или используйте обработчики, которые логируют ошибки, но не показывают их пользователю. - Применяйте принцип наименьших привилегий. Пользователь БД для веб-приложения не должен иметь прав на чтение
information_schemaили доступ к чужим таблицам. - Используйте WAF (Web Application Firewall). Современные WAF умеют распознавать сигнатуры error-based инъекций, включая вызовы
EXTRACTVALUEиUPDATEXML. - Регулярно обновляйте СУБД. В новых версиях MySQL (8.0+) функция
EXTRACTVALUEудалена, что снижает риск, но не отменяет необходимость общей защиты. - Проводите аудит кода и пентесты. Автоматические сканеры (sqlmap, OWASP ZAP) помогают выявить уязвимости на ранних этапах.
Заключение
Запрос %')))) AND EXTRACTVALUE(4831,CONCAT(0x7e,((SELECT (ELT(4831=4831,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции через функцию EXTRACTVALUE. Понимание механики таких атак позволяет разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий