Что это за строка?
Строка )))) AND EXTRACTVALUE(9405,CONCAT(0x7e,((SELECT (ELT(9405=9405,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке, которое генерируется функцией EXTRACTVALUE при передаче ей специально сформированного аргумента.
Подобные строки часто встречаются в отчётах об уязвимостях, в логах веб-серверов или в материалах по пентесту. Они не являются вредоносным кодом сами по себе, но демонстрируют методику эксплуатации недостаточной фильтрации входных данных в SQL-запросах.
Разбор компонентов инъекции
Рассмотрим каждый элемент строки подробно.
1. Начальные символы `))))`
Последовательность из четырёх закрывающих скобок обычно используется для «закрытия» ранее открытых скобок в оригинальном SQL-запросе. Злоумышленник предполагает, что в уязвимом запросе уже есть несколько открытых скобок, и добавляет закрывающие, чтобы синтаксис стал корректным для внедряемой части. Это типичный приём при ручной эксплуатации SQL-инъекций.
2. Оператор `AND`
Логический оператор AND присоединяет внедряемое условие к исходному запросу. Если исходный запрос был истинным, то добавление AND ... позволит выполнить внедряемую функцию только при выполнении определённых условий. В данном случае это необходимо для того, чтобы функция EXTRACTVALUE вызвалась и сгенерировала ошибку.
3. Функция `EXTRACTVALUE(9405, CONCAT(...))`
EXTRACTVALUE — это встроенная функция MySQL (до версии 8.0.17 включительно), предназначенная для извлечения значения из XML-строки по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr).
Если второй аргумент не является корректным XPath-выражением, MySQL возвращает ошибку XPATH syntax error, в тексте которой отображается переданная строка. Это и используется для извлечения данных: злоумышленник подставляет в XPath результат подзапроса, и СУБД возвращает его в сообщении об ошибке.
Первый аргумент 9405 — произвольное число, которое в данном случае не играет роли, так как всё равно будет вызвана ошибка из-за второго аргумента.
4. `CONCAT(0x7e, (SELECT (ELT(9405=9405,1))), 0x7e)`
Функция CONCAT объединяет несколько строк. Здесь используется:
0x7e— шестнадцатеричное представление символа~(тильда). Тильда добавляется в начало и конец, чтобы отделить выводимые данные от остального текста ошибки и облегчить их извлечение.(SELECT (ELT(9405=9405,1)))— подзапрос, возвращающий результат функцииELT.
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(9405=9405, 1) — условие 9405=9405 всегда истинно, что в числовом контексте даёт 1. Значит, ELT(1, 1) вернёт строку '1'. Это простейший пример, демонстрирующий работу конструкции. В реальной атаке вместо 1 могло бы быть имя пользователя, хеш пароля или другая конфиденциальная информация, полученная через подзапрос.
5. Завершающая последовательность `-- -`
Два дефиса и пробел (или дефис) — это комментарий в SQL. Всё, что идёт после -- , игнорируется парсером. Это позволяет «отрезать» остаток оригинального запроса, который мог бы помешать выполнению инъекции. Пробел после дефисов обязателен в некоторых реализациях MySQL, поэтому часто пишут -- - или --+.
Как это работает на практике
Предположим, на сервере выполняется запрос вида:
SELECT * FROM users WHERE id = '$input';
Если в $input передать нашу строку, запрос станет таким:
SELECT * FROM users WHERE id = ')))) AND EXTRACTVALUE(9405,CONCAT(0x7e,((SELECT (ELT(9405=9405,1)))),0x7e))-- -';
После подстановки MySQL попытается выполнить EXTRACTVALUE с некорректным XPath, что вызовет ошибку:
XPATH syntax error: '~1~'
В тексте ошибки мы видим ~1~ — это результат выполнения подзапроса. Если бы вместо 1 стоял, например, (SELECT password FROM users LIMIT 1), в ошибке отобразился бы пароль.
Почему это опасно?
Error-based SQL-инъекции через EXTRACTVALUE (а также через UPDATEXML) позволяют злоумышленнику извлекать произвольные данные из базы, если приложение не фильтрует входные параметры и выводит ошибки СУБД пользователю. Это может привести к утечке конфиденциальной информации, компрометации учётных записей и полному захвату базы данных.
Начиная с MySQL 8.0.17, функции EXTRACTVALUE и UPDATEXML объявлены устаревшими и в новых версиях могут быть удалены. Однако на множестве устаревших систем они по-прежнему доступны и используются атакующими.
Как защититься?
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ предотвратить SQL-инъекции, так как данные не попадают в текст запроса напрямую.
- Экранируйте специальные символы. Если параметризация невозможна, применяйте функции экранирования, предоставляемые драйвером БД.
- Отключите вывод ошибок СУБД в продакшене. Сообщения об ошибках не должны показываться пользователю — это затрудняет эксплуатацию error-based инъекций.
- Обновляйте СУБД. В новых версиях MySQL опасные функции могут быть удалены или изменены.
- Проводите регулярные сканирования уязвимостей. Используйте автоматические сканеры и ручной аудит кода.
Заключение
Строка )))) AND EXTRACTVALUE(9405,CONCAT(0x7e,((SELECT (ELT(9405=9405,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции в MySQL. Она показывает, как через функцию EXTRACTVALUE можно заставить СУБД вывести произвольные данные в сообщении об ошибке. Понимание таких векторов атак необходимо для разработки безопасных веб-приложений и защиты баз данных.
Комментарии
—Войдите, чтобы оставить комментарий