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

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

Если объяснить просто: хакер вставляет в уязвимое поле ввода (например, в URL-параметр или форму поиска) специально составленную строку. Если сайт не фильтрует входные данные, эта строка попадает прямо в SQL-запрос к базе данных. Встроенные функции MySQL вызывают ошибку, в тексте которой «просвечивают» нужные злоумышленнику данные.

Как устроена эта инъекция по частям

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

  • %" — начало полезной нагрузки. Символ % часто используется в URL-кодировании, а кавычка " пытается «закрыть» строковый литерал в исходном SQL-запросе, чтобы внедрить собственный код.
  • AND — логический оператор. Он присоединяет вредоносное условие к оригинальному запросу, чтобы тот остался синтаксически корректным.
  • EXTRACTVALUE(6287,CONCAT(...)) — ключевая функция. Она извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL выбрасывает ошибку с текстом этого выражения. Именно это и нужно атакующему.
  • CONCAT(0x7e, ..., 0x7e) — склейка строк. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильды служат маркерами-разделителями, чтобы в сообщении об ошибке было легко найти полезные данные.
  • SELECT (ELT(6287=6287,1)) — подзапрос, который возвращает результат. ELT() возвращает N-й элемент из списка. Здесь условие 6287=6287 всегда истинно, поэтому возвращается 1. В реальной атаке на этом месте подставляется подзапрос к системным таблицам (например, SELECT database() или SELECT version()).
  • -- - — комментарий. Всё, что идёт после него, MySQL игнорирует. Это нужно, чтобы «отрезать» остаток оригинального запроса и не сломать его синтаксис.

Зачем нужна функция EXTRACTVALUE?

EXTRACTVALUE() принимает два строковых аргумента: фрагмент XML-разметки и XPath-выражение (локатор). Функция возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента, соответствующего XPath.

Особенность в том, что если XPath-выражение содержит синтаксическую ошибку, MySQL генерирует сообщение об ошибке вида «XPATH syntax error: '...'». В этом сообщении отображается переданное выражение. Атакующий подставляет в XPath результат подзапроса — и получает его прямо в тексте ошибки.

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

Почему используется ELT и CONCAT?

ELT(N, str1, str2, ...) возвращает строку под номером N. В примере ELT(6287=6287,1) условие всегда истинно, поэтому возвращается 1. Это демонстрационный «заглушечный» вариант — он показывает саму механику, не выполняя реального извлечения данных.

CONCAT() склеивает тильды и результат подзапроса в одну строку. Тильды нужны, чтобы в сообщении об ошибке легко отделить полезную нагрузку от служебного текста. Такой приём — стандартная практика в error-based эксплуатации MySQL.

Как это выглядит в реальной атаке

Вместо безобидного 1 злоумышленник подставляет, например, SELECT database(), SELECT user() или SELECT table_name FROM information_schema.tables. Тогда в ошибке отразится имя текущей базы, пользователь СУБД или список таблиц.

Пошагово типичный сценарий выглядит так:

  1. Поиск уязвимого параметра (например, ?id=1).
  2. Проверка на инъекцию с помощью простых условий (AND 1=1, AND 1=2).
  3. Внедрение error-based конструкции с EXTRACTVALUE или UPDATEXML.
  4. Чтение данных из текста ошибки.
  5. Извлечение имён таблиц и колонок через information_schema.
  6. Получение логинов, паролей и другой конфиденциальной информации.

Чем опасны такие инъекции

Error-based SQL-инъекции позволяют злоумышленнику:

  • получить доступ к содержимому базы данных;
  • узнать структуру таблиц и колонок;
  • извлечь учётные данные пользователей;
  • в некоторых случаях — выполнить команды на сервере или изменить данные.

Особенно опасно, когда сайт работает под учётной записью с широкими правами. Тогда одна уязвимость может привести к полной компрометации базы.

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

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

  • Параметризованные запросы (prepared statements) — самый надёжный способ. Данные передаются отдельно от SQL-кода и не могут изменить его структуру.
  • Валидация и фильтрация ввода — проверяйте типы данных, отбрасывайте подозрительные символы.
  • Экранирование спецсимволов — если параметризация невозможна, используйте функции экранирования, предоставляемые драйвером БД.
  • Минимальные права для учётной записи БД — веб-приложение не должно иметь прав администратора СУБД.
  • Отключение подробных сообщений об ошибках — не показывайте пользователям текст ошибок MySQL. Это лишает error-based атаку «канала вывода».
  • WAF и мониторинг — веб-приложения-фаерволы могут распознавать характерные сигнатуры вроде EXTRACTVALUE и UPDATEXML.

Итог

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

Источники