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

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

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

Анатомия payload'а

Начало: %')

Символы %' и закрывающая скобка ) используются для «выхода» из контекста оригинального SQL-запроса. Предполагается, что уязвимый запрос выглядит примерно так: SELECT * FROM users WHERE name = '%s'. Подставляя %'), атакующий закрывает строковый литерал и скобку, чтобы добавить собственные условия.

Оператор AND

Логический оператор AND позволяет присоединить к оригинальному условию дополнительное выражение. Если оригинальное условие истинно (например, при поиске по существующему имени), то результат всего запроса будет зависеть от правой части — внедрённой функции.

Функция EXTRACTVALUE

EXTRACTVALUE(XML_frag, XPath_expr) — это встроенная функция MySQL, которая извлекает значение из XML-фрагмента по заданному XPath-выражению. Если XPath-выражение некорректно, функция генерирует ошибку, в тексте которой содержится переданный XPath. Именно это свойство и используется для извлечения данных: злоумышленник может подставить в XPath результат подзапроса, и СУБД вернёт его в сообщении об ошибке.

Аргументы 9022 и CONCAT(0x7e, ..., 0x7e)

Первый аргумент 9022 — это произвольный числовой идентификатор (может быть любым). Второй аргумент — выражение CONCAT(0x7e, ((SELECT (ELT(9022=9022,1)))), 0x7e). 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить поиск извлечённых данных в тексте ошибки.

Подзапрос (SELECT (ELT(9022=9022,1)))

Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(9022=9022,1) — условие 9022=9022 всегда истинно (возвращает 1), поэтому ELT вернёт строку '1'. Это простейший пример: в реальной атаке вместо '1' мог бы быть результат подзапроса, например, имя пользователя или хеш пароля. Но цель данного payload'а — просто проверить, что инъекция работает: если приложение вернёт ошибку с текстом, содержащим '1', значит уязвимость подтверждена.

Комментарий -- -

Два дефиса и пробел (в некоторых вариантах с дополнительным дефисом) обозначают начало комментария в MySQL. Всё, что идёт после, игнорируется парсером. Это нужно, чтобы «отрезать» оставшуюся часть оригинального запроса (например, закрывающую кавычку), которая могла бы вызвать синтаксическую ошибку.

Как это работает вместе

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

Если бы вместо '1' был, например, подзапрос (SELECT password FROM users LIMIT 1), то в ошибке отобразился бы пароль. Таким образом, error-based инъекция позволяет посимвольно извлекать любые данные из базы.

Зачем нужен именно такой payload?

Этот конкретный пример часто используется в сканерах уязвимостей (например, sqlmap) как тестовый. Он прост, не требует特殊ных условий и гарантированно вызывает ошибку, если инъекция возможна. Наличие ошибки с тильдами и числом '1' — явный признак уязвимости.

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

Основная мера — использование параметризованных запросов (prepared statements) с привязкой переменных. Никогда не подставляйте пользовательский ввод напрямую в SQL-код. Дополнительно:

  • Экранируйте специальные символы с помощью функций типа mysqli_real_escape_string (но это менее надёжно, чем параметризация).
  • Ограничивайте права пользователя базы данных: приложение должно работать под учётной записью с минимальными привилегиями.
  • Используйте ORM или query builder, которые автоматически экранируют значения.
  • Регулярно проводите аудит кода и сканирование уязвимостей.
  • Отключайте вывод подробных ошибок СУБД в production-окружении, чтобы не давать атакующему информацию.

Важно понимать, что error-based инъекции — лишь один из многих типов атак. Защита должна быть комплексной.

Заключение

Рассмотренная строка — это не случайный мусор, а тщательно сконструированный инструмент для проверки и эксплуатации уязвимости SQL-инъекции в MySQL. Понимание её работы помогает разработчикам осознать важность безопасного кодирования, а специалистам по безопасности — распознавать подобные атаки в логах.

Источники