Что такое EXTRACTVALUE и при чём тут SQL-инъекция?
Функция EXTRACTVALUE — это встроенная функция СУБД MySQL (начиная с версии 5.1), предназначенная для работы с XML. Она принимает два аргумента: фрагмент XML-документа и выражение XPath, а возвращает скалярное значение — текст узла, атрибут или элемент, соответствующий указанному пути. Синтаксис: EXTRACTVALUE(XML_фрагмент, XPath_выражение).
Однако эта функция получила печальную известность в среде пентестеров и злоумышленников. Дело в том, что при передаче некорректного XPath-выражения MySQL генерирует сообщение об ошибке, в которое подставляется переданная строка. Это позволяет реализовать так называемую error-based SQL-инъекцию — атаку, при которой данные извлекаются не через прямое отображение на странице, а через текст ошибки базы данных.
Как работает error-based инъекция через EXTRACTVALUE
Классический пример полезной нагрузки, подобной той, что указана в запросе пользователя, выглядит так:
%" ) AND EXTRACTVALUE(4501,CONCAT(0x7e,((SELECT (ELT(4501=4501,1)))),0x7e))-- -
Разберём её по частям:
- %" ) — закрытие ранее открытой кавычки и скобки в уязвимом SQL-запросе, чтобы внедрить собственный код.
- AND EXTRACTVALUE(...) — добавление логического условия. Если функция вызовет ошибку, запрос завершится неудачей, и сообщение об ошибке вернётся клиенту.
- 4501 — произвольное число, первый аргумент EXTRACTVALUE (может быть любым, так как XML невалиден).
- CONCAT(0x7e, ((SELECT (ELT(4501=4501,1)))), 0x7e) — конкатенация тильды (
0x7e— шестнадцатеричный код символа~), результата подзапроса и ещё одной тильды. ПодзапросSELECT (ELT(4501=4501,1))возвращает1, если условие истинно (что всегда так, поскольку 4501=4501). В реальной атаке вместо этого подзапроса внедряется извлечение данных, например, версии СУБД, имени базы, таблицы или хешей паролей. - -- - — комментарий, отсекающий оставшуюся часть оригинального запроса.
Когда MySQL пытается выполнить EXTRACTVALUE с некорректным XPath (в данном случае аргумент начинается с тильды, что не является допустимым XPath-выражением), он возвращает ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и оказываются данные, полученные из подзапроса. Злоумышленник может итеративно извлекать информацию посимвольно, используя функции вроде SUBSTRING, ASCII и другие.
Почему EXTRACTVALUE опасна?
До появления других техник (например, основанных на XML-функции UpdateXML) EXTRACTVALUE была основным инструментом для error-based инъекций в MySQL. Её преимущества для атакующего:
- Не требует вывода данных на странице — достаточно, чтобы ошибки БД отображались пользователю.
- Позволяет извлекать произвольные данные, включая содержимое других таблиц и баз данных.
- Работает даже при ограниченных правах пользователя БД, если ему разрешено выполнение SELECT.
Стоит отметить, что аналогичная функциональность есть и в других СУБД. Например, в Oracle функция EXTRACTVALUE также принимает XMLType и XPath, но механизм ошибок там отличается. В Microsoft SQL Server для error-based инъекций часто используют преобразование типов. Однако именно MySQL-реализация EXTRACTVALUE стала канонической для демонстрации этой уязвимости.
Пример эксплуатации
Предположим, на сайте есть параметр id, который подставляется в запрос: SELECT * FROM articles WHERE id = '$id'. Злоумышленник передаёт:
1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -
В ответе сервера появится ошибка: XPATH syntax error: '~5.7.33~'. Так узнаётся версия MySQL. Далее можно извлекать имена таблиц из information_schema.tables, логины и пароли из users и т.д.
Как защититься от инъекций через EXTRACTVALUE
Основной метод защиты — использование параметризованных запросов (prepared statements). Это полностью исключает возможность внедрения SQL-кода, так как данные передаются отдельно от структуры запроса. Дополнительные меры:
- Экранирование специальных символов — но это менее надёжно, чем параметризация.
- Отключение вывода ошибок БД в production-среде. Ошибки должны логироваться, а пользователь видеть общее сообщение.
- Ограничение прав пользователя БД — запрет на доступ к information_schema, mysql и другим системным базам.
- Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов, содержащих EXTRACTVALUE, CONCAT и т.п.
- Регулярное обновление MySQL — в новых версиях поведение функций может быть изменено, но полной защиты это не даёт.
Важно понимать, что сама по себе функция EXTRACTVALUE не является уязвимостью. Опасность возникает только при некорректной обработке пользовательского ввода в SQL-запросах. Разработчикам следует всегда проверять и очищать все входные данные, особенно те, что попадают в SQL.
Заключение
Error-based SQL-инъекция через EXTRACTVALUE — это мощный метод атаки на веб-приложения, использующие MySQL. Она позволяет извлекать конфиденциальные данные через сообщения об ошибках. Понимание механизма работы этой техники помогает разработчикам и специалистам по безопасности лучше защищать свои системы. Главный совет: используйте параметризованные запросы и не выводите ошибки БД конечным пользователям.
Комментарии
—Войдите, чтобы оставить комментарий