Что это за строка?

Строка %')))) AND EXTRACTVALUE(7119,CONCAT(0x7e,((SELECT (ELT(7119=7119,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы данных через вывод сообщений об ошибках.

Подобные строки часто встречаются в логах веб-серверов, в полях ввода форм, в параметрах URL. Они могут быть как результатом автоматизированного сканирования уязвимостей, так и целенаправленной атаки.

Разбор компонентов инъекции

Рассмотрим каждый элемент подробно.

1. %')))) — закрытие исходного запроса

Символ % в URL-кодировании соответствует пробелу или другому символу (в зависимости от контекста). Далее идут закрывающие кавычки и скобки: ')))). Это попытка «закрыть» оригинальный SQL-запрос, чтобы внедрить свой код. Например, если уязвимый запрос выглядит как SELECT * FROM users WHERE id = ('$input'), то вставка ')))) закроет кавычку и скобки, позволив добавить произвольное выражение.

2. AND EXTRACTVALUE(7119,CONCAT(0x7e,((SELECT (ELT(7119=7119,1)))),0x7e)) — вызов уязвимой функции

EXTRACTVALUE — это встроенная функция MySQL (до версии 8.0.17), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Если XPath-выражение некорректно, функция генерирует ошибку, которая включает в себя переданные данные. Это и используется для внедрения.

В данном случае:

  • Первый аргумент — 7119 (произвольное число, может быть любым).
  • Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(7119=7119,1)))), 0x7e).

0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.

3. (SELECT (ELT(7119=7119,1))) — подзапрос для проверки

ELT — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, str1, str2, ...). Если N=1, возвращается первая строка, если N=2 — вторая и т.д. Если N меньше 1 или больше количества строк, возвращается NULL.

Выражение 7119=7119 всегда истинно (1). Таким образом, ELT(1, 1) вернёт строку '1'. Это простейшая проверка, которая может быть заменена на любой другой подзапрос, например, для извлечения имени пользователя или хеша пароля.

4. -- - — комментарий

Два дефиса с пробелом в MySQL означают начало комментария до конца строки. Это позволяет «отрезать» оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.

Как это работает на практике

Предположим, уязвимый запрос на сервере выглядит так:

SELECT * FROM products WHERE category = '$cat'

Злоумышленник передаёт в параметр cat строку:

%')))) AND EXTRACTVALUE(7119,CONCAT(0x7e,((SELECT (ELT(7119=7119,1)))),0x7e))-- -

После подстановки запрос принимает вид:

SELECT * FROM products WHERE category = '%')))) AND EXTRACTVALUE(7119,CONCAT(0x7e,((SELECT (ELT(7119=7119,1)))),0x7e))-- -'

База данных пытается выполнить этот запрос. Функция EXTRACTVALUE получает второй аргумент, содержащий символ ~ и результат подзапроса. Поскольку XPath-выражение ~1~ некорректно (тильда не является допустимым XPath), MySQL генерирует ошибку:

XPATH syntax error: '~1~'

В сообщении об ошибке отображается результат выполнения подзапроса — в данном случае '1'. Если заменить ELT(7119=7119,1) на, например, SELECT password FROM users LIMIT 1, то в ошибке появится хеш пароля.

Цели и опасность

Основная цель такой инъекции — получить доступ к конфиденциальным данным: учётным записям, персональной информации, данным банковских карт. Error-based инъекции особенно опасны, потому что они позволяют извлекать данные посимвольно, используя вывод ошибок. Злоумышленник может автоматизировать процесс с помощью инструментов вроде sqlmap.

Кроме того, подобные строки могут быть частью более сложных атак, включающих обход аутентификации, выполнение административных операций или даже выполнение команд на сервере (при наличии соответствующих привилегий).

Как защититься

Чтобы предотвратить SQL-инъекции, необходимо следовать следующим правилам:

  • Использовать подготовленные выражения (prepared statements). Это самый надёжный способ, при котором данные передаются отдельно от SQL-кода.
  • Применять ORM (например, Doctrine, Hibernate). Они автоматически экранируют параметры.
  • Валидировать и фильтровать входные данные. Не доверяйте никаким данным от пользователя.
  • Ограничить права пользователя БД. Веб-приложение должно работать с минимально необходимыми привилегиями.
  • Обновлять СУБД и библиотеки. В MySQL 8.0.17 функция EXTRACTVALUE удалена, что снижает риск подобных атак.
  • Использовать WAF (Web Application Firewall). Он может блокировать подозрительные запросы.

Также рекомендуется регулярно проводить аудит безопасности и сканирование уязвимостей.

Заключение

Строка %')))) AND EXTRACTVALUE(7119,CONCAT(0x7e,((SELECT (ELT(7119=7119,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, использующая особенности функций MySQL для извлечения данных через ошибки. Понимание её работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.

Если вы обнаружили такую строку в логах, это сигнал о попытке взлома. Необходимо немедленно проверить код на наличие уязвимостей и принять меры.

Источники