Что такое EXTRACTVALUE и при чём тут SQL-инъекции?
Функция EXTRACTVALUE в MySQL предназначена для извлечения данных из XML-документов с помощью XPath-выражений. Она принимает два аргумента: фрагмент XML-разметки и XPath-локатор, возвращая текст первого узла, соответствующего выражению. Однако эта функция стала известна не только благодаря работе с XML, но и как мощный инструмент для проведения error-based SQL-инъекций.
Суть атаки в том, что злоумышленник может внедрить в уязвимый SQL-запрос конструкцию, которая вызовет ошибку, содержащую конфиденциальные данные. EXTRACTVALUE генерирует сообщение об ошибке, включающее переданный XPath-выражение. Если в это выражение подставить результат подзапроса, например, имя пользователя или хеш пароля, то эти данные отобразятся в тексте ошибки.
Как работает error-based инъекция через EXTRACTVALUE
Рассмотрим классический пример, который часто встречается в отчётах по пентесту. Предположим, есть уязвимый параметр id в URL, и запрос строится так:
SELECT * FROM articles WHERE id = '$id'
Злоумышленник может передать следующее значение:
1' AND EXTRACTVALUE(5089,CONCAT(0x7e,(SELECT (ELT(5089=5089,1))),0x7e))-- -
Разберём по частям:
- 1' AND — закрывает предыдущее условие и добавляет новое.
- EXTRACTVALUE(5089, CONCAT(...)) — вызывает функцию с первым аргументом 5089 (произвольное число, может быть любым) и вторым аргументом — результатом CONCAT.
- CONCAT(0x7e, (SELECT (ELT(5089=5089,1))), 0x7e) — объединяет тильды (~) с результатом подзапроса. В данном случае
ELT(5089=5089,1)всегда возвращает 1, так как условие истинно. Это простейшая проверка, но вместо 1 может быть любой другой запрос, например,(SELECT password FROM users LIMIT 1). - -- - — комментарий, обрезающий остаток исходного запроса.
При выполнении MySQL попытается интерпретировать второй аргумент как XPath-выражение. Поскольку он не является корректным XPath (начинается с ~), возникает ошибка: XPATH syntax error: '~1~'. В этом сообщении и утекает результат подзапроса.
Почему это опасно?
Error-based инъекции через EXTRACTVALUE позволяют атакующему:
- Извлекать имена таблиц и столбцов из системной схемы
information_schema. - Получать логины, пароли, номера банковских карт и другие конфиденциальные данные.
- Обходить фильтрацию, если она настроена только на сигнатуры UNION-инъекций.
Особенность метода в том, что он не требует вывода данных на странице — достаточно, чтобы сообщение об ошибке отображалось пользователю или сохранялось в логах, к которым есть доступ. Даже если ошибки скрыты, атакующий может использовать слепые техники, анализируя время ответа или поведение приложения.
Примеры полезной нагрузки
Вот несколько вариантов эксплуатации, которые встречаются в реальных атаках:
- Получение версии MySQL:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) - Чтение имени текущей базы данных:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e)) - Извлечение пароля пользователя:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT password FROM users LIMIT 1), 0x7e))
Все они приводят к ошибке, в тексте которой появляются запрошенные данные. Важно отметить, что EXTRACTVALUE не единственная функция для таких атак — аналогично используются UPDATEXML и GTID_SUBSET, но EXTRACTVALUE стала классикой.
Как защититься от инъекций через EXTRACTVALUE
Основная причина уязвимости — передача пользовательского ввода в SQL-запрос без должной обработки. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода, и внедрение становится невозможным.
- Применяйте ORM. Современные ORM-библиотеки автоматически экранируют параметры.
- Отключите вывод ошибок СУБД на продакшене. Сообщения об ошибках не должны попадать в ответы сервера. Логируйте их, но не показывайте пользователю.
- Ограничьте права пользователя БД. Не давайте приложению доступ к
information_schemaи лишним таблицам. - Используйте WAF. Веб-приложения-экраны могут блокировать подозрительные конструкции, но не полагайтесь только на них.
- Регулярно обновляйте СУБД и фреймворки. В новых версиях MySQL некоторые функции могут быть удалены или изменены, что снижает риск.
Заключение
EXTRACTVALUE — легитимная функция MySQL для работы с XML, но в руках злоумышленника она превращается в инструмент для кражи данных через error-based SQL-инъекции. Понимание механизма атаки помогает разработчикам и администраторам правильно выстраивать защиту. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Если вы нашли такую уязвимость в своём приложении, немедленно проведите аудит кода и обновите методы работы с базой данных. Безопасность — это процесс, а не разовое действие.
Комментарии
—Войдите, чтобы оставить комментарий