Что такое EXTRACTVALUE и зачем она в SQL-инъекциях?
Функция EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Однако в контексте SQL-инъекций эта функция приобрела дурную славу как инструмент для извлечения данных через ошибки. Злоумышленники используют её для того, чтобы заставить базу данных вернуть результат подзапроса в виде сообщения об ошибке.
Рассматриваемый запрос: ')) AND EXTRACTVALUE(6965,CONCAT(0x7e,((SELECT (ELT(6965=6965,1)))),0x7e))-- - — классический пример такой инъекции. Давайте разберём его по частям.
Анатомия инъекции
Начнём с начала. Последовательность ')) закрывает ранее открытые скобки и кавычки в уязвимом запросе, подготавливая почву для внедрения. Далее идёт AND EXTRACTVALUE(6965, CONCAT(0x7e, ((SELECT (ELT(6965=6965,1)))), 0x7e)). Здесь:
- 6965 — произвольное число, первый аргумент EXTRACTVALUE. Оно не играет роли, так как XML-фрагмент невалиден.
- CONCAT(0x7e, ..., 0x7e) — конкатенация символа
~(0x7e в шестнадцатеричном виде) с результатом подзапроса и ещё одним~. Символ~используется как маркер, чтобы облегчить поиск результата в сообщении об ошибке. - SELECT (ELT(6965=6965,1)) — подзапрос, возвращающий 1, если условие истинно. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь
6965=6965— всегда истина, поэтому ELT(1,1) вернёт1.
В итоге EXTRACTVALUE получает на вход число 6965 (не XML) и строку вида ~1~. Поскольку первый аргумент не является корректным XML, MySQL генерирует ошибку XPath, включая в неё переданную строку. Так результат подзапроса «утекает» в сообщении об ошибке.
Какие ошибки вызывает EXTRACTVALUE?
При передаче невалидного XML функция EXTRACTVALUE возвращает ошибку ERROR 1105 (HY000): XPATH syntax error. В сообщении будет указана часть переданного XPath-выражения. Именно это и позволяет извлекать данные. Например, если подзапрос вернёт имя пользователя, оно появится в тексте ошибки.
Пример из реальной практики: ERROR 1105 (HY000): XPATH syntax error: ':1' — это как раз результат работы подобной инъекции. Второй аргумент EXTRACTVALUE должен быть корректным XPath, но CONCAT создаёт строку, которая не является валидным XPath, что и вызывает ошибку с внедрёнными данными.
Почему это работает?
Механизм основан на том, что MySQL при ошибке XPath включает в сообщение фрагмент переданного выражения. Если злоумышленник может контролировать этот фрагмент, он может поместить туда результат подзапроса. Функция ELT здесь используется как простой способ вернуть конкретное значение (в данном случае 1) для демонстрации. В реальных атаках вместо ELT(6965=6965,1) подставляют подзапросы, извлекающие имена таблиц, колонок, пароли и т.д.
Важно отметить, что EXTRACTVALUE — не единственная функция с таким поведением. Аналогично работают UPDATEXML и некоторые другие. Все они относятся к классу error-based SQL-инъекций.
Практическое применение в тестировании на проникновение
Пентестеры часто используют EXTRACTVALUE для быстрого извлечения данных, когда нет возможности использовать UNION-запросы. Например, чтобы получить версию базы данных, можно выполнить:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))
В ответе придёт ошибка с версией MySQL. Аналогично можно извлекать имена таблиц из information_schema, хеши паролей и другую конфиденциальную информацию.
Однако стоит помнить, что длина выводимой строки ограничена (обычно около 32 символов для сообщения об ошибке), поэтому для длинных данных используют посимвольное извлечение или функцию SUBSTRING.
Как защититься от таких инъекций?
Основной метод защиты — использование параметризованных запросов (prepared statements). Это полностью исключает возможность внедрения SQL-кода, так как данные передаются отдельно от структуры запроса. Дополнительные меры:
- Экранирование специальных символов (хотя это менее надёжно, чем параметризация).
- Ограничение прав пользователя базы данных: не давайте приложению прав на чтение системных таблиц без необходимости.
- Валидация и фильтрация входных данных на стороне сервера.
- Использование ORM, которые автоматически применяют параметризацию.
- Регулярное обновление СУБД и фреймворков.
Также рекомендуется отключить вывод подробных ошибок базы данных в продакшене, чтобы злоумышленник не мог получить результат инъекции через сообщения об ошибках.
Заключение
Запрос ')) AND EXTRACTVALUE(6965,CONCAT(0x7e,((SELECT (ELT(6965=6965,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание этого механизма важно как для специалистов по безопасности, так и для разработчиков, чтобы своевременно закрывать уязвимости. Помните: лучшая защита — параметризованные запросы и минимальные привилегии для пользователей БД.
Комментарии
—Войдите, чтобы оставить комментарий