Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленники внедряют вредоносный код в SQL-запросы, чтобы получить доступ к базе данных. Строка )))) AND EXTRACTVALUE(6809,CONCAT(0x7e,((SELECT (ELT(6809=6809,1)))),0x7e))-- - — это пример так называемой error-based SQL-инъекции для СУБД MySQL. Она заставляет сервер выдать сообщение об ошибке, которое содержит полезные для атакующего данные.
В данной статье мы разберём, как работает этот конкретный запрос, зачем используется функция EXTRACTVALUE, и главное — как защитить свой сайт от подобных атак.
Разбор строки инъекции
Рассмотрим запрос по частям:
))))— закрывающие скобки, которые завершают предыдущие выражения в оригинальном SQL-запросе, чтобы внедрённый код был синтаксически корректным.AND EXTRACTVALUE(6809,CONCAT(0x7e,((SELECT (ELT(6809=6809,1)))),0x7e))— вызов функцииEXTRACTVALUEс двумя аргументами. Первый аргумент — произвольное число (6809), второй — конкатенация символа~(0x7e), результата подзапроса и снова~.-- -— комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы не вызвать синтаксическую ошибку.
Ключевой элемент — функция EXTRACTVALUE(XML_document, XPath_expression). В MySQL она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL возвращает ошибку вида XPATH syntax error: '...', в которой выводится переданная строка. Именно это и используется для извлечения данных: злоумышленник подставляет в XPath результат подзапроса, и сервер сам «показывает» его в тексте ошибки.
Подзапрос (SELECT (ELT(6809=6809,1)))
В нашем примере подзапрос возвращает 1, потому что условие 6809=6809 всегда истинно, а функция ELT(N, str1, str2, ...) возвращает строку под номером N. Здесь N=1, поэтому возвращается первый аргумент — 1. В реальной атаке вместо этого подзапроса может быть любой другой, например, извлекающий имя пользователя базы данных или хеш пароля администратора.
Далее CONCAT(0x7e, ..., 0x7e) объединяет символ ~ (тильда) с результатом подзапроса и ещё одной тильдой. Тильды нужны, чтобы чётко отделить полезные данные в сообщении об ошибке от остального текста.
Как это работает на практике
Предположим, на сайте есть форма поиска, которая формирует запрос:
SELECT * FROM articles WHERE title LIKE '%$search%';
Если злоумышленник введёт в поле поиска нашу строку, запрос превратится в:
SELECT * FROM articles WHERE title LIKE '%' )))) AND EXTRACTVALUE(6809,CONCAT(0x7e,((SELECT (ELT(6809=6809,1)))),0x7e))-- -%';
MySQL выполнит подзапрос, получит строку ~1~ и попытается интерпретировать её как XPath. Поскольку это невалидный XPath, возникнет ошибка:
XPATH syntax error: '~1~'
Эта ошибка будет возвращена приложению и, скорее всего, отобразится на странице (если включён режим отладки). Так атакующий узнаёт, что инъекция возможна, и может заменить подзапрос на извлечение реальных данных.
Зачем используется EXTRACTVALUE?
Функция EXTRACTVALUE — не единственная, позволяющая реализовать error-based инъекцию. Аналогично работают UPDATEXML, GTID_SUBSET, EXP и другие. Однако EXTRACTVALUE популярна благодаря простоте: достаточно передать любой XML-документ (даже просто число) и заведомо неверный XPath, содержащий интересующие данные. MySQL выведет этот XPath в тексте ошибки.
Важно понимать: начиная с MySQL 5.7.9 функция EXTRACTVALUE была объявлена устаревшей, а в MySQL 8.0 удалена. Тем не менее, множество сайтов до сих пор работают на старых версиях, поэтому угроза сохраняется.
Последствия успешной атаки
Если злоумышленнику удаётся эксплуатировать уязвимость, он может:
- Получить доступ к конфиденциальным данным: логины, пароли, персональные данные пользователей, номера банковских карт.
- Изменять или удалять информацию в базе данных.
- Выполнять команды на сервере (в некоторых конфигурациях).
- Использовать сайт для дальнейших атак на другие ресурсы.
Как защититься от SQL-инъекций
Основной метод защиты — использование подготовленных выражений (prepared statements) с параметризацией запросов. Это делает невозможным внедрение SQL-кода через пользовательский ввод.
Дополнительные меры:
- Экранирование специальных символов — если по каким-то причинам нельзя использовать подготовленные выражения, применяйте функции экранирования (например,
mysqli_real_escape_string). - Валидация входных данных — проверяйте, что вводимые данные соответствуют ожидаемому формату (числа, email и т.д.).
- Ограничение прав пользователя БД — учётная запись, используемая веб-приложением, должна иметь минимально необходимые права. Не используйте root.
- Отключение вывода ошибок — в production-окружении ошибки БД не должны показываться пользователю. Логируйте их, но не отображайте.
- Регулярные обновления — используйте актуальные версии СУБД и фреймворков, чтобы исключить известные уязвимости.
- WAF — веб-приложения firewall могут блокировать типовые попытки инъекций, но не должны быть единственной защитой.
Заключение
Строка с EXTRACTVALUE — это не просто набор символов, а рабочий инструмент атакующего. Понимание принципов её работы помогает разработчикам и администраторам лучше защищать свои системы. Помните: безопасность — это процесс, а не разовое действие. Регулярно проверяйте код на уязвимости, используйте современные методы защиты и следите за обновлениями.
Комментарии
—Войдите, чтобы оставить комментарий