Введение
SQL-инъекции остаются одной из самых распространённых уязвимостей веб-приложений. Среди них особое место занимают error-based инъекции, позволяющие извлекать данные через сообщения об ошибках. Функция ExtractValue в MySQL — популярный инструмент для таких атак. В этой статье мы разберём конкретный запрос: ")) AND EXTRACTVALUE(8565,CONCAT(0x7e,((SELECT (ELT(8565=8565,1)))),0x7e))-- -.
Что такое ExtractValue?
ExtractValue — это встроенная функция MySQL, предназначенная для извлечения значения из XML-строки с помощью выражения XPath. Синтаксис:
EXTRACTVALUE(xml_frag, xpath_expr)
Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим часть переданного выражения. Именно это свойство используется злоумышленниками для вывода данных.
Разбор запроса
Рассмотрим запрос по частям:
"))— закрывает предполагаемую строку и скобки в уязвимом SQL-запросе.AND EXTRACTVALUE(8565,CONCAT(0x7e,((SELECT (ELT(8565=8565,1)))),0x7e))— внедряемая функция. Первый аргумент (8565) — произвольное число, второй — конкатенация тильды (0x7e), результата подзапроса и снова тильды.ELT(8565=8565,1)— функция ELT возвращает N-й элемент из списка. Здесь условие8565=8565всегда истинно (1), поэтому возвращается 1.-- -— комментарий, обрезающий остаток оригинального запроса.
В результате MySQL попытается выполнить XPath-выражение ~1~, что вызовет ошибку вида: XPATH syntax error: '~1~'. В реальной атаке вместо 1 подставляется конкатенация данных из базы (например, имена таблиц или пароли).
Как работает error-based инъекция
Механизм прост:
- Приложение передаёт пользовательский ввод в SQL-запрос без должной очистки.
- Злоумышленник добавляет конструкцию, вызывающую ошибку с полезной нагрузкой.
- Сообщение об ошибке отображается на странице или возвращается в ответе API.
- Из текста ошибки извлекаются данные.
Функция ExtractValue удобна тем, что позволяет выводить до 32 символов за раз (ограничение длины сообщения об ошибке). Для получения длинных строк используются посимвольные или постраничные методы.
Пример эксплуатации
Допустим, уязвимый запрос: SELECT * FROM users WHERE id = '$_GET[id]'. Передав 1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -, мы получим ошибку с версией MySQL. Аналогично можно извлечь имена таблиц, колонок и данные.
Важно: подобные действия без разрешения владельца системы являются нарушением закона и преследуются по статье 272 УК РФ.
Методы защиты
Чтобы предотвратить error-based SQL-инъекции через ExtractValue и другие функции, следуйте этим рекомендациям:
- Используйте подготовленные выражения (prepared statements) — это самый надёжный способ.
- Отключите вывод ошибок MySQL на продакшене — установите
display_errors = Off. - Применяйте ORM (например, Doctrine, Hibernate), которые автоматически экранируют параметры.
- Валидируйте входные данные — приводите типы, используйте белые списки.
- Ограничьте права пользователя БД — не давайте приложению прав на чтение системных таблиц.
- Используйте WAF для фильтрации подозрительных конструкций.
Заключение
Запрос ")) AND EXTRACTVALUE(8565,CONCAT(0x7e,((SELECT (ELT(8565=8565,1)))),0x7e))-- - — классический пример error-based SQL-инъекции, эксплуатирующей функцию ExtractValue. Понимание механизма помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Никогда не тестируйте уязвимости на чужих системах без письменного разрешения.
Комментарии
—Войдите, чтобы оставить комментарий