Введение
В запросе пользователя указана строка: %")) AND EXTRACTVALUE(6687,CONCAT(0x7e,((SELECT (ELT(6687=6687,1)))),0x7e))-- -. Это не случайный набор символов, а типичный пример error-based SQL-инъекции для СУБД MySQL. Такие строки часто встречаются в логах веб-серверов, когда злоумышленники пытаются проэксплуатировать уязвимость в параметрах приложения.
В этой статье мы разберём, что означает каждый элемент данной конструкции, как она работает и почему считается классическим приёмом атак на базы данных.
Что такое error-based SQL-инъекция?
SQL-инъекция — это способ внедрения вредоносного SQL-кода в запрос через пользовательский ввод. Error-based (основанная на ошибках) — разновидность, при которой атакующий заставляет СУБД вернуть сообщение об ошибке, содержащее полезные данные. Если приложение выводит такие ошибки на страницу, злоумышленник может читать информацию из базы: имена таблиц, логины, пароли и т.д.
В MySQL для этого часто используют функции EXTRACTVALUE и UPDATEXML. Они вызывают ошибку формата XML, если второй аргумент содержит недопустимые символы, и в тексте ошибки отображается переданное значение.
Разбор строки по частям
Рассмотрим фрагмент %")) AND EXTRACTVALUE(6687,CONCAT(0x7e,((SELECT (ELT(6687=6687,1)))),0x7e))-- - детально.
1. Префикс %"))
Знак % — это символ подстановки в LIKE-запросах. Далее идут закрывающая кавычка " и две закрывающие скобки )). Это попытка «закрыть» ранее открытые конструкции в исходном SQL-запросе, чтобы внедрить свой код. Количество скобок и кавычек подбирается под конкретный запрос.
2. AND EXTRACTVALUE(6687, ...)
Функция EXTRACTVALUE(XML_document, XPath_expression) извлекает значение из XML. Если второй аргумент не является корректным XPath-выражением, MySQL генерирует ошибку. Злоумышленник использует это для вывода данных: в тексте ошибки будет указано значение, которое он передал.
Число 6687 — это произвольный идентификатор (может быть любым). Он не несёт смысловой нагрузки, кроме как заполнить первый аргумент.
3. CONCAT(0x7e, ((SELECT (ELT(6687=6687,1)))), 0x7e)
CONCAT объединяет строки. 0x7e — шестнадцатеричное представление символа ~ (тильда). Тильда используется как разделитель, чтобы облегчить поиск выведенных данных в сообщении об ошибке.
Внутри CONCAT стоит подзапрос SELECT (ELT(6687=6687,1)). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 6687=6687 — это логическое выражение, которое всегда истинно, то есть возвращает 1. Значит, ELT(1, 1) вернёт строку '1'. Это простейший пример. В реальной атаке вместо 1 мог бы стоять подзапрос, извлекающий данные (например, SELECT password FROM users LIMIT 1), но в данном случае используется заглушка для демонстрации.
4. Завершение -- -
Два дефиса и пробел — это комментарий в SQL. Всё, что идёт после, игнорируется. Это позволяет «отрезать» остаток оригинального запроса, чтобы он не вызвал синтаксическую ошибку.
Как это работает на практике
Предположим, исходный запрос выглядит так:
SELECT * FROM articles WHERE title LIKE '%ЗАПРОС%'
После подстановки вредоносной строки вместо ЗАПРОС получаем:
SELECT * FROM articles WHERE title LIKE '%%")) AND EXTRACTVALUE(6687,CONCAT(0x7e,((SELECT (ELT(6687=6687,1)))),0x7e))-- -%'
База данных выполнит EXTRACTVALUE с аргументом, содержащим тильды и результат подзапроса. Так как XPath-выражение ~1~ некорректно, MySQL выдаст ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении атакующий увидит значение 1. Если вместо 1 подставить подзапрос к таблице пользователей, в ошибке отобразится, например, хеш пароля.
Почему это опасно?
Error-based инъекции позволяют злоумышленнику получать данные из базы посимвольно или целыми строками, не имея прямого доступа к СУБД. Если приложение показывает ошибки базы данных пользователю, это критическая уязвимость. Даже если ошибки скрыты, атакующий может использовать слепые методы, но error-based — самый быстрый и удобный способ.
Как защититься?
- Используйте подготовленные выражения (prepared statements). Они разделяют код и данные, делая внедрение невозможным.
- Экранируйте пользовательский ввод. Но это менее надёжно, чем параметризация.
- Отключайте вывод ошибок СУБД на продакшене. Пользователь не должен видеть технические детали.
- Применяйте WAF (Web Application Firewall). Он может блокировать подозрительные строки, содержащие
EXTRACTVALUEи подобные функции. - Регулярно обновляйте СУБД и фреймворки. Устаревшие версии могут иметь дополнительные уязвимости.
Заключение
Строка %")) AND EXTRACTVALUE(6687,CONCAT(0x7e,((SELECT (ELT(6687=6687,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для MySQL. Она демонстрирует, как через функцию EXTRACTVALUE и логические выражения можно заставить базу данных вывести произвольные данные в сообщении об ошибке. Понимание таких конструкций помогает разработчикам и специалистам по безопасности лучше защищать веб-приложения.
Если вы нашли подобную строку в логах — это признак попытки взлома. Следует немедленно проверить уязвимости и усилить защиту.
Комментарии
—Войдите, чтобы оставить комментарий