Что это за строка?
Строка ))) AND EXTRACTVALUE(1152,CONCAT(0x7e,((SELECT (ELT(1152=1152,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (SQL-инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы через вывод сообщения об ошибке, которое возвращается приложением.
Подобные строки можно встретить в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) или в специализированных уязвимых приложениях (например, DVWA, SQLZoo), предназначенных для обучения пентестеров. Они не являются частью легитимного кода, а служат инструментом атаки.
Разбор структуры инъекции
Рассмотрим каждый элемент подробно.
1. )))
Три закрывающие скобки. В контексте SQL-запроса они могут закрывать ранее открытые скобки в уязвимом параметре. Например, если исходный запрос выглядит как SELECT * FROM users WHERE id = (('$input')), то вставка ))) позволит «выровнять» синтаксис и добавить собственные условия.
2. AND
Логический оператор, который присоединяет нашу инъекцию к оригинальному условию. Он гарантирует, что внедряемый код выполнится только если предыдущее выражение истинно (или в сочетании с другими операторами).
3. EXTRACTVALUE(1152, CONCAT(...))
EXTRACTVALUE — это встроенная функция MySQL (до версии 8.0.17 включительно), предназначенная для извлечения значения из XML-строки. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой отображается переданное значение. Именно это свойство и эксплуатируется.
Первый аргумент — 1152 — произвольное число, которое в данном случае не играет роли (может быть любым). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(1152=1152,1)))), 0x7e) — конструирует строку, которая будет вставлена в сообщение об ошибке.
4. CONCAT(0x7e, ..., 0x7e)
CONCAT объединяет несколько строк. Здесь 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильды используются как маркеры, чтобы облегчить поиск выводимых данных в тексте ошибки. Между ними помещается результат подзапроса.
5. (SELECT (ELT(1152=1152,1)))
Вложенный подзапрос, который возвращает значение. ELT — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, строка1, строка2, ...). В данном случае 1152=1152 — это выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) вернёт строку '1'. Фактически это простейший пример: инъекция выведет число 1, чтобы продемонстрировать работоспособность. В реальной атаке вместо 1 мог бы стоять подзапрос, извлекающий имя пользователя, хеш пароля, версию БД и т.д.
6. -- -
Комментарий в MySQL. Два дефиса с пробелом (или -- ) начинают комментарий до конца строки. Дефис в конце часто добавляют для надёжности, чтобы гарантировать, что комментарий не «съест» лишние символы. Это позволяет отсечь остаток оригинального SQL-запроса, который мог бы помешать выполнению инъекции.
Как это работает на практике
Предположим, уязвимый запрос формируется так:
SELECT * FROM articles WHERE id = $id;
Злоумышленник передаёт в параметр id строку:
1 ))) AND EXTRACTVALUE(1152,CONCAT(0x7e,((SELECT (ELT(1152=1152,1)))),0x7e))-- -
После подстановки запрос принимает вид:
SELECT * FROM articles WHERE id = 1 ))) AND EXTRACTVALUE(1152,CONCAT(0x7e,((SELECT (ELT(1152=1152,1)))),0x7e))-- -;
MySQL пытается выполнить EXTRACTVALUE с некорректным XPath (второй аргумент не является валидным XPath-выражением), что вызывает ошибку вида:
XPATH syntax error: '~1~'
В тексте ошибки мы видим ~1~ — это и есть результат выполнения подзапроса, обрамлённый тильдами. Если приложение выводит ошибки СУБД на экран, злоумышленник получает данные. Если ошибки скрыты, атака может не сработать, но часто разработчики забывают отключить вывод ошибок в production.
Зачем это нужно злоумышленнику?
Error-based SQL-инъекция — один из методов извлечения информации из базы данных, когда другие каналы (например, UNION-based или blind) недоступны. Основные цели:
- Получение версии MySQL, имени текущей базы данных, пользователя.
- Извлечение имён таблиц и столбцов через
information_schema. - Чтение конфиденциальных данных: логинов, паролей (хешей), персональной информации.
Функция EXTRACTVALUE — не единственная, эксплуатируемая таким образом. Аналогично работают UPDATEXML, GTID_SUBSET, JSON_KEYS и другие функции, вызывающие ошибки с контролируемым текстом.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов.
- Применять ORM или библиотеки, автоматически экранирующие пользовательский ввод.
- Отключить вывод ошибок СУБД в production-окружении (display_errors = Off).
- Ограничить права пользователя БД, от имени которого работает приложение (принцип наименьших привилегий).
- Регулярно обновлять MySQL: в версии 8.0.17 функция EXTRACTVALUE удалена, что снижает риск таких инъекций.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных конструкций.
Заключение
Строка ))) AND EXTRACTVALUE(1152,CONCAT(0x7e,((SELECT (ELT(1152=1152,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как через функцию EXTRACTVALUE можно вывести произвольные данные в сообщении об ошибке. Понимание таких конструкций важно как для специалистов по безопасности, так и для разработчиков, чтобы своевременно закрывать уязвимости.
Комментарии
—Войдите, чтобы оставить комментарий