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

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

Контекст внедрения

Начало строки %')))) — это попытка «закрыть» исходный SQL-запрос и внедрить свой код. Символы % и ' используются для обхода простых фильтров и закрытия строковых литералов, а несколько закрывающих скобок )))) — чтобы сбалансировать скобки в оригинальном запросе. Далее идёт ключевое слово AND, за которым следует внедряемая полезная нагрузка. Завершающая последовательность -- - — это комментарий, который «отрезает» остаток оригинального запроса, чтобы синтаксис остался корректным.

Функция EXTRACTVALUE

EXTRACTVALUE — встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Она возвращает текст узла, соответствующего XPath. Однако при некорректном XPath или при наличии в результате недопустимых символов MySQL генерирует ошибку, в тексте которой может оказаться часть переданных данных. Именно это свойство и эксплуатируется в error-based инъекциях: злоумышленник подставляет в XPath выражение, содержащее подзапрос, и если подзапрос возвращает строку с недопустимыми для XPath символами (например, двоеточие или кавычки), сервер выдаёт ошибку с этой строкой.

Функция ELT

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае используется ELT(6502=6502,1). Выражение 6502=6502 всегда истинно и в числовом контексте даёт 1. Таким образом, ELT(1,1) возвращает '1'. Это простейшая проверка работоспособности инъекции: если сервер вернёт ошибку с символом 1, значит, внедрение успешно. В реальных атаках вместо 1 подставляют подзапрос, например (SELECT password FROM users LIMIT 1), чтобы извлечь конфиденциальные данные.

Функция CONCAT и 0x7e

CONCAT объединяет строки. Здесь она склеивает символ 0x7e (тильда ~), результат подзапроса и ещё одну тильду. Тильда используется как маркер: она недопустима в XPath, поэтому EXTRACTVALUE гарантированно выдаст ошибку, в тексте которой будет содержаться искомая строка, окружённая тильдами. Это облегчает автоматическое извлечение данных из сообщения об ошибке.

Как работает запрос целиком

Собирая всё вместе, получаем: EXTRACTVALUE(6502, CONCAT(0x7e, (SELECT (ELT(6502=6502,1))), 0x7e)). Внутренний подзапрос возвращает строку '1'. CONCAT формирует строку '~1~'. Затем EXTRACTVALUE пытается интерпретировать 6502 как XML (что само по себе некорректно, но MySQL может выдать ошибку раньше) и применить XPath '~1~'. Поскольку тильда не является допустимым началом XPath, генерируется ошибка вида XPATH syntax error: '~1~'. Злоумышленник, видя такую ошибку, понимает, что инъекция работает, и может заменить ELT(...) на подзапрос для извлечения любых данных.

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

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

Меры защиты

Чтобы предотвратить такие атаки, необходимо:

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

Заключение

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

Источники