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

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

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

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

Начнём с того, что строка встраивается в существующий SQL-запрос, который формируется на сервере. Предположим, исходный запрос выглядел так:

SELECT * FROM users WHERE id = ('$input');

Злоумышленник подставляет свою строку вместо $input, и запрос превращается в нечто вроде:

SELECT * FROM users WHERE id = ('')) AND EXTRACTVALUE(5092,CONCAT(0x7e,((SELECT (ELT(5092=5092,1)))),0x7e))-- -');

Разберём компоненты:

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

Как работает EXTRACTVALUE для атаки

Функция EXTRACTVALUE(XML_fragment, XPath_expression) извлекает текст из XML-документа. Если XPath-выражение некорректно, MySQL генерирует ошибку вида:

XPATH syntax error: '~1~'

Именно эту ошибку и использует атакующий. Он конструирует XPath так, чтобы в текст ошибки попадали данные из базы. В нашем случае подзапрос возвращает 1, и в ошибке появится ~1~. Если бы вместо 1 стояла, например, версия СУБД или имя пользователя, они бы тоже отобразились.

Классический пример из эксплуатации:

AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))

Это выведет версию MySQL в сообщении об ошибке. Аналогично можно извлечь имя базы, таблицы, столбцы и даже хеши паролей.

Почему используется именно 5092?

Число 5092 в данном примере — произвольное. Оно не несёт смысловой нагрузки и нужно лишь для того, чтобы функция EXTRACTVALUE получила первый аргумент. В других вариантах инъекций встречаются числа 8635, 3720 и любые другие. Главное — чтобы первый аргумент был корректным XML-фрагментом (или числом, которое MySQL преобразует в строку).

Аналогично 5092=5092 — это тавтология, всегда истинная. Она нужна, чтобы ELT вернул элемент с индексом 1. Если бы условие было ложным, ELT вернул бы NULL, и ошибка выглядела бы иначе. Такая конструкция часто используется для «слепой» проверки: если инъекция работает, ошибка будет одного типа, если нет — другого.

Разновидности error-based инъекций

Помимо EXTRACTVALUE, в MySQL существуют и другие функции, провоцирующие ошибки с выводом данных:

  • UPDATEXML — аналогична EXTRACTVALUE, но работает с XML-документами.
  • GTID_SUBSET — в некоторых версиях MySQL вызывает ошибку с полезной нагрузкой.
  • GeometryCollection — при некорректных аргументах возвращает данные в тексте ошибки.
  • EXP — математическая функция, вызывающая ошибку переполнения с числом.

Все они эксплуатируют одну и ту же идею: заставить СУБД выдать конфиденциальную информацию в сообщении об ошибке, которое затем отображается на странице (если включён вывод ошибок).

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

Основная причина успеха подобных инъекций — динамическое конструирование SQL-запросов с прямым включением пользовательского ввода. Вот ключевые меры защиты:

  1. Параметризованные запросы (prepared statements). Используйте их везде, где возможно. Это самый надёжный способ.
  2. Хранимые процедуры. Если они правильно написаны, риск инъекций снижается.
  3. Экранирование специальных символов. Применяйте функции экранирования, предоставляемые драйвером БД (например, mysqli_real_escape_string в PHP).
  4. Валидация входных данных. Проверяйте типы, длины, форматы. Не доверяйте пользовательскому вводу.
  5. Отключение вывода ошибок на продакшене. Сообщения об ошибках не должны попадать в браузер.
  6. Регулярные обновления СУБД. В новых версиях MySQL некоторые функции могут быть удалены или изменены, что усложняет эксплуатацию.

Также рекомендуется использовать WAF (Web Application Firewall), который может блокировать известные сигнатуры SQL-инъекций, включая EXTRACTVALUE.

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

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

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

Не игнорируйте такие события — даже если атака не удалась, злоумышленник может вернуться с более изощрённым методом.

Заключение

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

Помните: безопасность — это процесс, а не разовое действие. Используйте параметризованные запросы, валидируйте данные и следите за обновлениями.

Источники