Что это за строка?
Строка '))) AND EXTRACTVALUE(5410,CONCAT(0x7e,((SELECT (ELT(5410=5410,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках. Подобные payload'ы часто встречаются в отчётах сканеров уязвимостей и в задачах по информационной безопасности.
В отличие от UNION-based или blind-инъекций, error-based метод заставляет сервер вернуть результат подзапроса прямо в тексте ошибки. Это делает его очень удобным для ручного анализа, когда нужно быстро получить имя пользователя, версию СУБД или другую информацию.
Разбор по частям
1. Начало: ')))
Три закрывающие скобки и апостроф. Это попытка «закрыть» оригинальный SQL-запрос, в который внедряется payload. Разработчик мог использовать конструкцию вида WHERE id = (('...')), и инъекция ломает синтаксис, добавляя свои условия.
2. AND EXTRACTVALUE(...)
EXTRACTVALUE — функция MySQL (до версии 8.0.17), которая извлекает значение из XML-строки по XPath-выражению. Если XPath содержит недопустимые символы, MySQL выбрасывает ошибку и включает в неё переданный фрагмент. Это и есть канал утечки данных.
3. 5410 и CONCAT(0x7e, ..., 0x7e)
Первый аргумент 5410 — произвольное число (может быть любым, часто используется случайное). Второй аргумент — строка, которую мы хотим «протащить» в ошибку. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как маркер, чтобы легко найти выводимые данные в тексте ошибки.
4. ((SELECT (ELT(5410=5410,1))))
Здесь мы видим подзапрос. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае 5410=5410 — это всегда истина (1), поэтому ELT(1, 1) вернёт 1. Это простейший тест: если инъекция работает, в ошибке появится ~1~. На практике вместо 1 подставляют вызовы вроде version(), user(), database() или подзапросы к information_schema.
5. Завершение: -- -
Комментарий, который «съедает» остаток оригинального запроса. Пробел после -- обязателен в MySQL, иначе комментарий не сработает. Иногда вместо -- - используют # или /* */.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = ('$input')Подставляем payload и получаем:
SELECT * FROM users WHERE id = ('1'))) AND EXTRACTVALUE(5410,CONCAT(0x7e,((SELECT (ELT(5410=5410,1)))),0x7e))-- -')СУБД выполнит EXTRACTVALUE и вернёт ошибку вида:
XPATH syntax error: '~1~'Если вместо 1 подставить version(), в ошибке появится версия MySQL. Такой метод позволяет извлекать данные посимвольно или целыми строками, если позволяет длина сообщения об ошибке.
Зачем это нужно знать?
Понимание error-based SQL-инъекций важно как для специалистов по безопасности, так и для разработчиков. OWASP регулярно включает SQL-инъекции в топ-10 критических уязвимостей. Знание конкретных payload'ов помогает:
- правильно настраивать WAF и фильтры ввода;
- проводить пентесты и аудиты кода;
- писать безопасные запросы с параметризацией.
Стоит помнить, что EXTRACTVALUE удалена в MySQL 8.0.17 и заменена на UPDATEXML и другие функции. Однако на старых версиях (5.7 и ниже) она по-прежнему работает и активно используется в эксплойтах.
Как защититься?
Главная мера — использовать подготовленные выражения (prepared statements) с параметрами. Никогда не конкатенируйте пользовательский ввод в SQL-запрос. Дополнительно:
- ограничьте права пользователя БД (не давайте доступ к
information_schemaбез необходимости); - включите логирование ошибок, но не показывайте их пользователю;
- используйте ORM с параметризацией.
Если вы нашли такую строку в логах своего сайта — это признак попытки взлома. Проверьте, не уязвим ли ваш код, и обновите MySQL до актуальной версии.
Комментарии
—Войдите, чтобы оставить комментарий