Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых и опасных видов атак на веб-приложения. Злоумышленники внедряют вредоносный SQL-код в запросы, чтобы получить доступ к базе данных, изменить или удалить информацию. Одной из техник является использование функции EXTRACTVALUE в СУБД MySQL для извлечения данных через сообщения об ошибках. В запросе OR EXTRACTVALUE(9367,CONCAT(0x7e,((SELECT (ELT(9367=9367,1)))),0x7e))-- - как раз демонстрируется такой подход.
В этой статье мы детально разберём, как работает эта инъекция, какие функции задействованы и как защититься от подобных атак.
Разбор запроса OR EXTRACTVALUE(...)
Рассматриваемый запрос состоит из нескольких частей. Начнём с того, что OR — логический оператор, который добавляется к оригинальному условию, чтобы инъекция сработала, если исходное условие ложно. Далее идёт вызов функции EXTRACTVALUE(9367, CONCAT(...)). Эта функция предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако при некорректном XPath она генерирует ошибку, содержащую переданные данные. Именно это и эксплуатируется.
Первый аргумент 9367 — это произвольное число, которое не является валидным XML. Второй аргумент — результат CONCAT(0x7e, ((SELECT (ELT(9367=9367,1)))), 0x7e). Функция CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить поиск выводимых данных в сообщении об ошибке.
Внутри CONCAT находится подзапрос SELECT (ELT(9367=9367,1)). Функция ELT возвращает N-й элемент из списка. Здесь 9367=9367 — всегда истинное условие, которое возвращает 1. Таким образом, ELT(1,1) вернёт строку '1'. Это простейший пример, демонстрирующий работу конструкции. В реальной атаке вместо 1 мог бы быть подзапрос, извлекающий имя пользователя, пароль или другую конфиденциальную информацию.
Завершающая часть -- - — это комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы избежать синтаксических ошибок.
Как работает EXTRACTVALUE для извлечения данных?
Функция EXTRACTVALUE(XML_document, XPath_expression) анализирует XML и возвращает текст узла, соответствующего XPath. Если XML некорректен или XPath не соответствует ни одному узлу, MySQL выдаёт ошибку вида: XPATH syntax error: '...', где в кавычках может оказаться часть переданного XPath-выражения. Злоумышленник конструирует XPath так, чтобы в сообщение об ошибке попали нужные данные. Например, можно передать CONCAT(0x7e, (SELECT password FROM users LIMIT 1), 0x7e), и тогда в ошибке появится пароль, окружённый тильдами.
Этот метод относится к классу error-based SQL injection (инъекции на основе ошибок). Он удобен тем, что результат виден непосредственно в ответе сервера, без необходимости использовать слепые техники.
Пример практического использования
Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Оригинальный запрос: SELECT * FROM products WHERE id = 1. Злоумышленник подставляет:
1 OR EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -
В результате сервер вернёт ошибку, содержащую версию MySQL, например: XPATH syntax error: '~5.7.31~'. Аналогично можно извлечь имена таблиц, колонок, логины и пароли.
В нашем запросе используется ELT(9367=9367,1), что демонстрирует базовый принцип, но не несёт полезной нагрузки. Это, скорее, тестовый пример для проверки уязвимости.
Какие функции задействованы?
- EXTRACTVALUE — извлекает значение из XML, но при ошибке выводит переданные данные.
- CONCAT — объединяет строки, позволяет добавить разделители.
- ELT — возвращает N-й элемент из списка; используется для формирования вывода.
- SELECT — подзапрос для получения данных из БД.
- 0x7e — шестнадцатеричный код символа ~, служит маркером.
Все эти функции встроены в MySQL и доступны по умолчанию, что делает атаку возможной без дополнительных расширений.
Последствия успешной SQL-инъекции
Успешная эксплуатация уязвимости может привести к:
- Утечке конфиденциальных данных (пароли, персональная информация).
- Изменению или удалению данных.
- Обходу аутентификации и авторизации.
- Выполнению административных операций в базе данных.
- В некоторых случаях — к выполнению команд на сервере.
Поэтому важно своевременно выявлять и устранять такие уязвимости.
Как защититься от SQL-инъекций через EXTRACTVALUE?
Основные меры защиты:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают в SQL-код напрямую.
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(для MySQL). - Валидация и фильтрация входных данных — проверка типов, длины, допустимых символов.
- Ограничение прав пользователя БД — не использовать root для веб-приложений.
- Регулярное обновление СУБД и приложений — закрытие известных уязвимостей.
- Использование WAF (Web Application Firewall) — может блокировать подозрительные запросы.
- Отключение вывода ошибок на продакшене — чтобы злоумышленник не видел детали.
Важно понимать, что никакая отдельная мера не даёт 100% гарантии, поэтому рекомендуется комбинировать подходы.
Заключение
Запрос OR EXTRACTVALUE(9367,CONCAT(0x7e,((SELECT (ELT(9367=9367,1)))),0x7e))-- - — это пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для вывода данных через сообщения об ошибках. Понимание таких техник необходимо как специалистам по безопасности для тестирования, так и разработчикам для написания защищённого кода. Всегда используйте параметризованные запросы и следите за обновлениями безопасности.
Если вы нашли подобную уязвимость в своём приложении, немедленно устраните её и проведите аудит безопасности.
Комментарии
—Войдите, чтобы оставить комментарий