Введение

SQL-инъекции остаются одной из самых распространённых угроз для веб-приложений. Особый интерес представляют техники, использующие встроенные функции СУБД для извлечения данных или проведения слепых атак. В запросе "))) AND EXTRACTVALUE(2125,CONCAT(0x7e,((SELECT (ELT(2125=2125,1)))),0x7e))-- - демонстрируется классический пример инъекции, нацеленной на MySQL. В этой статье мы детально разберём, как работает такая конструкция, какие функции задействованы и как от неё защититься.

Что такое EXTRACTVALUE?

Функция EXTRACTVALUE изначально предназначена для работы с XML-данными. В различных СУБД (Oracle, MySQL) она принимает два аргумента: XML-документ (или XMLType) и выражение XPath, возвращая скалярное значение указанного узла. Согласно документации Oracle, результат должен быть единственным узлом — текстовым, атрибутом или элементом. Если узел является элементом, он должен содержать единственный текстовый узел.

В MySQL функция EXTRACTVALUE(XML_frag, XPath_expr) возвращает текст первого текстового узла, соответствующего XPath-выражению. Если совпадений нет или их несколько, генерируется ошибка. Именно это свойство — генерация ошибки с полезной нагрузкой — и используется злоумышленниками.

Синтаксис и особенности

  • В Oracle: EXTRACTVALUE(XMLType_instance, XPath_string).
  • В MySQL: EXTRACTVALUE(xml_frag, xpath_expr).
  • Возвращает текст, атрибут или элемент.
  • При неверном XPath или множественном результате выбрасывает ошибку.

Роль CONCAT и ELT в инъекции

Функция CONCAT объединяет строки. В нашем примере она собирает строку из трёх частей: символа 0x7e (тильда ~), результата подзапроса (SELECT (ELT(2125=2125,1))) и ещё одной тильды. Тильда используется как маркер, чтобы облегчить поиск вывода в сообщении об ошибке.

ELT (Enum List Type) возвращает N-й элемент из списка. Выражение ELT(2125=2125,1) возвращает 1, так как условие 2125=2125 истинно (в MySQL TRUE эквивалентно 1). Это простейший случай, но в реальной атаке на месте 1 может быть подзапрос, извлекающий данные (например, имя таблицы, версию СУБД, хеши паролей).

Классическая слепая SQL-инъекция: злоумышленник заставляет базу данных выдать ошибку, содержащую конфиденциальные данные, через сообщение функции EXTRACTVALUE.

Как работает весь запрос

Рассмотрим по частям:

  1. "))) — закрывающие скобки и кавычки, завершающие оригинальный запрос приложения.
  2. AND EXTRACTVALUE(2125, CONCAT(0x7e, (SELECT (ELT(2125=2125,1))), 0x7e)) — внедрённое условие.
  3. -- - — комментарий, отсекающий остаток исходного SQL-запроса.

Первый аргумент 2125 — произвольное число, которое MySQL попытается интерпретировать как XML. Поскольку это не корректный XML, функция выдаст ошибку. Однако перед этим вычислится второй аргумент — XPath-выражение, собранное через CONCAT. В результате в тексте ошибки появится что-то вроде: XPATH syntax error: '~1~'. Тильды обрамляют извлечённое значение, что позволяет атакующему легко его найти.

Пример вывода ошибки

В MySQL ошибка может выглядеть так:

ERROR 1105 (HY000): XPATH syntax error: '~1~'

Если вместо 1 подставить подзапрос, например (SELECT version()), в ошибке отобразится версия СУБД. Это основной вектор извлечения данных.

Зачем это нужно злоумышленнику?

Основная цель — обойти фильтры и получить информацию о базе данных, когда прямой вывод данных невозможен (например, при отсутствии UNION-инъекции). EXTRACTVALUE позволяет реализовать слепую инъекцию с выводом через ошибки (error-based SQL injection). Это один из самых эффективных методов, так как не требует множества запросов для побитового угадывания.

Методы защиты

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

  • Параметризованные запросы (prepared statements) — самый надёжный способ. Данные передаются отдельно от SQL-кода, и внедрение становится невозможным.
  • Экранирование специальных символов — если параметризация недоступна, используйте функции экранирования (например, mysqli_real_escape_string).
  • Валидация входных данных — проверяйте типы, форматы, длину. Не допускайте попадания в запрос неожиданных символов.
  • Ограничение прав СУБД — пользователь базы данных должен иметь минимально необходимые привилегии. Отключите возможность вызова опасных функций, если они не используются.
  • Регулярные обновления — многие уязвимости закрываются в новых версиях СУБД и фреймворков.
  • WAF (Web Application Firewall) — может блокировать известные шаблоны атак, но не является панацеей.

Заключение

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

Источники