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

В запросе пользователя фигурирует строка ') AND EXTRACTVALUE(1326,CONCAT(0x7e,((SELECT (ELT(1326=1326,1)))),0x7e))-- -. Это не случайный набор символов, а типичный пример SQL-инъекции — атаки, при которой злоумышленник внедряет вредоносный SQL-код в запрос к базе данных. Цель таких манипуляций — обойти механизмы защиты, получить доступ к скрытым данным или вызвать ошибку, которая раскроет информацию.

Конструкция использует две встроенные функции MySQL: EXTRACTVALUE и ELT. EXTRACTVALUE извлекает значение из XML-фрагмента, а ELT возвращает N-й элемент из списка строк. Вместе они позволяют вызвать ошибку, содержащую результат подзапроса, что даёт атакующему возможность читать данные из базы.

Разбор синтаксиса

Рассмотрим каждый элемент запроса:

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

В результате EXTRACTVALUE получает строку вида ~1~, которая не является корректным XML. Это вызывает ошибку с сообщением, содержащим переданную строку. Злоумышленник может заменить ELT(1326=1326,1) на подзапрос, извлекающий данные (например, имя пользователя или пароль), и прочитать их в тексте ошибки.

Зачем нужна такая инъекция?

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

Функция ELT здесь используется для генерации полезной нагрузки. В примере ELT(1326=1326,1) всегда возвращает 1, но в реальной атаке вместо условия может стоять подзапрос, возвращающий нужные данные. Например, ELT((SELECT password FROM users LIMIT 1),1) вернёт пароль, который затем попадёт в XML-строку и вызовет ошибку с его содержимым.

Почему возникает ошибка?

Функция EXTRACTVALUE в MySQL ожидает корректный XML-документ. Строка ~1~ не является валидным XML, поэтому СУБД генерирует ошибку вида:

XPATH syntax error: '~1~'

Именно этот текст и видит атакующий. Если же вместо «1» подставить конфиденциальные данные, они отобразятся в сообщении об ошибке. Это и есть основа эксплуатации.

Модификации и ограничения

Вместо EXTRACTVALUE могут использоваться другие функции, например UPDATEXML или GTID_SUBSET. Однако EXTRACTVALUE — классический инструмент. Следует отметить, что в MySQL 5.7+ и в MariaDB эта функция может быть удалена или ограничена, поэтому атакующие ищут альтернативы.

Также важно, что для успешной инъекции приложение должно передавать пользовательский ввод в SQL-запрос без должной обработки. Если используется параметризованный запрос или экранирование, атака не сработает.

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

Основные меры:

  1. Параметризованные запросы (prepared statements) — самый надёжный способ, при котором данные не смешиваются с кодом.
  2. Экранирование специальных символов — но это менее надёжно, чем параметризация.
  3. Валидация и фильтрация входных данных — например, проверка типов, длины, допустимых символов.
  4. Использование ORM — современные ORM-библиотеки автоматически применяют параметризацию.
  5. Регулярный аудит кода и сканеры уязвимостей.
  6. Минимизация привилегий пользователя БД — чтобы даже при инъекции злоумышленник не получил лишних прав.

Также рекомендуется отключать вывод подробных ошибок СУБД в продакшене, чтобы не давать атакующему информацию.

Заключение

Запрос с EXTRACTVALUE и ELT — это не просто случайный набор символов, а хорошо продуманная техника эксплуатации уязвимости. Понимание её механизма помогает разработчикам и администраторам правильно выстраивать защиту. Никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.

Источники