Что такое SQL-инъекция через EXTRACTVALUE?

SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленники внедряют вредоносный код в SQL-запросы, чтобы получить доступ к базе данных. Существует несколько типов таких атак: union-based, boolean-based, time-based и error-based. Запрос, который вы видите, относится к последнему типу — error-based SQL-инъекции с использованием функции EXTRACTVALUE в СУБД MySQL.

Функция EXTRACTVALUE предназначена для работы с XML-документами. Она принимает два аргумента: фрагмент XML-разметки и выражение XPath. Функция возвращает текст первого узла, соответствующего XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, которая может содержать полезную для атакующего информацию.

Разбор конкретного запроса

Рассмотрим запрос: )) AND EXTRACTVALUE(9325,CONCAT(0x7e,((SELECT (ELT(9325=9325,1)))),0x7e))-- -

Этот фрагмент — классический пример error-based SQL-инъекции. Разберём его по частям:

  • )) — закрывающие скобки, завершающие оригинальный запрос приложения.
  • AND — логический оператор, присоединяющий условие.
  • EXTRACTVALUE(9325, CONCAT(...)) — вызов уязвимой функции. Первый аргумент (9325) — произвольное число, которое не влияет на результат, так как оно не является корректным XML. Второй аргумент — конкатенация строки с тильдой (0x7e), результата подзапроса и ещё одной тильды.
  • SELECT (ELT(9325=9325,1)) — подзапрос, который возвращает 1, так как условие 9325=9325 всегда истинно. ELT — функция, возвращающая N-й элемент из списка. Здесь она возвращает первый элемент — 1.
  • -- - — комментарий, обрезающий остаток оригинального запроса.

В результате MySQL пытается интерпретировать строку, начинающуюся с символа ~, как XPath-выражение. Это вызывает ошибку вида: XPATH syntax error: '~1~'. В сообщении об ошибке отображается результат подзапроса (в данном случае 1). Если вместо 1 подставить, например, (SELECT user()), то в ошибке появится имя текущего пользователя базы данных. Так злоумышленник может извлекать произвольные данные.

Зачем нужна такая сложная конструкция?

Основная цель — заставить сервер вернуть данные в сообщении об ошибке. Когда приложение выводит ошибки СУБД на страницу, атакующий может читать содержимое базы. Если вывод ошибок отключён, этот метод не сработает.

Конкатенация с 0x7e (тильда) используется для того, чтобы XPath-выражение начиналось с недопустимого символа. Это гарантирует синтаксическую ошибку и вывод полезной нагрузки в тексте ошибки. Тильда выбрана как маркер, чтобы легко найти начало и конец данных в сообщении.

Подзапрос с ELT(9325=9325,1) — это простейший пример. В реальных атаках вместо 1 подставляют вызовы функций, например database(), user(), version() или подзапросы, извлекающие имена таблиц и столбцов из information_schema.

Пошаговый пример эксплуатации

Предположим, есть уязвимый параметр id в URL: http://example.com/product?id=1. Оригинальный запрос: SELECT * FROM products WHERE id = 1.

Атакующий может отправить: 1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e)). Если приложение выводит ошибки, на странице появится сообщение: XPATH syntax error: '~shop_db~'. Так узнаётся имя базы данных.

Далее можно извлекать имена таблиц: 1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x7e)). Меняя параметры LIMIT, перебирают все таблицы. Затем аналогично получают столбцы и данные.

Меры защиты

Чтобы предотвратить подобные атаки, необходимо:

  • Использовать подготовленные выражения (prepared statements). Это самый надёжный способ, так как данные не смешиваются с кодом запроса.
  • Экранировать все входные данные. Применяйте функции экранирования, соответствующие вашей СУБД.
  • Отключить вывод ошибок СУБД на страницу. Пользователь не должен видеть детали ошибок. Логируйте их на сервере.
  • Ограничить права пользователя базы данных. Не используйте учётную запись с правами администратора для веб-приложения.
  • Регулярно обновлять СУБД и фреймворки. В новых версиях MySQL функция EXTRACTVALUE помечена как устаревшая, но всё ещё может быть доступна.
Важно: материал носит ознакомительный характер. Применение описанных техник без письменного разрешения владельца системы является нарушением закона.

Заключение

Запрос )) AND EXTRACTVALUE(9325,CONCAT(0x7e,((SELECT (ELT(9325=9325,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции. Он показывает, как через ошибки XPath можно извлечь данные из базы MySQL. Понимание таких атак помогает разработчикам и специалистам по безопасности лучше защищать веб-приложения.

Источники