Что такое error-based SQL-инъекция через ExtractValue
SQL-инъекция остаётся одной из самых опасных уязвимостей веб-приложений и стабильно входит в топ OWASP. Среди множества техник особое место занимает error-based SQL-инъекция, при которой злоумышленник извлекает данные через сообщения об ошибках базы данных. Один из классических приёмов для MySQL — использование функции ExtractValue().
Функция ExtractValue(XML_document, XPath_expression) предназначена для извлечения значений из XML-документа по указанному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL возвращает ошибку XPATH syntax error с фрагментом переданного выражения. Именно это свойство эксплуатируется: злоумышленник подставляет в XPath результат подзапроса, и СУБД сама «показывает» данные в тексте ошибки.
Разбор конкретного запроса
Рассмотрим запрос из заголовка:
")) AND EXTRACTVALUE(2260,CONCAT(0x7e,((SELECT (ELT(2260=2260,1)))),0x7e))-- -
Он представляет собой фрагмент, который внедряется в уязвимый SQL-запрос. Разберём его по частям.
Синтаксис и контекст внедрения
"))— закрывающие кавычка и скобки. Они «выравнивают» исходный SQL-запрос, чтобы внедряемый код стал его продолжением. Точный набор символов зависит от того, как построен оригинальный запрос.AND— логический оператор, присоединяющий условие к WHERE-части.EXTRACTVALUE(2260, CONCAT(...))— вызов уязвимой функции. Первый аргумент — произвольный XML-документ (здесь просто число 2260, которое MySQL преобразует в строку).-- -— комментарий, обрезающий остаток оригинального запроса. Пробел после двух дефисов обязателен для MySQL.
Зачем нужен CONCAT и 0x7e
Функция CONCAT() склеивает несколько строк. Константа 0x7e — это шестнадцатеричное представление символа тильды ~. Тильда используется как маркер-ограничитель: она отделяет полезные данные от остального текста в сообщении об ошибке, чтобы их было легко найти. Итоговая XPath-строка принимает вид ~<данные>~.
Символ ~ недопустим в начале XPath-выражения, поэтому MySQL гарантированно выдаст ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: ':~1~'
В этом сообщении между тильдами окажется результат подзапроса — именно то, что нужно атакующему.
Подзапрос с ELT(2260=2260,1)
Внутри CONCAT находится подзапрос:
(SELECT (ELT(2260=2260,1)))
Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь N — это результат сравнения 2260=2260, которое всегда истинно и в числовом контексте даёт 1. Следовательно, ELT(1, 1) вернёт строку '1'. В учебном примере это просто демонстрация работы конструкции: на месте 1 мог бы стоять любой другой подзапрос, например (SELECT version()) или (SELECT password FROM users LIMIT 1).
Таким образом, запрос проверяет, что инъекция выполняется, и показывает, как через ошибку можно вытащить произвольные данные.
Почему это работает: особенности MySQL
Функция ExtractValue появилась в MySQL 5.1 и доступна во всех последующих версиях, включая 5.7 и 8.0. При передаче некорректного XPath-выражения СУБД возвращает ошибку, содержащую до 64 символов этого выражения. Этого достаточно для посимвольного извлечения данных, хотя для длинных строк приходится использовать SUBSTRING и смещения.
Аналогичным образом работает функция UpdateXML(), которая также генерирует XPATH-ошибку. Обе функции часто используются в автоматизированных инструментах, например в sqlmap, для ускорения эксплуатации error-based инъекций.
Как защититься от таких атак
Главный принцип — никогда не конкатенировать пользовательский ввод в SQL-запросы. Вот основные меры:
- Параметризованные запросы (prepared statements). Это самый надёжный способ. Данные передаются отдельно от кода, и СУБД не интерпретирует их как SQL.
- Хранимые процедуры. При правильной реализации также исключают инъекции.
- Экранирование специальных символов. Например, функция
mysqli_real_escape_string()в PHP. Но это менее надёжно, чем параметризация. - Ограничение прав пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми привилегиями (никаких
FILE,PROCESSи т.п.). - Отключение вывода ошибок БД в продакшене. Сообщения об ошибках не должны попадать в ответы сервера.
- WAF. Веб-прикладной экран может блокировать подозрительные конструкции, но не является панацеей.
Также рекомендуется регулярно проводить аудит кода и сканирование уязвимостей, а разработчиков обучать безопасной работе с SQL.
Итог
Запрос ")) AND EXTRACTVALUE(2260,CONCAT(0x7e,((SELECT (ELT(2260=2260,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию ExtractValue в MySQL. Он показывает, как с помощью тильды-ограничителя и подзапроса можно заставить базу данных выдать данные в тексте ошибки. Понимание этой техники необходимо как специалистам по безопасности, так и разработчикам, чтобы своевременно закрывать подобные уязвимости с помощью параметризованных запросов и других мер защиты.
Комментарии
—Войдите, чтобы оставить комментарий