Что такое OR EXTRACTVALUE?
Строка OR EXTRACTVALUE(7047,CONCAT(0x7e,((SELECT (ELT(7047=7047,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через вывод сообщения об ошибке. Злоумышленник внедряет вредоносный код в SQL-запрос, и сервер возвращает в тексте ошибки результат выполнения подзапроса — то есть информацию, которую атакующий пытается получить.
Функция EXTRACTVALUE() в MySQL предназначена для работы с XML-документами: она извлекает значение из XML по заданному XPath-выражению. Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, в тексте которой может отображаться переданная строка. Именно это свойство и используют для проведения атаки.
Разбор строки по частям
Рассмотрим конструкцию детально:
- OR — логический оператор, который добавляется к исходному запросу, чтобы инъекция сработала в контексте условия WHERE.
- EXTRACTVALUE(7047, ...) — первый аргумент (7047) — это произвольное число, которое в данном случае служит идентификатором (может быть любым). Второй аргумент — XPath-выражение.
- CONCAT(0x7e, ((SELECT (ELT(7047=7047,1)))), 0x7e) — функция CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа «~» (тильда). ELT(7047=7047,1) — функция ELT возвращает N-й элемент из списка; условие 7047=7047 всегда истинно, поэтому возвращается 1. Таким образом, в XPath попадает строка вида «~1~».
- -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не возникло синтаксической ошибки.
В результате MySQL пытается выполнить XPath-выражение «~1~», что вызывает ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и выводится результат подзапроса (в данном примере — «1»).
Зачем нужен ELT(7047=7047,1)?
ELT — это функция MySQL, которая возвращает N-й элемент из списка. Синтаксис: ELT(N, str1, str2, ...). Если N=1, возвращается первая строка. Выражение 7047=7047 всегда истинно и в числовом контексте даёт 1. Таким образом, ELT возвращает «1» — это простейший тест, чтобы убедиться, что инъекция работает. В реальных атаках вместо «1» подставляют подзапросы, извлекающие имена таблиц, колонок или данные пользователей.
Как работает error-based SQL-инъекция через EXTRACTVALUE
Механизм атаки следующий:
- Злоумышленник находит параметр, который подставляется в SQL-запрос без должной обработки.
- В параметр внедряется конструкция с EXTRACTVALUE и подзапросом, извлекающим нужные данные.
- СУБД выполняет запрос, и из-за некорректного XPath-выражения возникает ошибка.
- Текст ошибки возвращается пользователю (или сохраняется в логах, доступных атакующему), и в нём содержится результат подзапроса.
Это один из самых удобных методов извлечения данных, так как не требует слепого перебора (boolean-based) или временных задержек (time-based). Однако он работает только если приложение выводит сообщения об ошибках СУБД.
Другие функции для error-based инъекций
Помимо EXTRACTVALUE, в MySQL для этих целей используют:
- UPDATEXML() — также работает с XML и генерирует ошибку при некорректном XPath.
- GTID_SUBSET(), JSON_KEYS() и другие функции, вызывающие ошибки с полезной нагрузкой.
- floor() в связке с группировкой — классический пример error-based инъекции.
Все они эксплуатируют одну и ту же идею: заставить СУБД вывести в сообщении об ошибке контролируемые данные.
Как защититься от SQL-инъекций
Основной способ защиты — использование параметризованных запросов (prepared statements). В этом случае данные пользователя передаются отдельно от SQL-кода и не могут изменить структуру запроса. Дополнительные меры:
- Валидация и фильтрация всех входных данных (особенно числовых параметров).
- Отключение вывода подробных сообщений об ошибках СУБД в production-окружении.
- Использование ORM и современных фреймворков, которые по умолчанию применяют параметризацию.
- Регулярное обновление СУБД и приложений.
- Применение WAF (Web Application Firewall) для блокировки подозрительных запросов.
Важно: даже если сайт не выводит ошибки, злоумышленник может использовать слепые методы инъекций. Поэтому параметризация запросов обязательна для любого взаимодействия с базой данных.
Пример уязвимого кода
Рассмотрим фрагмент на PHP, который может быть уязвим:
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = $id";
$result = mysqli_query($conn, $query);
Если в параметр id передать 1 OR EXTRACTVALUE(7047,CONCAT(0x7e,((SELECT (ELT(7047=7047,1)))),0x7e))-- -, то итоговый запрос станет:
SELECT * FROM products WHERE id = 1 OR EXTRACTVALUE(7047,CONCAT(0x7e,((SELECT (ELT(7047=7047,1)))),0x7e))-- -
MySQL выполнит его и вернёт ошибку с текстом «~1~». Чтобы этого избежать, следует использовать подготовленные выражения:
$stmt = $conn->prepare("SELECT * FROM products WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
В этом случае любой ввод будет восприниматься как значение, а не как часть SQL-кода.
Заключение
Строка OR EXTRACTVALUE(7047,CONCAT(0x7e,((SELECT (ELT(7047=7047,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки уязвимости MySQL-инъекций. Понимание принципов его работы помогает разработчикам осознать важность защиты и внедрять безопасные методы работы с базой данных. Если вы обнаружили такую строку в логах своего сайта — это признак попытки взлома, и стоит немедленно проверить код на наличие уязвимостей.
Комментарии
—Войдите, чтобы оставить комментарий