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

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

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

Анатомия инъекции

Разобьём запрос на составляющие:

  • )))) — закрывающие скобки. Они нужны, чтобы «закрыть» ранее открытые скобки в оригинальном SQL-запросе уязвимого приложения и сделать синтаксис корректным.
  • AND — логический оператор, который добавляется к условию WHERE. Если исходный запрос был, например, SELECT * FROM users WHERE id = '$input', то после подстановки получится ... WHERE id = '')))) AND ....
  • EXTRACTVALUE(3576, CONCAT(0x7e, ((SELECT (ELT(3576=3576,1)))), 0x7e)) — вызов функции MySQL, которая извлекает значение из XML-фрагмента. Если переданный XML некорректен, MySQL выдаёт ошибку с текстом, содержащим результат вложенного запроса.
  • -- - — комментарий. В MySQL -- (с последующим пробелом) означает начало комментария до конца строки. Это позволяет «отрезать» оставшуюся часть оригинального запроса, чтобы не возникло синтаксической ошибки.

Как работает EXTRACTVALUE

Функция EXTRACTVALUE(XML_document, XPath_expression) появилась в MySQL 5.1. Она принимает XML-документ и XPath-выражение, возвращая строку с найденным узлом. Если XML-документ не является корректным, функция генерирует ошибку вида:

XPATH syntax error: '~результат~'

Именно на эту ошибку и рассчитывает атакующий. Он конструирует второй аргумент так, чтобы в тексте ошибки оказались данные, которые нужно извлечь.

Роль CONCAT и 0x7e

CONCAT(0x7e, ((SELECT ...)), 0x7e) склеивает три строки: символ ~ (шестнадцатеричный код 0x7e), результат подзапроса и снова ~. Тильды служат маркерами, по которым удобно выделить полезную нагрузку в сообщении об ошибке.

Подзапрос с ELT

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(3576=3576, 1) — условие 3576=3576 всегда истинно, что в числовом контексте даёт 1. Значит, ELT вернёт первый элемент — число 1. Это простейшая проверка: если инъекция сработала, в ошибке появится ~1~.

В реальных атаках вместо 1 подставляют подзапросы вроде (SELECT password FROM users LIMIT 1), чтобы извлечь конкретные данные.

Зачем это нужно злоумышленнику?

Error-based инъекции — один из самых быстрых способов получить данные из базы, когда приложение не выводит результаты запроса напрямую, но отображает ошибки СУБД. Атакующий может посимвольно извлекать имена таблиц, колонок и содержимое полей, используя функции вроде SUBSTRING, ASCII и другие.

Конкретно этот payload с 3576=3576 и ELT(...,1) — это тестовая проверка (proof of concept). Если сервер возвращает ошибку с ~1~, значит, приложение уязвимо и можно переходить к более сложным запросам.

Распространённые вариации

Вместо EXTRACTVALUE часто используют UPDATEXML — ещё одну функцию для работы с XML, которая также генерирует ошибку при некорректном XPath. Синтаксис аналогичен:

AND UPDATEXML(1, CONCAT(0x7e, (SELECT ...), 0x7e), 1)-- -

Также встречаются инъекции через GTID_SUBSET, EXP (для MySQL 5.7+), geometrycollection и другие функции, вызывающие ошибки с полезной нагрузкой.

Как защититься от таких атак?

Главное правило — никогда не подставлять пользовательский ввод в SQL-запросы напрямую. Используйте параметризованные запросы (prepared statements) — это надёжно отделяет код от данных.

  • Параметризация: передавайте значения через плейсхолдеры (? или :name).
  • Экранирование: если параметризация невозможна, применяйте функции экранирования, специфичные для вашей СУБД (например, mysqli_real_escape_string в PHP).
  • Ограничение прав: пользователь базы данных, от имени которого работает приложение, должен иметь минимально необходимые привилегии.
  • Отключение вывода ошибок: не показывайте детальные сообщения СУБД конечным пользователям — это лишает атакующего обратной связи.
  • WAF: веб-приложения-экраны могут блокировать подозрительные конструкции, но не заменяют исправление уязвимости.

Что делать, если вы нашли такую строку в логах?

Если вы администратор и видите подобные запросы в логах, это может означать, что ваш сайт сканируют на уязвимости. Проверьте код на наличие небезопасных SQL-запросов, обновите CMS и плагины. Если инъекция уже произошла, срочно смените пароли к базе данных и проверьте, не были ли скомпрометированы данные.

Итог

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

Источники