Что такое EXTRACTVALUE и при чём тут SQL-инъекции?
Функция EXTRACTVALUE в MySQL предназначена для извлечения значений из XML-строки по заданному XPath-выражению. Однако злоумышленники часто используют её в так называемых error-based SQL-инъекциях. Суть атаки: заставить базу данных вернуть в сообщении об ошибке конфиденциальные данные (например, версию СУБД, имена таблиц, логины).
Классический пример, который часто встречается в отчётах по пентесту, выглядит так:
` AND EXTRACTVALUE(9128,CONCAT(0x7e,((SELECT (ELT(9128=9128,1)))),0x7e))-- -
Этот запрос внедряется в уязвимый параметр, например, в строку URL или поле формы. Давайте разберём его по частям.
Разбор вредоносного запроса
1. Обратная кавычка и логика AND
Символ ` (обратная кавычка) часто используется для экранирования имён таблиц или столбцов в MySQL. Злоумышленник ставит его, чтобы разорвать исходный SQL-запрос и добавить своё условие. Конструкция AND позволяет присоединить дополнительное выражение, которое выполнится, только если предыдущее истинно.
2. Функция EXTRACTVALUE(9128, ...)
Первый аргумент — 9128 — это произвольное число, которое не является корректным XML-документом. Второй аргумент — XPath-выражение, которое формируется через CONCAT. Поскольку первый аргумент не XML, MySQL выдаст ошибку. Но хитрость в том, что в тексте ошибки будет отображён результат вычисления второго аргумента.
3. CONCAT и ELT
CONCAT(0x7e, ((SELECT (ELT(9128=9128,1)))), 0x7e) — здесь 0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как маркер, чтобы легко найти полезную нагрузку в сообщении об ошибке. Функция ELT(9128=9128,1) возвращает 1, если условие 9128=9128 истинно (а это всегда так). Фактически это заглушка, но в реальной атаке вместо ELT может быть подзапрос, извлекающий данные, например, (SELECT version()).
4. Комментарий -- -
Два дефиса и пробел (или дефис) — это комментарий в SQL, который отсекает оставшуюся часть оригинального запроса. Это позволяет внедрить произвольный код, не нарушая синтаксис.
Как работает error-based инъекция через EXTRACTVALUE?
MySQL при вызове EXTRACTVALUE с некорректным XML-документом генерирует ошибку вида: XPATH syntax error: '~результат~'. Злоумышленник помещает в XPath-выражение подзапрос, который возвращает нужные данные. Например:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -
В ответе сервера появится имя текущей базы данных. Аналогично можно извлечь версию MySQL, имена таблиц, хеши паролей и другую информацию.
Пример реальной эксплуатации
Предположим, есть уязвимый скрипт: SELECT * FROM users WHERE id = '$id'. Злоумышленник передаёт в параметр id следующее:
1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables LIMIT 1), 0x7e))-- -
В ответе придёт ошибка с названием первой таблицы. Перебирая LIMIT, можно получить список всех таблиц, а затем и столбцов.
Меры защиты от SQL-инъекций
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ.
- Экранировать все пользовательские данные с помощью функций вроде
mysqli_real_escape_stringилиPDO::quote. - Ограничить права пользователя БД, чтобы даже при успешной инъекции нельзя было прочитать системные таблицы.
- Включить логирование ошибок и не выводить их пользователю — это затруднит эксплуатацию error-based инъекций.
- Регулярно обновлять СУБД и использовать WAF (Web Application Firewall).
Важно понимать, что EXTRACTVALUE — не единственная функция, используемая для error-based атак. Аналогично работают UPDATEXML, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.
Заключение
Запрос ` AND EXTRACTVALUE(9128,CONCAT(0x7e,((SELECT (ELT(9128=9128,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, демонстрирующий уязвимость веб-приложения. Понимание механики таких атак помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий