Что такое ExtractValue в MySQL
Функция ExtractValue предназначена для извлечения данных из XML-документа по заданному XPath-выражению. Синтаксис: ExtractValue(XML_document, XPath_expression). Например, SELECT ExtractValue('<a><b>1</b></a>', '/a/b') вернёт 1. Однако, если XPath-выражение некорректно, MySQL генерирует ошибку с текстом, содержащим часть переданного выражения. Это свойство и стало основой для одного из самых распространённых методов SQL-инъекции — error-based SQL injection.
Как работает атака через ExtractValue
Злоумышленник внедряет в уязвимый параметр запроса конструкцию, подобную вашей: %" ) AND EXTRACTVALUE(8065,CONCAT(0x7e,((SELECT (ELT(8065=8065,1)))),0x7e))-- -. Разберём её по частям.
%" )— закрывает предыдущую строку и скобку, чтобы внедрить свой код.AND EXTRACTVALUE(8065, ...)— вызывает функцию с заведомо некорректным первым аргументом (число 8065 вместо XML).CONCAT(0x7e, ((SELECT (ELT(8065=8065,1)))), 0x7e)— формирует строку, начиная и заканчивая символом~(0x7e). Внутри — подзапрос, возвращающий результат.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь8065=8065— всегда истина (1), поэтому ELT вернёт1. Но в реальной атаке вместо этого подзапроса может быть извлечение имени базы, таблицы, хеша пароля и т.д.-- -— комментарий, обрезающий остаток оригинального запроса.
В результате MySQL выдаёт ошибку вида: XPATH syntax error: '~1~'. В этом сообщении содержится результат выполнения подзапроса, обрамлённый тильдами. Так злоумышленник может посимвольно извлекать любые данные из базы.
Примеры эксплуатации
Классический пример: AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) — вернёт версию MySQL в тексте ошибки. Аналогично можно получить имя текущего пользователя, название базы данных, список таблиц и даже хеши паролей.
Важно: подобные инъекции работают только если приложение выводит сообщения об ошибках СУБД пользователю. В противном случае атака не даст результата.
Другие функции для error-based инъекций
Помимо ExtractValue, злоумышленники используют:
- UpdateXML — аналогичная функция для обновления XML, также генерирует ошибку с фрагментом XPath.
- Floor — в комбинации с
group byиrand()вызывает ошибку дублирования ключа. - Exp — переполнение при больших числах.
Все они позволяют вытащить данные через сообщения об ошибках, если прямой вывод заблокирован.
Как защититься от SQL-инъекций через ExtractValue
Основные меры:
- Параметризованные запросы (prepared statements) — самый надёжный способ. Данные пользователя передаются отдельно от SQL-кода и не интерпретируются как часть запроса.
- Экранирование спецсимволов — используйте функции экранирования, предоставляемые драйвером БД (например,
mysqli_real_escape_stringв PHP). Но это менее надёжно, чем параметризация. - Отключение вывода ошибок СУБД — не показывайте пользователю сообщения MySQL. Логируйте их, но не выводите в браузер.
- Ограничение прав пользователя БД — веб-приложение должно работать с минимально необходимыми привилегиями (обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц).
- WAF (Web Application Firewall) — может блокировать известные сигнатуры атак, но не является панацеей.
- Регулярное обновление СУБД — в новых версиях MySQL (8.0+) поведение функций может быть изменено для снижения рисков.
Заключение
Конструкция EXTRACTVALUE(8065,CONCAT(0x7e,((SELECT (ELT(8065=8065,1)))),0x7e)) — это типичный пример error-based SQL-инъекции, использующей особенность функции ExtractValue возвращать данные в тексте ошибки. Для защиты необходимо применять параметризованные запросы, скрывать ошибки СУБД и ограничивать права доступа к базе данных. Помните, что SQL-инъекции остаются в топ-10 угроз OWASP, поэтому игнорировать их нельзя.
Комментарии
—Войдите, чтобы оставить комментарий