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

Строка ')) OR EXTRACTVALUE(2247,CONCAT(0x7e,((SELECT (ELT(2247=2247,1)))),0x7e))-- - — это пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют функцию EXTRACTVALUE для принудительного вызова ошибки, в тексте которой возвращаются данные из базы. Это один из самых распространённых методов атак на веб-приложения, уязвимые к SQL-инъекциям.

В данной статье мы детально разберём, как работает этот запрос, какие функции задействованы и как защититься от подобных атак.

Как работает EXTRACTVALUE?

Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис:

EXTRACTVALUE(XML_фрагмент, XPath_выражение)

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

Разбор инъекции по частям

Рассмотрим запрос ')) OR EXTRACTVALUE(2247,CONCAT(0x7e,((SELECT (ELT(2247=2247,1)))),0x7e))-- - поэтапно.

  • ')) — закрывает предыдущие скобки и кавычки в оригинальном SQL-запросе, чтобы внедрить свой код.
  • OR — логический оператор, который делает условие всегда истинным или вызывает выполнение правой части.
  • EXTRACTVALUE(2247, ...) — первый аргумент (2247) — произвольный XML-фрагмент, который не анализируется, так как второй аргумент вызывает ошибку.
  • CONCAT(0x7e, ((SELECT (ELT(2247=2247,1)))), 0x7e) — конкатенация тильды (0x7e — это символ ~), результата подзапроса и ещё одной тильды. Тильды используются как маркеры, чтобы облегчить поиск данных в сообщении об ошибке.
  • SELECT (ELT(2247=2247,1)) — подзапрос, возвращающий число 1. ELT — функция, возвращающая N-й элемент из списка; здесь список состоит из одного элемента, и условие 2247=2247 всегда истинно, поэтому возвращается 1. В реальной атаке вместо этого подзапроса злоумышленник вставляет запрос к системным таблицам для извлечения имён баз, таблиц, колонок или конкретных данных.
  • -- - — комментарий, обрезающий остаток оригинального запроса.

В результате выполнения MySQL пытается интерпретировать строку, начинающуюся с тильды, как XPath. Это вызывает ошибку вида: XPATH syntax error: '~1~'. В сообщении об ошибке возвращается результат подзапроса, заключённый между тильдами.

Зачем нужен error-based метод?

Error-based SQL-инъекция позволяет извлекать данные напрямую через сообщения об ошибках, которые отображаются на странице. Это быстрее и проще, чем blind-инъекции, где приходится угадывать символы по времени задержки или логическим условиям. Функция EXTRACTVALUE — не единственная; также часто используются UPDATEXML и GTID_SUBSET.

Основные цели атак:

  • Получение версии СУБД, имени пользователя, текущей базы данных.
  • Извлечение имён таблиц и колонок из information_schema.
  • Кража конфиденциальных данных: логинов, паролей, персональной информации.

Пример реальной эксплуатации

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

SELECT * FROM products WHERE id = '1'

Злоумышленник подставляет:

1')) OR EXTRACTVALUE(2247,CONCAT(0x7e,(SELECT database()),0x7e))-- -

Вместо SELECT (ELT(2247=2247,1)) он вставляет SELECT database(). Сервер вернёт ошибку с именем текущей базы данных. Аналогично можно извлечь любую другую информацию, например, версию MySQL или хеши паролей.

Как защититься от SQL-инъекций?

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

  1. Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают в SQL-код напрямую.
  2. Экранировать специальные символы при невозможности использовать параметризацию.
  3. Применять ORM (например, Hibernate, Entity Framework), которые автоматически генерируют безопасные запросы.
  4. Ограничить права пользователя БД: веб-приложение должно работать с минимально необходимыми привилегиями, без доступа к information_schema и системным таблицам.
  5. Отключить вывод ошибок на продакшене: сообщения об ошибках БД не должны показываться пользователю.
  6. Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
  7. Регулярно обновлять СУБД и фреймворки, чтобы закрыть известные уязвимости.
Важно: даже если сайт не выводит ошибки, злоумышленник может использовать blind-инъекции. Поэтому защита должна быть комплексной.

Заключение

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

Источники