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