Что такое EXTRACTVALUE в MySQL?
Функция EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения текстового содержимого из XML-фрагмента с помощью выражения XPath. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Она возвращает текст первого узла, соответствующего XPath. Например, SELECT EXTRACTVALUE('<a><b>текст</b></a>', '/a/b') вернёт «текст». Эта функция часто используется для работы с XML-данными, хранящимися в колонках таблиц.
Однако, как и многие другие функции, EXTRACTVALUE может быть использована злоумышленниками для проведения SQL-инъекций, основанных на ошибках (error-based SQL injection). Суть метода: если XPath-выражение содержит синтаксическую ошибку, MySQL возвращает сообщение об ошибке, в котором может отображаться результат подзапроса. Это позволяет атакующему извлекать произвольные данные из базы.
Разбор полезной нагрузки: " OR EXTRACTVALUE(5018,CONCAT(0x7e,((SELECT (ELT(5018=5018,1)))),0x7e))-- -
Данная строка — типичный пример error-based SQL-инъекции. Рассмотрим её по частям:
"— закрывающая кавычка для завершения строкового литерала в уязвимом запросе.OR— логический оператор, который делает условие всегда истинным, если подзапрос вернёт результат.EXTRACTVALUE(5018, CONCAT(...))— вызов функции с заведомо некорректным XPath, чтобы вызвать ошибку.CONCAT(0x7e, ((SELECT (ELT(5018=5018,1)))), 0x7e)— конкатенация тильды (0x7e— шестнадцатеричный код символа~), результата подзапроса и снова тильды.ELT(5018=5018,1)— функция ELT возвращает N-й элемент из списка. Здесь5018=5018— истина (1), поэтому ELT(1, 1) вернёт «1». Это простейшая проверка, которая всегда возвращает 1.-- -— комментарий, отсекающий остальную часть оригинального SQL-запроса.
В результате MySQL попытается вычислить XPath-выражение, которое начинается с символа ~ (тильда). XPath не допускает такого начала, поэтому возникнет ошибка вида: XPATH syntax error: '~1~'. В сообщении об ошибке отобразится результат подзапроса — в данном случае «1». В реальной атаке вместо ELT(5018=5018,1) подставляются вызовы, извлекающие имена таблиц, колонок или хеши паролей.
Зачем нужен CONCAT и тильды?
Тильды (0x7e) используются как маркеры, чтобы облегчить парсинг вывода ошибки. Сообщение об ошибке MySQL обычно имеет формат: XPATH syntax error: '...'. Вставив тильды по краям, атакующий легко выделяет полезную нагрузку между ними. CONCAT объединяет маркеры и результат подзапроса в одну строку, которая затем передаётся в EXTRACTVALUE как XPath. Поскольку XPath начинается с тильды, парсер MySQL сразу выдаёт ошибку, но перед этим вычисляет все аргументы, включая подзапрос.
Почему это работает?
MySQL при обнаружении ошибки в XPath возвращает подробное сообщение, содержащее фрагмент переданного выражения. Это особенность реализации функции EXTRACTVALUE (и аналогичной UPDATEXML). Если приложение выводит сообщения об ошибках СУБД на страницу, злоумышленник может читать эти сообщения и извлекать данные. Если вывод ошибок отключён, атака не сработает, но может быть использована слепая SQL-инъекция.
Важно: начиная с MySQL 5.7.8 функция EXTRACTVALUE помечена как устаревшая (deprecated), а в MySQL 8.0 удалена. Однако многие устаревшие системы всё ещё используют её, что делает эту технику актуальной для пентеста.
Как защититься от таких инъекций?
Основные меры защиты:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают в тело SQL-запроса.
- Экранирование специальных символов при невозможности использовать параметризацию. Но этот метод менее надёжен.
- Отключение вывода подробных ошибок СУБД на продакшене. Сообщения об ошибках должны логироваться, а пользователю показываться общая страница ошибки.
- Ограничение прав пользователя БД, от имени которого работает приложение. Не давайте лишних привилегий.
- Регулярное обновление MySQL до версий, где уязвимые функции удалены или исправлены.
- Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов, хотя это не панацея.
Также рекомендуется проводить аудит кода и пентесты для выявления уязвимостей.
Заключение
Полезная нагрузка " OR EXTRACTVALUE(5018,CONCAT(0x7e,((SELECT (ELT(5018=5018,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, эксплуатирующей функцию EXTRACTVALUE в MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Помните: лучшая защита — параметризованные запросы и минимизация вывода ошибок.
Комментарии
—Войдите, чтобы оставить комментарий