Что такое SQL-инъекция с EXTRACTVALUE?
SQL-инъекция — это один из самых распространённых способов взлома веб-приложений, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Существует несколько типов таких атак: UNION-based, boolean-based, time-based и error-based. Запрос, который вы видите, относится именно к error-based SQL-инъекциям с использованием функции EXTRACTVALUE в СУБД MySQL.
Внешне строка ') AND EXTRACTVALUE(3795,CONCAT(0x7e,((SELECT (ELT(3795=3795,1)))),0x7e))-- - выглядит как бессмысленный набор символов, но на самом деле это тщательно сконструированный эксплойт, цель которого — заставить базу данных выдать сообщение об ошибке, содержащее полезные для атакующего данные.
Как работает EXTRACTVALUE?
Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис:
EXTRACTVALUE(XML_фрагмент, XPath_выражение)
Функция возвращает текстовое значение узла, найденного по XPath. Однако есть важное ограничение: если XPath-выражение содержит недопустимые символы, MySQL генерирует ошибку. Именно на этом строится error-based инъекция: злоумышленник передаёт в XPath данные, которые заведомо вызовут ошибку, и в тексте ошибки отображается результат подзапроса.
Например, если передать в XPath строку с символом ~ (тильда), MySQL сообщит: XPATH syntax error: '~...'. Всё, что находится между тильдами, будет выведено в сообщении об ошибке. Это позволяет извлекать произвольные данные из базы.
Разбор конкретного запроса
Рассмотрим по частям строку ') AND EXTRACTVALUE(3795,CONCAT(0x7e,((SELECT (ELT(3795=3795,1)))),0x7e))-- -.
- ') — закрывает ранее открытую скобку и строковый литерал в уязвимом запросе. Например, если исходный запрос был
SELECT * FROM users WHERE id = ('$input'), то подстановка')завершает условие. - AND — логический оператор, присоединяющий наше условие к оригинальному запросу.
- EXTRACTVALUE(3795, ...) — вызов функции. Первый аргумент (3795) — произвольное число, оно не играет роли, так как XML-фрагмент невалиден, но это не важно для атаки.
- CONCAT(0x7e, ((SELECT (ELT(3795=3795,1)))), 0x7e) — конкатенация тильды (0x7e — шестнадцатеричный код символа ~), результата подзапроса и ещё одной тильды. Это гарантирует, что в XPath попадёт запрещённый символ, и MySQL выдаст ошибку с нашим содержимым.
- SELECT (ELT(3795=3795,1)) — подзапрос, возвращающий число 1. ELT — функция, возвращающая N-й элемент из списка. Здесь 3795=3795 — всегда истина (1), поэтому ELT(1,1) вернёт 1. В реальной атаке вместо этого подзапроса стоял бы запрос к системным таблицам, например,
SELECT version()илиSELECT password FROM users LIMIT 1. - -- - — комментарий, обрезающий остаток оригинального SQL-запроса, чтобы не нарушить синтаксис.
Таким образом, при выполнении этого запроса MySQL попытается вычислить XPath-выражение, содержащее тильды, и выдаст ошибку вида: XPATH syntax error: '~1~'. Атакующий увидит результат подзапроса (в данном случае 1) прямо в сообщении об ошибке.
Зачем нужна такая инъекция?
Error-based SQL-инъекции применяются, когда другие методы (UNION, blind) недоступны или неудобны. Например, если приложение не выводит данные напрямую, но отображает сообщения об ошибках СУБД. С помощью EXTRACTVALUE можно посимвольно извлекать содержимое базы: имена таблиц, столбцов, логины, пароли, хеши и другую конфиденциальную информацию.
В приведённом примере подзапрос возвращает константу, но в реальной атаке он был бы заменён на что-то вроде (SELECT table_name FROM information_schema.tables LIMIT 1). Тильды нужны для того, чтобы MySQL гарантированно сгенерировал ошибку и вывел данные в её тексте.
Как защититься от EXTRACTVALUE-инъекций?
Основная причина успеха таких атак — недостаточная фильтрация пользовательского ввода и отсутствие параметризованных запросов. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Экранируйте специальные символы. Если по каким-то причинам параметризация невозможна, применяйте функции экранирования (например, mysqli_real_escape_string в PHP).
- Ограничьте права пользователя БД. Не давайте приложению доступ к information_schema и системным таблицам без необходимости.
- Отключите вывод ошибок СУБД. Настройте логирование ошибок на сервере, а пользователю показывайте общие сообщения. Это лишит атакующего обратной связи.
- Используйте WAF (Web Application Firewall). Современные WAF умеют распознавать шаблоны error-based инъекций, включая EXTRACTVALUE и UPDATEXML.
- Регулярно обновляйте СУБД и фреймворки. В новых версиях MySQL некоторые функции могут быть удалены или изменены, что снижает риск.
Заключение
Запрос ') AND EXTRACTVALUE(3795,CONCAT(0x7e,((SELECT (ELT(3795=3795,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как злоумышленники используют особенности MySQL для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам правильно выстраивать защиту: параметризованные запросы, ограничение прав, скрытие ошибок и использование WAF. Никогда не доверяйте пользовательскому вводу и всегда проверяйте его на стороне сервера.
Комментарии
—Войдите, чтобы оставить комментарий