Введение

Встречая в логах или в поле ввода подобную строку: %' OR EXTRACTVALUE(5726,CONCAT(0x7e,((SELECT (ELT(5726=5726,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение данных из базы через сообщения об ошибках. В данной статье мы подробно разберём, что такое EXTRACTVALUE, как работает этот вектор атаки, и какие меры защиты существуют.

Что такое SQL-инъекция?

SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в поля ввода, URL-параметры или cookies, чтобы заставить базу данных выполнить нежелательные действия. Цели могут быть разными: от обхода аутентификации до кражи конфиденциальных данных.

Существует несколько типов SQL-инъекций:

  • Классические (in-band) — результат атаки виден прямо на странице.
  • Слепые (blind) — данные извлекаются по косвенным признакам (задержки, логические условия).
  • Error-based — информация получается через текст ошибок, которые генерирует СУБД.

Рассматриваемая строка относится именно к error-based типу. Она заставляет MySQL выдать сообщение об ошибке, содержащее результат подзапроса.

Функция EXTRACTVALUE в MySQL

EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), предназначенная для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Синтаксис:

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

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

Аналогично работает функция UPDATEXML, которая также часто применяется в error-based атаках.

Разбор вредоносной строки

Давайте детально разберём конструкцию:

%' OR EXTRACTVALUE(5726,CONCAT(0x7e,((SELECT (ELT(5726=5726,1)))),0x7e))-- -

Она состоит из нескольких частей:

  1. %' — попытка закрыть строковый литерал в исходном запросе. Знак процента часто используется для обхода фильтров (например, в LIKE).
  2. OR — логический оператор, позволяющий внедрить условие.
  3. EXTRACTVALUE(5726, ...) — вызов уязвимой функции. Первый аргумент (5726) — произвольный XML-фрагмент, который не важен для атаки.
  4. CONCAT(0x7e, ..., 0x7e) — объединяет тильды (0x7e — символ ~) с результатом подзапроса. Тильды служат маркерами, чтобы легко найти вывод в сообщении об ошибке.
  5. (SELECT (ELT(5726=5726,1))) — подзапрос, возвращающий результат. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь условие 5726=5726 всегда истинно, поэтому возвращается 1. В реальной атаке вместо этого подзапроса может быть извлечение имён таблиц, паролей и т.д.
  6. -- - — комментарий, обрезающий остаток оригинального запроса.

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

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

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

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

Поскольку ошибка отображается на странице (или попадает в лог), атакующий может пошагово вытаскивать информацию по символам, используя функции SUBSTRING, ASCII и т.п.

Пример реальной атаки

Предположим, на сайте есть форма поиска, которая выполняет запрос:

SELECT * FROM articles WHERE title LIKE '%$search%'

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

%' OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -

Если приложение не фильтрует ввод, MySQL выполнит:

SELECT * FROM articles WHERE title LIKE '%%' OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -%'

И в ответе появится ошибка: XPATH syntax error: '~8.0.32~'. Так злоумышленник узнаёт версию сервера.

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

Основной метод — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому внедрённый SQL не выполняется. Дополнительные меры:

  • Экранирование специальных символов с помощью функций драйвера (например, mysqli_real_escape_string).
  • Валидация и фильтрация входных данных по белому списку.
  • Ограничение прав пользователя БД: не давать ему доступ к information_schema и лишним таблицам.
  • Отключение вывода ошибок СУБД на страницу (ведение логов).
  • Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.

Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based атаках. Злоумышленники также применяют UPDATEXML, GTID_SUBSET, XMLType и другие. Поэтому защита должна быть комплексной.

Заключение

Строка с EXTRACTVALUE — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, эксплуатирующая особенности обработки XML в MySQL. Понимание механизма таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости. Помните: безопасность веб-приложений начинается с параметризованных запросов и внимательного отношения к пользовательскому вводу.

Источники