Что это за строка

Строка AND EXTRACTVALUE(5276,CONCAT(0x7e,((SELECT (ELT(5276=5276,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции против СУБД MySQL. Такие строки можно увидеть в логах веб-сервера, в отчётах WAF (Web Application Firewall) или в баг-трекерах пентестеров. Она не является обычным пользовательским вводом: это фрагмент атаки, который пытается заставить базу данных выдать скрытую информацию через текст ошибки.

Ключевой элемент — функция EXTRACTVALUE(). Она входит в набор XML-функций MySQL и предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим этот самый XPath. Именно на этом строится атака: злоумышленник подставляет в XPath результат подзапроса, и СУБД сама «печатает» нужные данные в сообщении об ошибке.

Как работает EXTRACTVALUE в MySQL

Синтаксис функции простой:

EXTRACTVALUE(XML_документ, XPath_выражение)

Первый аргумент — строка с XML, второй — путь к узлу. Если XPath синтаксически корректен, функция вернёт содержимое узла. Если нет — сгенерирует ошибку вида XPATH syntax error: '...', где в кавычках окажется кусок переданного XPath. Это и есть канал утечки.

Функция доступна в MySQL 5.1 и выше, а также в MariaDB. В новых версиях MySQL 8 она помечена как устаревшая, но всё ещё присутствует. Именно поэтому старые веб-приложения и CMS остаются уязвимыми.

Пошаговый разбор строки

  1. AND — логический оператор, который присоединяется к существующему условию WHERE в запросе приложения. Атакующий рассчитывает, что исходный SQL выглядит примерно так: SELECT ... WHERE id = 1 AND EXTRACTVALUE(...).
  2. EXTRACTVALUE(5276, ...) — первый аргумент (5276) здесь не важен: это просто заглушка, потому что XML-документ всё равно не используется по назначению.
  3. CONCAT(0x7e, ..., 0x7e) — конкатенация. Символ 0x7e — это шестнадцатеричный код тильды ~. Тильды служат маркерами-разделителями, чтобы в тексте ошибки было легко найти полезную нагрузку.
  4. (SELECT (ELT(5276=5276,1))) — вложенный подзапрос. Условие 5276=5276 всегда истинно, поэтому ELT(1,1) вернёт строку «1». В реальной атаке вместо этого подзапроса подставляют, например, SELECT version() или SELECT password FROM users LIMIT 1.
  5. -- - — комментарий. В MySQL -- начинает комментарий только если после него есть пробел или управляющий символ. Поэтому пишут -- - или --+, чтобы «съесть» остаток оригинального запроса.

В результате MySQL пытается разобрать XPath вида ~1~, терпит неудачу и возвращает ошибку с текстом, содержащим ~1~. Если вместо «1» стоял бы реальный подзапрос, в ошибке утекли бы данные.

Зачем атакующий использует именно EXTRACTVALUE

  • Приложение не всегда выводит данные SELECT на страницу — но ошибки СУБД часто показываются в отладке.
  • Функция позволяет обойти фильтры, которые блокируют UNION SELECT.
  • Она работает даже там, где приложение возвращает лишь булево «да/нет», потому что ошибка — это отдельный канал.
  • Аналогичные техники используют функции UPDATEXML(), GTID_SUBSET(), EXP() и POLYGON().

Чем опасна error-based инъекция

Если сайт уязвим, злоумышленник может:

  • узнать версию MySQL и имя текущей базы;
  • перечислить таблицы и колонки через information_schema;
  • извлечь логины, хеши паролей, токены, номера карт;
  • при достаточных правах — читать и записывать файлы, выполнять команды ОС.

Даже если конкретно этот запрос с 5276=5276 безобиден и служит лишь проверкой («слепая» разведка), он показывает, что приложение принимает пользовательский ввод без параметризации.

Как защититься

  1. Параметризованные запросы. Используйте prepared statements в PDO, mysqli, JDBC, Hibernate, SQLAlchemy. Это базовое и самое надёжное средство.
  2. Валидация ввода. Если поле ожидает число — приводите его к int, если идентификатор — сверяйте с белым списком.
  3. Отключите вывод ошибок СУБД. В production-режиме пользователь не должен видеть текст MySQL-ошибок. Логи — только на сервере.
  4. WAF и сигнатуры. Современные WAF ловят шаблоны extractvalue, updatexml, concat(0x7e. Но полагаться только на них нельзя.
  5. Минимальные привилегии. Учётная запись приложения не должна иметь прав на FILE, information_schema сверх необходимого, на смену схемы.
  6. Обновляйте MySQL. В свежих версиях XML-функции устарели, но обновление закрывает и другие векторы.

Что делать, если вы увидели такую строку в логах

Скорее всего, ваш сайт сканирует автоматический сканер уязвимостей или бот. Это не обязательно успешная атака. Проверьте:

  • не было ли следом запросов с UNION SELECT, sleep(), benchmark();
  • не менялись ли данные в БД;
  • какие IP и User-Agent оставили запросы;
  • обновите CMS и плагины, если они давно не обновлялись.

Если сайт написан на заказ — прогоните код через SAST-анализатор или закажите пентест. Одна такая строка в логе — это повод провести аудит, а не паниковать.

Короткий итог

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

Источники