Что это за строка с EXTRACTVALUE?
Строка вида %" AND EXTRACTVALUE(2649,CONCAT(0x7e,((SELECT (ELT(2649=2649,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах об уязвимостях и в инструментах для пентеста (например, sqlmap).
Внешне это может показаться бессмысленным набором символов, но за ним стоит чёткая логика: заставить сервер базы данных вернуть в сообщении об ошибке результат выполнения вложенного запроса. Именно поэтому такой тип инъекции называется error-based (основанный на ошибках).
Как работает эта инъекция?
Разберём по частям. Предположим, что исходный SQL-запрос, который выполняет уязвимое веб-приложение, выглядит примерно так:
SELECT * FROM users WHERE id = 'ВВОД'
Злоумышленник подставляет вместо ВВОД строку %" AND EXTRACTVALUE(...)-- -. В итоге запрос принимает вид:
SELECT * FROM users WHERE id = '%" AND EXTRACTVALUE(2649,CONCAT(0x7e,((SELECT (ELT(2649=2649,1)))),0x7e))-- -'
Символ %" в начале нужен для экранирования кавычки и комментария, а -- - в конце — чтобы закомментировать остаток оригинального запроса. Основная нагрузка ложится на функцию EXTRACTVALUE.
Функция EXTRACTVALUE
В MySQL (до версии 8.0.17) существовала функция EXTRACTVALUE(XML, XPath). Она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно или возвращает не скалярное значение, функция генерирует ошибку. Именно эту особенность используют для error-based инъекций: в тексте ошибки MySQL выводит часть переданного XPath, что позволяет извлечь данные.
В нашем примере первым аргументом идёт число 2649 — это не настоящий XML, а просто заполнитель. Второй аргумент — результат CONCAT(0x7e, ((SELECT (ELT(2649=2649,1)))), 0x7e). 0x7e — это шестнадцатеричное представление символа тильды (~), который используется как маркер начала и конца выводимых данных, чтобы их было легко найти в сообщении об ошибке.
Конструкция ELT и условие 2649=2649
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(2649=2649, 1) — первое условие 2649=2649 всегда истинно (возвращает 1), поэтому функция вернёт строку с индексом 1, то есть 1. Если бы условие было ложным, вернулось бы 0, и ELT вернул бы NULL. Это стандартный приём для проверки условий в слепых инъекциях, но здесь он используется для демонстрации.
В реальной атаке вместо ELT(2649=2649,1) могла бы стоять подзапрос, извлекающий, например, имя пользователя или хеш пароля. Например: (SELECT password FROM users LIMIT 1). Тогда в ошибке MySQL отобразилось бы значение пароля, обрамлённое тильдами.
Зачем нужен CONCAT и тильды?
Функция CONCAT объединяет строки. Тильды (0x7e) добавляются, чтобы отделить полезную нагрузку от служебного текста ошибки. Когда MySQL выдаёт ошибку вида XPATH syntax error: '~1~', злоумышленник легко извлекает содержимое между тильдами. Без них было бы сложно понять, где начинаются и заканчиваются данные.
Почему это опасно?
Error-based SQL-инъекции позволяют злоумышленнику получать произвольные данные из базы: логины, пароли, номера кредитных карт, персональные данные пользователей. В отличие от слепых инъекций, здесь не нужно перебирать символы — информация возвращается сразу в сообщении об ошибке. Это делает атаку быстрой и эффективной.
Уязвимыми оказываются приложения, которые:
- подставляют пользовательский ввод в SQL-запросы без параметризации;
- выводят сообщения об ошибках базы данных прямо на страницу;
- используют устаревшие версии MySQL, где
EXTRACTVALUEещё доступна.
Как защититься?
Главная мера — использовать параметризованные запросы (prepared statements), при которых пользовательский ввод никогда не интерпретируется как SQL-код. Дополнительно рекомендуется:
- Отключить вывод ошибок СУБД в production-окружении.
- Обновить MySQL до версии 8.0.17 или выше, где
EXTRACTVALUEудалена (заменена наJSON_EXTRACTи другие функции). - Использовать ORM или query builder, которые экранируют входные данные.
- Проводить регулярные сканирования уязвимостей и пентесты.
Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based инъекциях. Аналогично применяются UPDATEXML, GTID_SUBSET, EXP и другие. Однако EXTRACTVALUE долгое время была одной из самых популярных из-за простоты и надёжности.
Заключение
Строка с EXTRACTVALUE и CONCAT — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для эксплуатации уязвимости SQL-инъекции. Она демонстрирует, как с помощью ошибок базы данных можно извлекать конфиденциальную информацию. Понимание таких примеров помогает разработчикам и специалистам по безопасности лучше защищать веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий