Что это за строка и откуда она берётся?

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

Подобные инъекции эксплуатируют функции MySQL, вызывающие ошибки с текстом, содержащим результат подзапроса. В данном случае используется функция EXTRACTVALUE(), которая извлекает значение из XML-фрагмента. Если передать ей некорректный XML, она выдаст ошибку, в тексте которой может оказаться переданная строка. Это позволяет атакующему «вытащить» данные через сообщения об ошибках — метод, известный как error-based SQL injection.

Разбор по частям: что делает каждый элемент

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

  • %" — это начало строки. Символ % часто используется в LIKE-запросах как шаблон, а " (двойная кавычка) закрывает строковый литерал в SQL. Злоумышленник предполагает, что исходный запрос выглядит примерно так: SELECT * FROM table WHERE field LIKE '%"..."%'. Внедряя %", он пытается «закрыть» текущую строку и выйти за её пределы.
  • AND EXTRACTVALUE(7698, CONCAT(...)) — добавление условия AND с вызовом функции EXTRACTVALUE. Первый аргумент — число 7698, которое будет использовано как XML-документ (очевидно, некорректный). Второй аргумент — результат CONCAT, который содержит подзапрос.
  • CONCAT(0x7e, ((SELECT (ELT(7698=7698,1)))), 0x7e) — функция CONCAT склеивает три части: шестнадцатеричный код 0x7e (символ тильды ~), результат подзапроса и снова тильду. Тильды служат маркерами, чтобы в сообщении об ошибке было легко найти полезную нагрузку.
  • SELECT (ELT(7698=7698,1)) — подзапрос, возвращающий результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь N — это выражение 7698=7698, которое всегда истинно (равно 1). Таким образом, ELT(1, 1) вернёт строку '1'. Это простейший пример; в реальной атаке вместо '1' мог бы быть подзапрос, извлекающий имя пользователя или хеш пароля.
  • -- - — это комментарий в SQL. Два дефиса с пробелом (или без) означают, что весь оставшийся код запроса будет проигнорирован. Это позволяет отрезать лишние кавычки и скобки, которые могут помешать выполнению инъекции.

В результате, если приложение уязвимо, база данных выполнит этот код, и EXTRACTVALUE вызовет ошибку вида: XPATH syntax error: '~1~'. В тексте ошибки появится значение, возвращённое подзапросом. Атакующий, читая ответ сервера, может извлекать данные посимвольно или целыми строками.

Почему именно EXTRACTVALUE?

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

Аналогичными функциями являются UPDATEXML() и GTID_SUBSET(). Все они относятся к классу error-based SQL-инъекций.

Как распознать такую атаку в логах?

Если вы администратор или разработчик, обратите внимание на следующие признаки в логах веб-сервера:

  • Наличие в параметрах запросов функций EXTRACTVALUE, UPDATEXML, CONCAT с шестнадцатеричными строками.
  • Использование комментариев --, # или /* */ в конце параметров.
  • Частые запросы с символами %, ', ", ) в необычных сочетаниях.
  • Ошибки СУБД в ответах сервера (например, «XPATH syntax error»).

При обнаружении подобных строк следует немедленно проверить код приложения на наличие уязвимостей и, при необходимости, заблокировать подозрительные IP-адреса.

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

Основной метод защиты — использование параметризованных запросов (prepared statements). Это позволяет отделить код SQL от данных, и любые введённые пользователем символы перестают восприниматься как часть запроса. Даже если злоумышленник введёт EXTRACTVALUE, база данных обработает это как обычную строку.

Дополнительные меры:

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

Помните, что безопасность — это процесс, а не разовое действие. Проводите аудит кода и тестирование на проникновение.

Заключение

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

Источники