Что такое EXTRACTVALUE и почему она в запросе?
Встречая в логах или в поле ввода строку вида %")))) AND EXTRACTVALUE(4444,CONCAT(0x7e,((SELECT (ELT(4444=4444,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке.
Функция EXTRACTVALUE в MySQL используется для извлечения значения из XML-фрагмента по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Если XPath-выражение некорректно, MySQL генерирует ошибку, которая включает в себя часть переданного XPath. Именно это свойство эксплуатируют злоумышленники.
Как работает инъекция с EXTRACTVALUE
Рассмотрим строку подробнее:
%")))) AND EXTRACTVALUE(4444,CONCAT(0x7e,((SELECT (ELT(4444=4444,1)))),0x7e))-- -
Она состоит из нескольких частей:
- %")))) — попытка закрыть предыдущие кавычки и скобки, чтобы внедрить свой код.
- AND EXTRACTVALUE(...) — вызов уязвимой функции.
- CONCAT(0x7e, (SELECT ...), 0x7e) — конкатенация символа тильды (0x7e) с результатом подзапроса и ещё одной тильды. Это делается для того, чтобы отделить полезную нагрузку от служебного текста ошибки.
- SELECT (ELT(4444=4444,1)) — подзапрос, который возвращает 1, если условие истинно (4444=4444 всегда истинно). ELT — функция выбора элемента из списка.
- -- - — комментарий, отсекающий остаток оригинального SQL-запроса.
Когда MySQL выполняет EXTRACTVALUE с XPath-выражением, начинающимся с тильды (~), он выдаёт ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса. Так злоумышленник может извлекать произвольные данные, подставляя вместо ELT(4444=4444,1) другие SQL-выражения, например, версию СУБД, имена таблиц, пароли.
Пошаговый разбор полезной нагрузки
- Закрытие предыдущих конструкций: последовательность
%"))))пытается завершить строковый литерал и несколько круглых скобок, чтобы обеспечить синтаксическую возможность внедрения. - Логическое условие AND: если предыдущее выражение истинно, выполняется EXTRACTVALUE. Это позволяет обойти некоторые фильтры.
- Формирование XPath с ошибкой: CONCAT создаёт строку, начинающуюся с ~ (0x7e), за которой следует результат подзапроса, и заканчивается ~. XPath не допускает такого формата, поэтому MySQL генерирует ошибку.
- Извлечение данных: в тексте ошибки возвращается результат подзапроса. Меняя подзапрос, атакующий может получать любые данные из базы.
- Комментирование остатка:
-- -превращает оставшуюся часть исходного запроса в комментарий, чтобы не нарушать синтаксис.
Цели и опасность error-based инъекций
Error-based SQL-инъекции считаются одними из самых опасных, так как позволяют быстро извлекать информацию без необходимости слепого перебора. Злоумышленник может:
- Получить версию MySQL и другую служебную информацию.
- Извлечь имена таблиц и столбцов из информационной схемы.
- Похитить конфиденциальные данные: логины, пароли, персональные данные пользователей.
- В некоторых случаях выполнить произвольные SQL-запросы, вплоть до модификации или удаления данных.
Как защититься от SQL-инъекций через EXTRACTVALUE
Основная причина уязвимости — использование динамически конструируемых SQL-запросов с включением пользовательского ввода без должной обработки. Вот ключевые меры защиты:
- Параметризованные запросы (prepared statements) — самый надёжный способ. Все современные языки программирования и драйверы БД поддерживают параметризацию, при которой данные передаются отдельно от SQL-кода.
- Экранирование специальных символов — если параметризация невозможна, используйте функции экранирования, предоставляемые драйвером БД (например, mysqli_real_escape_string в PHP).
- Валидация и фильтрация входных данных — проверяйте, что вводимые данные соответствуют ожидаемому формату (числа, email и т.д.).
- Ограничение прав пользователя БД — учётная запись, используемая веб-приложением, должна иметь минимально необходимые привилегии. Не давайте ей доступ к INFORMATION_SCHEMA без необходимости.
- Отключение вывода подробных ошибок — на продакшене не показывайте пользователям сообщения об ошибках БД. Это затруднит эксплуатацию error-based инъекций.
- Использование WAF — веб-application firewall может блокировать известные шаблоны атак, но не должен быть единственной мерой защиты.
- Регулярное обновление СУБД и фреймворков — закрывайте известные уязвимости.
Пример безопасного кода
Вместо конкатенации строк используйте параметризованные запросы. Например, на PHP с PDO:
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $userInput]);
Здесь пользовательский ввод передаётся отдельно и не может изменить структуру запроса.
Заключение
Строка с EXTRACTVALUE — это не случайный набор символов, а целенаправленная попытка эксплуатации уязвимости SQL-инъекции. Понимание механизма её работы помогает разработчикам и администраторам лучше защищать свои системы. Главный вывод: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий