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

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

В данном случае применяется функция EXTRACTVALUE() — она предназначена для работы с XML и при некорректном XPath-выражении генерирует ошибку, в которую попадает переданная строка. Это позволяет обойти ограничения на вывод данных и получить информацию, к которой обычный пользователь доступа не имеет.

Разбор компонентов запроса

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

  • )))) — закрывающие скобки. Они нужны, чтобы «закрыть» ранее открытые скобки в оригинальном SQL-запросе и сделать внедряемый код синтаксически корректным. Количество скобок подбирается экспериментально.
  • AND — логический оператор, присоединяющий наше условие к исходному запросу. Если исходный запрос возвращал true, то добавление AND с заведомо истинным условием не изменит результат, но выполнит внедрённую функцию.
  • EXTRACTVALUE(3326, CONCAT(...)) — функция MySQL для извлечения значения из XML по XPath. Первый аргумент (3326) — произвольное число, которое не является корректным XML-документом, что гарантирует ошибку. Второй аргумент — конкатенация строк, где и прячется полезная нагрузка.
  • CONCAT(0x7e, ((SELECT (ELT(3326=3326,1)))), 0x7e) — объединяет символ тильды (~, код 0x7e) с результатом подзапроса. ELT(3326=3326,1) возвращает 1, если условие истинно. В реальной атаке вместо 1 подставляется имя базы, таблицы или поле с данными.
  • -- - — комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы не возникло синтаксической ошибки.

В результате MySQL пытается разобрать строку ~1~ как XPath-выражение, терпит неудачу и возвращает ошибку вида: XPATH syntax error: '~1~'. Злоумышленник видит эту ошибку и понимает, что инъекция работает, а также может подставлять вместо 1 другие SQL-выражения для извлечения данных.

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

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

  1. Определение версии СУБД — с помощью @@version или version().
  2. Получение имён таблиц и колонок — через запросы к information_schema.
  3. Извлечение логинов, паролей, персональных данных — например, SELECT password FROM users LIMIT 1.
  4. Обход аутентификации — иногда достаточно подставить условие, которое всегда истинно.

Важно понимать: сам по себе запрос с EXTRACTVALUE не наносит вреда, если сервер не уязвим. Он лишь проверяет наличие уязвимости. Но если приложение не фильтрует входные данные, последствия могут быть катастрофическими — вплоть до полного чтения базы и модификации данных.

Почему EXTRACTVALUE, а не другие функции?

В MySQL есть несколько функций, вызывающих ошибки с контролируемым содержимым: EXTRACTVALUE(), UPDATEXML(), GTID_SUBSET() и другие. EXTRACTVALUE долгое время была самой популярной, потому что:

  • она доступна во всех версиях MySQL 5.x;
  • сообщение об ошибке содержит переданную строку целиком (до определённой длины);
  • её легко комбинировать с CONCAT для вывода произвольных данных.

Однако начиная с MySQL 5.7 и особенно в 8.0 использование EXTRACTVALUE может быть ограничено, а в некоторых сборках функция удалена. Поэтому современные атаки всё чаще используют UPDATEXML или другие техники.

Как защититься от таких инъекций?

Главное правило: никогда не доверяйте пользовательскому вводу. Вот конкретные меры:

  1. Параметризованные запросы (prepared statements) — самый надёжный способ. Данные передаются отдельно от SQL-кода, и внедрение становится невозможным.
  2. Экранирование специальных символов — если по каким-то причинам нельзя использовать параметризацию, применяйте функции экранирования (например, mysqli_real_escape_string в PHP).
  3. Валидация входных данных — проверяйте, что параметр имеет ожидаемый тип (число, email, дата).
  4. Ограничение прав пользователя БД — учётная запись приложения не должна иметь прав на чтение information_schema или системных таблиц.
  5. Отключение вывода ошибок — не показывайте пользователям детали ошибок СУБД. Логируйте их, но не выводите в браузер.
  6. WAF (Web Application Firewall) — может блокировать известные шаблоны атак, но не является панацеей.
  7. Регулярные обновления — используйте актуальные версии СУБД и фреймворков, где многие уязвимости закрыты.
Помните: безопасность — это процесс, а не разовое действие. Даже одна непроверенная точка ввода может скомпрометировать всю систему.

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

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

  • проверьте, не была ли выполнена инъекция успешно (ищите необычные ошибки в логах СУБД);
  • проанализируйте код приложения на наличие уязвимых мест;
  • срочно обновите ПО и примените патчи;
  • рассмотрите возможность аудита безопасности.

Не игнорируйте такие сигналы — злоумышленники часто проводят разведку перед основной атакой.

Заключение

Строка с EXTRACTVALUE и CONCAT — это не случайный набор символов, а тщательно сконструированный инструмент для проверки и эксплуатации SQL-уязвимостей. Понимание принципов его работы помогает разработчикам писать более безопасный код, а администраторам — вовремя распознавать угрозы. Помните, что лучшая защита — это параметризованные запросы и внимательное отношение к безопасности на всех этапах разработки.

Источники