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

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

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

Разбор полезной нагрузки

Начнём с начала:

  • %') — это фрагмент, который «закрывает» исходный SQL-запрос. Символ % часто используется в LIKE-запросах, а ') закрывает строковый литерал и скобку. Злоумышленник подставляет его, чтобы разорвать легитимный запрос и добавить свой код.
  • AND — логический оператор, который позволяет присоединить дополнительное условие. Если исходный запрос был истинным, то после AND можно внедрить вызов функции.
  • EXTRACTVALUE(1932, CONCAT(0x7e, ((SELECT (ELT(1932=1932,1)))), 0x7e)) — это ядро атаки. Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа по XPath-выражению. Однако при передаче некорректного XPath она генерирует ошибку, в тексте которой отображается переданное значение.

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

Что делает ELT(1932=1932,1)?

ELT(N, str1, str2, ...) — функция MySQL, возвращающая N-ю строку из списка. Если N=1, возвращается первая строка. В данном случае 1932=1932 — это всегда истинное выражение, которое в MySQL приводится к числу 1. Таким образом, ELT(1,1) возвращает строку '1'.

Подзапрос (SELECT (ELT(1932=1932,1))) просто возвращает 1. Это простейший пример, демонстрирующий работоспособность инъекции. В реальной атаке вместо 1 могло бы быть имя пользователя, хэш пароля или другая конфиденциальная информация, полученная из базы.

Зачем нужен CONCAT с тильдами?

Функция EXTRACTVALUE() при некорректном XPath выдаёт ошибку вида: XPATH syntax error: '~1~'. Тильды добавляются, чтобы злоумышленник мог легко найти границы выведенных данных в тексте ошибки. Это стандартный приём при error-based инъекциях.

Завершение -- -

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

Как работает error-based SQL-инъекция через ExtractValue

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

Аналогично работает функция UPDATEXML(). Обе они относятся к так называемым XPath-инъекциям.

Важно: начиная с MySQL 5.7.9 и MariaDB 10.2.7 функции EXTRACTVALUE и UPDATEXML были удалены из ядра, но во многих устаревших системах они всё ещё доступны.

Пример уязвимого запроса

Предположим, веб-приложение выполняет следующий SQL-запрос:

SELECT * FROM users WHERE name LIKE '%' + user_input + '%';

Если пользователь введёт %') AND EXTRACTVALUE(1932,CONCAT(0x7e,((SELECT (ELT(1932=1932,1)))),0x7e))-- -, то итоговый запрос станет таким:

SELECT * FROM users WHERE name LIKE '%%') AND EXTRACTVALUE(1932,CONCAT(0x7e,((SELECT (ELT(1932=1932,1)))),0x7e))-- -%';

База данных попытается выполнить EXTRACTVALUE с некорректным XPath и вернёт ошибку, содержащую ~1~. Если приложение выводит эту ошибку на экран, злоумышленник увидит результат.

Последствия и защита

Успешная эксплуатация такой инъекции позволяет читать произвольные данные из базы: имена пользователей, пароли, номера кредитных карт и т.д. В некоторых случаях возможна запись файлов и выполнение команд ОС.

Чтобы защититься, необходимо:

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

Также рекомендуется проводить регулярные аудиты безопасности и пентесты.

Заключение

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

Источники