Что это за строка?
Перед вами классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер. Строка )) OR EXTRACTVALUE(5029,CONCAT(0x7e,((SELECT (ELT(5029=5029,1)))),0x7e))-- - — это попытка внедрить вредоносный код в SQL-запрос, который выполняется на уязвимом сайте.
Подобные строки часто встречаются в логах веб-серверов, в полях ввода форм, в URL-параметрах. Если вы увидели её в своих логах, значит, кто-то пытался просканировать ваш сайт на наличие уязвимостей. Если вы встретили её в чужом коде — возможно, это часть эксплойта или учебного примера.
Как работает EXTRACTVALUE в MySQL
Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_документ, XPath_выражение). Она возвращает текстовое значение узла, атрибута или элемента. Если результат не является единственным узлом или содержит ошибку, MySQL генерирует сообщение об ошибке.
Именно эта особенность используется в error-based инъекциях: злоумышленник конструирует XPath-выражение так, чтобы в тексте ошибки появились данные из базы. Например, если передать в качестве XPath строку с недопустимыми символами, MySQL вернёт ошибку вида XPATH syntax error: '...', где ... — это переданная строка. Если в эту строку подставить результат подзапроса, то в ошибке отобразятся данные.
Например, запросSELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e));вызовет ошибку:XPATH syntax error: '~5.7.34~'. Так злоумышленник узнаёт версию СУБД.
Разбор конкретной строки
Рассмотрим по частям:
))— закрывающие скобки, которые завершают предыдущий запрос. Злоумышленник предполагает, что исходный запрос имеет вложенные скобки, и пытается «выровнять» синтаксис.OR— логический оператор. Если предыдущее условие ложно, выполняется следующее. Это позволяет внедрить дополнительное выражение.EXTRACTVALUE(5029,CONCAT(0x7e,((SELECT (ELT(5029=5029,1)))),0x7e))— вызов функции EXTRACTVALUE с двумя аргументами. Первый аргумент — число 5029 (может быть любым, часто используется как идентификатор). Второй аргумент —CONCAT(0x7e, ((SELECT (ELT(5029=5029,1)))), 0x7e).0x7e— шестнадцатеричное представление символа~(тильда). Он используется как разделитель, чтобы в ошибке было легко выделить полезную нагрузку.ELT(5029=5029,1)— функция ELT возвращает N-й элемент из списка. Здесь5029=5029— это всегда истина (1), поэтому ELT(1,1) вернёт 1. Это простейшая проверка, которая не несёт полезной нагрузки, но показывает шаблон. В реальной атаке вместо1подставляется подзапрос, например(SELECT user()).-- -— комментарий в MySQL. Всё, что идёт после--(пробел обязателен), игнорируется. Это позволяет отбросить остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку.
Таким образом, строка пытается заставить сервер выполнить EXTRACTVALUE с заведомо некорректным XPath-выражением, содержащим результат подзапроса. В данном примере подзапрос возвращает просто 1, но в реальной атаке там могут быть имена таблиц, столбцов, пароли и т.д.
Зачем это нужно злоумышленнику?
Цель error-based SQL-инъекции — получить данные из базы, когда другие методы (например, UNION) недоступны. Если сайт отображает ошибки MySQL, злоумышленник может пошагово извлекать информацию: версию СУБД, имя текущей базы, список таблиц, столбцов и, наконец, сами данные (логины, пароли, номера карт).
Конструкция с EXTRACTVALUE — один из многих приёмов. Аналогично работают UPDATEXML, GTID_SUBSET, EXP и другие функции, вызывающие ошибки с контролируемым текстом.
Пример реальной атаки
Предположим, на сайте есть скрипт product.php?id=1, который выполняет запрос:
SELECT * FROM products WHERE id = $id;
Злоумышленник передаёт id=1)) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -. Если приложение не фильтрует ввод, итоговый запрос станет:
SELECT * FROM products WHERE id = 1)) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -;
Сервер выполнит подзапрос, получит имя базы и попытается вставить его в XPath. Возникнет ошибка, которая отобразится на странице. Так злоумышленник узнает имя базы. Затем аналогично извлекаются таблицы и данные.
Как защититься?
Основная защита от SQL-инъекций — использование подготовленных выражений (prepared statements) с параметризацией. Никогда не подставляйте пользовательский ввод напрямую в SQL-запрос. Также рекомендуется:
- Отключить вывод ошибок MySQL на продакшене (display_errors = off).
- Использовать ORM или библиотеки, которые автоматически экранируют данные.
- Применять принцип наименьших привилегий для пользователя БД: не давать ему прав на чтение системных таблиц, если это не нужно.
- Регулярно обновлять СУБД и веб-приложения.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Если вы нашли такую строку в логах, это сигнал о попытке взлома. Проверьте, не уязвим ли ваш сайт, и при необходимости обратитесь к специалистам по безопасности.
Вывод
Строка )) OR EXTRACTVALUE(5029,CONCAT(0x7e,((SELECT (ELT(5029=5029,1)))),0x7e))-- - — это не случайный набор символов, а осмысленный эксплойт для error-based SQL-инъекции в MySQL. Она демонстрирует, как злоумышленники используют функции работы с XML для извлечения данных через сообщения об ошибках. Понимание таких конструкций помогает разработчикам и администраторам лучше защищать свои системы.
Комментарии
—Войдите, чтобы оставить комментарий