Что такое SQL-инъекция через ExtractValue?
SQL-инъекция (SQLi) — один из самых распространённых способов взлома веб-приложений. Злоумышленники внедряют вредоносный SQL-код в запросы, чтобы получить доступ к базе данных. Существует несколько типов SQL-инъекций: UNION-based, boolean-based, time-based и error-based. В этой статье мы подробно разберём error-based SQL-инъекцию с использованием функции ExtractValue в СУБД MySQL.
Запрос, который вы видите в заголовке — %"))) AND EXTRACTVALUE(4631,CONCAT(0x7e,((SELECT (ELT(4631=4631,1)))),0x7e))-- - — это классический пример эксплуатации уязвимости. Давайте разберём его по частям.
Как работает функция ExtractValue в MySQL
Функция EXTRACTVALUE() предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Если XPath-выражение некорректно, MySQL возвращает ошибку с сообщением: XPATH syntax error: '...'. Именно эта особенность и используется хакерами: они могут поместить в XPath-выражение результат подзапроса, и он отобразится в тексте ошибки.
Например, запрос SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)); вызовет ошибку вида XPATH syntax error: '~5.7.23~', раскрывая версию СУБД. Символ 0x7e — это тильда (~), используемая как маркер начала и конца выводимых данных.
Разбор вредоносного запроса
Рассмотрим запрос %"))) AND EXTRACTVALUE(4631,CONCAT(0x7e,((SELECT (ELT(4631=4631,1)))),0x7e))-- -:
%")))— попытка закрыть предыдущие кавычки и скобки в уязвимом параметре, чтобы внедрить свой код.AND EXTRACTVALUE(...)— добавляет условие, которое всегда ложно, но при этом выполняет функцию, вызывающую ошибку.4631— произвольное число, выступающее в роли XML-документа (не важно, так как XPath всё равно вызовет ошибку).CONCAT(0x7e, ..., 0x7e)— объединяет тильды с результатом подзапроса.(SELECT (ELT(4631=4631,1)))— подзапрос, возвращающий1, если условие истинно (здесь всегда истинно). ELT() возвращает N-й элемент из списка.-- -— комментарий, обрезающий остаток оригинального запроса.
В результате выполнения такого запроса MySQL сгенерирует ошибку, в тексте которой будет выведено значение ~1~. В реальной атаке вместо ELT(4631=4631,1) подставляются подзапросы к системным таблицам (например, INFORMATION_SCHEMA) для извлечения имён таблиц, колонок и самих данных.
Пошаговый пример эксплуатации
Предположим, уязвимый параметр передаётся в URL: https://example.com/product?id=1. Злоумышленник может отправить:
id=1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables LIMIT 0,1), 0x7e))
В ответе сервера появится ошибка с именем первой таблицы. Меняя LIMIT, можно перебрать все таблицы, затем колонки и, наконец, извлечь логины и пароли пользователей.
Важно: подобные действия являются незаконными и преследуются по закону. Данная информация предоставлена исключительно в образовательных целях для защиты своих систем.
Другие функции для error-based инъекций
Помимо EXTRACTVALUE, в MySQL существуют и другие функции, вызывающие ошибки с полезной нагрузкой:
UPDATEXML()— аналогична ExtractValue, но работает с XML-документом.GTID_SUBSET()— в некоторых версиях MySQL вызывает ошибку с указанным значением.EXP()— при переполнении возвращает ошибку с числом.RAND()в сочетании сGROUP BY— классический способ вывода данных через дублирование ключей.
Выбор функции зависит от версии СУБД и настроек. Например, EXTRACTVALUE удалена в MySQL 8.0. Поэтому современные пентестеры чаще используют UPDATEXML или другие методы.
Как защититься от SQL-инъекций через ExtractValue
Основной метод защиты — использование параметризованных запросов (prepared statements). Никогда не конкатенируйте пользовательский ввод в SQL-запрос. В PHP это делается через PDO или mysqli, в Python — через параметры в курсоре, в Java — через PreparedStatement.
Дополнительные меры:
- Валидация входных данных — проверяйте, что параметр является числом или соответствует ожидаемому формату.
- Экранирование специальных символов — используйте функции экранирования, предоставляемые драйвером БД.
- Ограничение прав пользователя БД — веб-приложение должно работать под учётной записью с минимальными привилегиями (только SELECT, INSERT, UPDATE для нужных таблиц).
- Отключение вывода ошибок — не показывайте пользователям детали ошибок СУБД; логируйте их на сервере.
- Использование WAF — веб-приложения firewall могут блокировать подозрительные запросы, содержащие
EXTRACTVALUEилиUPDATEXML. - Регулярное обновление СУБД — в новых версиях MySQL многие опасные функции удалены или изменены.
Заключение
Error-based SQL-инъекция через EXTRACTVALUE — мощный инструмент в руках злоумышленников, позволяющий извлекать данные из базы через сообщения об ошибках. Однако грамотная защита, основанная на параметризованных запросах и принципе наименьших привилегий, сводит риск к нулю. Если вы разработчик, всегда проверяйте свой код на наличие уязвимостей и используйте современные фреймворки, которые автоматически экранируют ввод.
Помните: безопасность — это процесс, а не одноразовое действие. Регулярно проводите аудит и тестирование на проникновение, чтобы выявить слабые места до того, как это сделают хакеры.
Комментарии
—Войдите, чтобы оставить комментарий