Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. В случае с MySQL одной из техник является использование функции EXTRACTVALUE для извлечения данных через сообщения об ошибках. Запрос OR EXTRACTVALUE(4639,CONCAT(0x7e,((SELECT (ELT(4639=4639,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, где атакующий пытается заставить сервер вернуть данные в тексте ошибки.
В этой статье мы детально разберём, как работает такая инъекция, для чего нужны функции EXTRACTVALUE, CONCAT, ELT, и как защититься от подобных атак.
Как работает функция EXTRACTVALUE в MySQL
Функция EXTRACTVALUE появилась в MySQL 5.1 как часть поддержки XML. Она извлекает значение из XML-фрагмента, используя выражение XPath. Синтаксис:
EXTRACTVALUE(XML_fragment, XPath_expression)
Например, EXTRACTVALUE('<a>текст</a>', '/a') вернёт «текст». Однако, если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданный фрагмент. Это и используется в атаках: злоумышленник передаёт в качестве XPath строку, содержащую результат подзапроса, и сервер возвращает его в сообщении об ошибке.
Важно: начиная с MySQL 5.7 функция EXTRACTVALUE была объявлена устаревшей, а в MySQL 8.0 удалена. Но многие устаревшие системы всё ещё работают на старых версиях, что делает эту технику актуальной.
Разбор конкретного запроса
Рассмотрим запрос по частям:
OR EXTRACTVALUE(4639,CONCAT(0x7e,((SELECT (ELT(4639=4639,1)))),0x7e))-- -
- OR — логический оператор, который делает условие всегда истинным (если инъекция внедрена в WHERE).
- EXTRACTVALUE(4639, ...) — первый аргумент 4639 — это произвольное число, которое будет интерпретировано как XML-фрагмент (что вызовет ошибку, так как это не XML).
- CONCAT(0x7e, ..., 0x7e) — конкатенация символа ~ (0x7e в шестнадцатеричном виде) с результатом подзапроса и ещё одним ~. Это делается для того, чтобы отделить данные в сообщении об ошибке.
- (SELECT (ELT(4639=4639,1))) — подзапрос, который возвращает 1, если 4639=4639 (всегда истина). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь возвращается 1.
- -- - — комментарий, который отсекает остальную часть оригинального SQL-запроса.
В результате MySQL попытается выполнить EXTRACTVALUE с некорректным XML, что вызовет ошибку вида: XPATH syntax error: '~1~'. Таким образом, атакующий видит результат выполнения подзапроса.
Зачем это нужно атакующему?
Основная цель — извлечь данные из базы, которые не отображаются на странице. Например, можно получить имена таблиц, колонок, логины и пароли пользователей. Вместо числа 1 в ELT можно подставить подзапрос, возвращающий нужные данные, например: (SELECT user FROM users LIMIT 1). Тогда в ошибке появится имя пользователя.
Error-based инъекции удобны тем, что не требуют вывода данных на странице — достаточно, чтобы приложение отображало ошибки базы данных. Если ошибки скрыты, атакующий может использовать blind-техники, но это сложнее.
Примеры других полезных функций
- UPDATEXML — аналогична EXTRACTVALUE, но для обновления XML. Также вызывает ошибку с переданными данными.
- ELT — возвращает N-й элемент из списка. Часто используется вместе с EXTRACTVALUE для формирования строки.
- CONCAT — объединяет строки, позволяет добавить маркеры (например, ~) для облегчения парсинга результата.
- 0x7e — шестнадцатеричное представление символа ~. Можно использовать и другие символы, например 0x3a (двоеточие).
Как защититься от таких инъекций?
Главный способ — использовать параметризованные запросы (prepared statements). Это надёжно отделяет данные от SQL-кода. Дополнительные меры:
- Обновить MySQL до версии 8.0, где EXTRACTVALUE удалена (но это не панацея, есть другие функции).
- Отключить вывод ошибок базы данных в продакшене.
- Использовать ORM или query builder, которые экранируют входные данные.
- Проводить регулярный аудит кода и сканирование уязвимостей.
- Применять WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Важно понимать, что никакая отдельная мера не даёт 100% защиты. Только комплексный подход обеспечивает безопасность.
Заключение
Запрос OR EXTRACTVALUE(4639,CONCAT(0x7e,((SELECT (ELT(4639=4639,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, использующей уязвимость функции EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание таких техник необходимо как разработчикам для защиты, так и пентестерам для тестирования. Всегда используйте параметризованные запросы и следите за обновлениями СУБД.
Комментарии
—Войдите, чтобы оставить комментарий