Что такое EXTRACTVALUE в SQL-инъекциях?
Строка ` AND EXTRACTVALUE(2451,CONCAT(0x7e,((SELECT (ELT(2451=2451,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер. В отличие от UNION-инъекций, здесь не нужно подбирать количество столбцов — достаточно, чтобы приложение выводило ошибки MySQL.
Error-based SQLi считается одним из самых быстрых и удобных методов эксплуатации, когда целевое приложение отображает текст ошибок базы данных. Злоумышленник может получить имена таблиц, колонок, логины, пароли и другие конфиденциальные данные. Понимание механики таких payload’ов необходимо как пентестерам, так и разработчикам для защиты своих систем.
Разбор payload по частям
Рассмотрим каждый элемент запроса подробно.
1. Обратная кавычка (`)
Символ обратной кавычки часто используется в SQL-запросах для экранирования имён таблиц и столбцов. Внедряя его, атакующий пытается разорвать исходный SQL-запрос. Например, если уязвимый запрос выглядит как SELECT * FROM users WHERE name = '$input', то вставка ` может закрыть строковый литерал или идентификатор, после чего добавляется произвольный код.
2. AND EXTRACTVALUE(2451, ...)
Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-строки по указанному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Если XPath-выражение некорректно, MySQL генерирует ошибку. Именно это свойство эксплуатируется: злоумышленник передаёт в качестве XPath строку, содержащую результат подзапроса, и сервер возвращает её в тексте ошибки.
Первый аргумент — число 2451 — это произвольное значение, которое не влияет на работу, но используется для того, чтобы запрос выглядел валидным. Второй аргумент — строка, начинающаяся с 0x7e (тильда ~), затем результат подзапроса и снова 0x7e.
3. CONCAT(0x7e, (SELECT (ELT(2451=2451,1))), 0x7e)
Функция CONCAT() объединяет строки. Здесь она склеивает:
0x7e— шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер, чтобы в сообщении об ошибке легко найти внедрённые данные.(SELECT (ELT(2451=2451,1)))— подзапрос, возвращающий значение.- Снова
0x7e— закрывающая тильда.
Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Выражение 2451=2451 всегда истинно (1), поэтому ELT(1, 1) вернёт строку '1'. В реальной атаке вместо '1' подставляется подзапрос, извлекающий нужные данные, например: ELT(1, (SELECT password FROM users LIMIT 1)).
4. Комментарий -- -
Последовательность -- - — это комментарий в SQL. Два дефиса начинают комментарий до конца строки, а пробел после них обязателен в некоторых СУБД (включая MySQL) для корректного распознавания. Таким образом, всё, что идёт после payload’а в исходном запросе, игнорируется, что позволяет завершить инъекцию без синтаксических ошибок.
Как это работает на практике
Предположим, уязвимый запрос: SELECT * FROM articles WHERE id = '$id'. Атакующий передаёт в параметр id строку:
1' AND EXTRACTVALUE(2451,CONCAT(0x7e,(SELECT database()),0x7e))-- -
Тогда итоговый запрос примет вид:
SELECT * FROM articles WHERE id = '1' AND EXTRACTVALUE(2451,CONCAT(0x7e,(SELECT database()),0x7e))-- -'
MySQL попытается выполнить EXTRACTVALUE с XPath-выражением вида ~имя_базы~. Это невалидный XPath, поэтому возникнет ошибка: XPATH syntax error: '~database_name~'. В этом сообщении и будут содержаться данные, которые извлекает атакующий.
В нашем payload’е вместо database() используется ELT(2451=2451,1) — это просто демонстрация, возвращающая '1'. В реальной атаке на этом месте может быть любой подзапрос, возвращающий строку.
Зачем нужна такая конструкция?
Error-based инъекции с EXTRACTVALUE и UPDATEXML популярны по нескольким причинам:
- Простота: не нужно беспокоиться о количестве столбцов, как в UNION-инъекциях.
- Скорость: данные извлекаются за один запрос, а не побайтово, как в blind SQLi.
- Обход фильтров: многие WAF’ы блокируют UNION, но пропускают EXTRACTVALUE.
Однако для успешной эксплуатации необходимо, чтобы приложение выводило сообщения об ошибках MySQL. Если ошибки скрыты, метод не сработает.
Меры защиты
Чтобы предотвратить подобные атаки, разработчикам следует:
- Использовать подготовленные выражения (prepared statements) — это самый надёжный способ, так как данные не смешиваются с кодом SQL.
- Экранировать специальные символы — если prepared statements недоступны, применяйте функции экранирования, например mysqli_real_escape_string().
- Отключить вывод ошибок БД — в production-окружении ошибки MySQL не должны показываться пользователю.
- Применять WAF — веб-приложения firewalls могут блокировать подозрительные конструкции, но не стоит полагаться только на них.
- Регулярно проводить аудит безопасности — сканеры уязвимостей и ручное тестирование помогут выявить SQL-инъекции.
Заключение
Payload ` AND EXTRACTVALUE(2451,CONCAT(0x7e,((SELECT (ELT(2451=2451,1)))),0x7e))-- - — это компактный и эффективный пример error-based SQL-инъекции для MySQL. Он демонстрирует, как с помощью встроенных функций (EXTRACTVALUE, CONCAT, ELT) можно заставить сервер вернуть произвольные данные в сообщении об ошибке. Понимание таких техник необходимо для защиты веб-приложений: используйте параметризованные запросы, скрывайте ошибки и проводите регулярные проверки безопасности.
Комментарии
—Войдите, чтобы оставить комментарий