Введение
В мире веб-безопасности SQL-инъекции остаются одной из самых распространённых и опасных уязвимостей. Запрос OR EXTRACTVALUE(4137,CONCAT(0x7e,((SELECT (ELT(4137=4137,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE в СУБД MySQL. В этой статье мы детально разберём, что делает каждый элемент этого запроса, зачем он нужен злоумышленнику и как защититься от подобных атак.
Что такое EXTRACTVALUE?
Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Она возвращает текст узла, соответствующего XPath. Однако при некорректном XPath-выражении MySQL генерирует ошибку, которая может содержать полезную информацию. Именно это свойство и используется в error-based SQL-инъекциях.
Разбор запроса по частям
Рассмотрим структуру запроса:
OR— логический оператор, добавляемый к оригинальному запросу для внедрения условия.EXTRACTVALUE(4137, CONCAT(0x7e, ((SELECT (ELT(4137=4137,1)))), 0x7e))— вызов функции с двумя аргументами: первый — произвольное число 4137 (может быть любым), второй — конкатенация строк.-- -— комментарий, который игнорирует оставшуюся часть оригинального SQL-запроса.
Первый аргумент 4137 не играет роли, так как XML-документ невалиден, но это не важно. Второй аргумент — результат CONCAT(0x7e, ((SELECT (ELT(4137=4137,1)))), 0x7e). Здесь 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.
Функция ELT и условие 4137=4137
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(4137=4137, 1): выражение 4137=4137 истинно, что в MySQL интерпретируется как 1. Значит, ELT вернёт первую строку — 1. Это простой способ получить константу, но в реальных атаках вместо 1 может быть подзапрос, извлекающий данные (например, имя базы данных, хеши паролей).
Конструкция SELECT (ELT(4137=4137,1)) — это подзапрос, возвращающий 1. В более сложных вариантах здесь может быть SELECT database() или SELECT password FROM users LIMIT 1.
Как работает error-based инъекция
Когда MySQL выполняет EXTRACTVALUE с XPath-выражением, содержащим недопустимые символы (например, тильду), он выдаёт ошибку вида: XPATH syntax error: '~1~'. В сообщении об ошибке отображается переданная строка. Если вместо 1 подставить результат подзапроса, например, имя базы данных, то ошибка покажет это имя. Так злоумышленник может пошагово извлекать данные из базы.
В нашем запросе второй аргумент — CONCAT(0x7e, ((SELECT (ELT(4137=4137,1)))), 0x7e) — даст строку ~1~. При вызове EXTRACTVALUE(4137, '~1~') MySQL попытается интерпретировать ~1~ как XPath и выдаст ошибку: XPATH syntax error: '~1~'. Это подтверждает, что инъекция работает.
Зачем нужен комментарий -- -
Символы -- начинают комментарий в SQL (при условии, что после них есть пробел). Пробел и дефис добавлены для надёжности, чтобы комментарий точно распознался. Всё, что идёт после -- -, игнорируется. Это позволяет отсечь остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку.
Пример уязвимого запроса
Предположим, веб-приложение формирует такой SQL-запрос:
SELECT * FROM articles WHERE id = '$id'Если пользователь передаст в параметр id значение 1 OR EXTRACTVALUE(4137,CONCAT(0x7e,((SELECT (ELT(4137=4137,1)))),0x7e))-- -, то итоговый запрос станет:
SELECT * FROM articles WHERE id = '1 OR EXTRACTVALUE(4137,CONCAT(0x7e,((SELECT (ELT(4137=4137,1)))),0x7e))-- -'MySQL выполнит условие id = '1' (ложь, если id не 1), затем оператор OR и вызовет EXTRACTVALUE, что приведёт к ошибке, раскрывающей информацию.
Последствия успешной атаки
Error-based SQL-инъекции позволяют злоумышленнику:
- Получить версию СУБД, имя текущей базы данных, пользователя.
- Извлечь содержимое таблиц (логины, пароли, персональные данные).
- В некоторых случаях выполнить произвольные команды на сервере.
Это критическая уязвимость, которая может привести к полной компрометации системы.
Способы защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не интерпретируются как SQL-код.
- Экранировать специальные символы при невозможности использовать подготовленные выражения.
- Ограничить права пользователя БД, чтобы минимизировать ущерб от возможной инъекции.
- Включить детализированное логирование ошибок и не показывать их пользователю, чтобы избежать утечки информации.
- Регулярно обновлять СУБД и применять патчи безопасности.
Также рекомендуется использовать веб-application firewall (WAF) для фильтрации подозрительных запросов.
Заключение
Запрос OR EXTRACTVALUE(4137,CONCAT(0x7e,((SELECT (ELT(4137=4137,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции через функцию EXTRACTVALUE в MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности создавать более защищённые приложения. Всегда проверяйте вводимые данные и используйте современные методы защиты.
Комментарии
—Войдите, чтобы оставить комментарий