Введение
В логах веб-сервера или в поле ввода часто встречается загадочная строка: %')))) AND EXTRACTVALUE(6031,CONCAT(0x7e,((SELECT (ELT(6031=6031,1)))),0x7e))-- -. Многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение данных из базы через функцию EXTRACTVALUE. В данной статье мы подробно разберём каждый элемент этого запроса, объясним, как он работает, и расскажем, как защититься от подобных атак.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Злоумышленник вставляет вредоносный SQL-код в поля ввода или параметры URL, чтобы заставить сервер выполнить непредусмотренные запросы к базе данных. Целью может быть кража конфиденциальной информации (пароли, номера карт), изменение или удаление данных, а иногда и полный контроль над сервером.
Приведённая строка — это типичный пример «слепой» SQL-инъекции, когда атакующий не видит напрямую результаты запроса, но может извлекать данные посимвольно, используя ошибки базы данных.
Разбор строки инъекции
Давайте разложим запрос на составляющие:
%')))) AND EXTRACTVALUE(6031,CONCAT(0x7e,((SELECT (ELT(6031=6031,1)))),0x7e))-- -
- %' — закрывающая кавычка и процент, часто используемые для завершения исходного SQL-запроса и добавления собственного кода.
- )))) — закрывающие скобки, чтобы «подогнать» синтаксис под исходный запрос.
- AND EXTRACTVALUE(...) — вызов функции EXTRACTVALUE, которая извлекает данные из XML и генерирует ошибку, если результат не соответствует ожидаемому формату.
- 6031 — произвольное число, часто используется как идентификатор для проверки условия.
- CONCAT(0x7e, ..., 0x7e) — конкатенация символа тильды (~) с полезной нагрузкой, чтобы отделить выводимые данные в сообщении об ошибке.
- SELECT (ELT(6031=6031,1)) — подзапрос, возвращающий 1, если условие истинно (6031=6031 всегда истинно). ELT — функция, возвращающая N-й элемент из списка.
- -- - — комментарий, обрезающий остаток исходного запроса.
Как работает EXTRACTVALUE?
Функция EXTRACTVALUE в MySQL (и MariaDB) предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_документ, XPath_выражение). Если XPath-выражение возвращает не текстовый узел, а, например, несколько узлов или недопустимый символ, MySQL генерирует ошибку с сообщением, содержащим результат вычисления.
Злоумышленники используют эту особенность для вывода данных: они передают в качестве XPath строку, содержащую конкатенацию тильды и результата подзапроса. Если подзапрос возвращает, например, версию базы данных, она попадёт в текст ошибки, который затем отобразится на странице или сохранится в логе. Это позволяет атакующему «читать» данные по частям.
Пример работы
Предположим, что внедряемый фрагмент выполняется в контексте запроса SELECT * FROM users WHERE id = '...'. После подстановки получается:
SELECT * FROM users WHERE id = '%')))) AND EXTRACTVALUE(6031,CONCAT(0x7e,((SELECT (ELT(6031=6031,1)))),0x7e))-- -'
База данных выполнит функцию EXTRACTVALUE. Поскольку XPath-выражение начинается с символа ~ (тильда), который не является допустимым началом XPath, MySQL выдаст ошибку вида: XPATH syntax error: '~1~'. Здесь 1 — результат подзапроса. В реальной атаке вместо ELT(6031=6031,1) может быть подставлен другой подзапрос, например, (SELECT password FROM users LIMIT 1), и тогда в ошибке появится пароль.
Зачем нужен ELT?
Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(6031=6031,1) вернёт 1, так как условие истинно. Это простейший способ вернуть константу, но в более сложных атаках ELT может использоваться для извлечения данных из базы, например: ELT(1, (SELECT table_name FROM information_schema.tables LIMIT 1)). Однако в нашем примере это лишь демонстрация возможности выполнения подзапросов.
Последствия успешной атаки
Если злоумышленнику удаётся эксплуатировать уязвимость, он может:
- Получить доступ к учётным данным пользователей (логины, пароли, хеши).
- Извлечь данные банковских карт, персональную информацию.
- Изменить или удалить содержимое базы данных.
- Выполнить произвольные команды на сервере (в некоторых конфигурациях).
Поэтому важно своевременно обнаруживать и блокировать такие попытки.
Как защититься от SQL-инъекций через EXTRACTVALUE
Основные меры защиты:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не смешиваются с кодом SQL.
- Экранирование специальных символов — но этот метод уступает параметризации и может быть обойдён.
- Валидация и фильтрация входных данных — например, отклонение запросов, содержащих подозрительные конструкции (EXTRACTVALUE, CONCAT, ELT и т.п.).
- Ограничение прав пользователя базы данных — учётная запись веб-приложения не должна иметь прав на выполнение опасных функций.
- Регулярный аудит логов — появление строк, подобных описанной, сигнализирует о попытках взлома.
- Использование WAF (Web Application Firewall) — современные WAF умеют распознавать шаблоны SQL-инъекций и блокировать их.
Заключение
Строка %')))) AND EXTRACTVALUE(6031,CONCAT(0x7e,((SELECT (ELT(6031=6031,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, использующая особенности функций MySQL для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои системы. Если вы встретили подобную строку в логах, это повод немедленно проверить безопасность вашего веб-приложения и базы данных.
Комментарии
—Войдите, чтобы оставить комментарий