Что такое EXTRACTVALUE в SQL-инъекции

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

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

Разбор полезной нагрузки

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

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

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

Как работает ELT и CONCAT

ELT(N, str1, str2, ...) возвращает N-ную строку из списка. В данном случае ELT(7210=7210,1): условие 7210=7210 всегда истинно, то есть равно 1. Значит, ELT(1,1) вернёт строку '1'. Это простейший тест — проверка, что инъекция выполняется. В реальной атаке вместо 1 подставляют подзапросы, извлекающие имена таблиц, колонок или данные пользователей.

Функция CONCAT объединяет тильды и результат подзапроса в одну строку. Затем EXTRACTVALUE пытается интерпретировать эту строку как XPath-выражение. Поскольку строка начинается с ~, это невалидный XPath, и MySQL выдаёт ошибку вида:

XPATH syntax error: '~1~'

В тексте ошибки как раз и появляется результат внедрённого подзапроса. Так атакующий получает данные посимвольно или целыми строками, в зависимости от конструкции.

Зачем нужна error-based инъекция

Error-based SQL-инъекция — один из самых быстрых способов извлечения информации из базы, когда приложение не выводит данные напрямую, но отображает сообщения об ошибках СУБД. В отличие от blind-инъекций, где приходится задавать множество вопросов «да/нет», здесь результат приходит сразу в ответе сервера.

Функция EXTRACTVALUE — не единственная в своём роде. Аналогично используются UPDATEXML, GTID_SUBSET, EXP и другие функции, вызывающие ошибки с подстановкой данных. Все они эксплуатируют недостаточную фильтрацию пользовательского ввода.

Пример реального использования

Предположим, есть уязвимый URL:

https://example.com/product.php?id=1

Атакующий подставляет:

https://example.com/product.php?id=1") AND EXTRACTVALUE(7210,CONCAT(0x7e,(SELECT database()),0x7e))-- -

В ответе сервера появится ошибка с именем текущей базы данных. Далее аналогично извлекаются таблицы, колонки и записи.

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

Основная причина уязвимости — конкатенация пользовательского ввода в SQL-запрос без экранирования. Меры защиты:

  1. Параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от кода, и СУБД не интерпретирует их как SQL.
  2. Экранирование специальных символов. Если параметризация невозможна, используйте функции экранирования, например mysqli_real_escape_string.
  3. Отключение вывода ошибок СУБД. Сообщения об ошибках не должны попадать в ответ клиенту — это лишает error-based инъекции смысла.
  4. Принцип наименьших привилегий. Пользователь БД для веб-приложения не должен иметь прав на чтение системных таблиц и выполнение опасных функций.
  5. WAF и регулярные аудиты. Веб-приложения-фильтры могут блокировать подозрительные конструкции, но не заменяют исправление кода.

Заключение

Строка ") AND EXTRACTVALUE(7210,CONCAT(0x7e,((SELECT (ELT(7210=7210,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки уязвимости MySQL-базы. Понимание механики таких атак помогает разработчикам и администраторам своевременно закрывать дыры и защищать данные пользователей.

Источники