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

Запрос пользователя: "))) AND EXTRACTVALUE(9232,CONCAT(0x7e,((SELECT (ELT(9232=9232,1)))),0x7e))-- - — это фрагмент полезной нагрузки (payload) для SQL-инъекции, а именно для атаки типа error-based (инъекция, основанная на ошибках). Такая строка встречается в логах веб-серверов, в полях ввода форм или в параметрах URL, когда злоумышленник пытается проверить уязвимость приложения или извлечь данные из базы данных MySQL.

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

В данной статье мы разберём, как именно работает эта инъекция, какие функции задействованы и как от неё защититься.

Разбор payload по частям

Рассмотрим строку по частям:

  • "))) — последовательность кавычек и скобок. Она нужна, чтобы «закрыть» предыдущие конструкции в исходном SQL-запросе и выйти за его пределы. Точный набор символов зависит от контекста: иногда это одна кавычка, иногда комбинация с закрывающими скобками.
  • AND — логический оператор, добавляющий условие к запросу. В error-based инъекции часто используется для внедрения функции, которая вызовет ошибку.
  • EXTRACTVALUE(9232, CONCAT(...)) — ключевая функция MySQL. EXTRACTVALUE(XML_document, XPath_expression) извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в текст которой попадает часть переданного выражения. Это и позволяет злоумышленнику «прочитать» результат подзапроса.
  • 9232 — произвольное число (или строка), которое передаётся в качестве первого аргумента. Оно может быть любым; часто используют случайное число, чтобы избежать кэширования.
  • CONCAT(0x7e, ((SELECT (ELT(9232=9232,1)))), 0x7e) — конкатенация. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке. Внутри — подзапрос SELECT (ELT(9232=9232,1)).
  • ELT(N, str1, str2, ...) — функция MySQL, возвращающая N-ю строку из списка. Если N=1, возвращается первая строка. В данном случае ELT(9232=9232,1) — условие 9232=9232 всегда истинно (1), поэтому возвращается 1. Это простейшая проверка работоспособности инъекции: если ошибка появится, значит, функция выполнилась.
  • -- - — комментарий в MySQL (пробел после двух дефисов обязателен). Он «отрезает» оставшуюся часть исходного запроса, чтобы синтаксис стал корректным.

В реальной атаке вместо ELT(9232=9232,1) подставляется подзапрос, возвращающий нужные данные, например: (SELECT password FROM users LIMIT 1). Тогда CONCAT объединяет тильду, результат подзапроса и ещё одну тильду, а EXTRACTVALUE пытается разобрать эту строку как XPath и выдаёт ошибку вида: XPATH syntax error: '~admin123~'. Так злоумышленник получает значение из базы.

Почему это работает?

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

Таким образом, error-based инъекция — это метод слепого извлечения данных, при котором вместо прямого вывода результата используется канал ошибок.

Примеры похожих payload

В результатах поиска упоминается также ' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users # — это пример UNION-based инъекции. Ошибка «The used SELECT statements have a different number of columns» возникает, когда количество столбцов в UNION SELECT не совпадает с исходным запросом. Это ещё один распространённый тип атак.

Наш же запрос с EXTRACTVALUE относится именно к error-based, и его главная цель — заставить базу вернуть данные в сообщении об ошибке.

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

Основные меры защиты:

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

Важно понимать, что сам по себе запрос с EXTRACTVALUE не является вирусом или вредоносным кодом — это лишь инструмент, который может быть использован злоумышленником при наличии уязвимости. Если вы встретили такую строку в логах, это повод проверить своё приложение на SQL-инъекции.

Заключение

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

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

Источники