Что такое EXTRACTVALUE и при чём тут SQL-инъекция?
Строка %') AND EXTRACTVALUE(3873,CONCAT(0x7e,((SELECT (ELT(3873=3873,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. В данной статье мы детально разберём, как работает этот запрос, какие функции задействованы и как защититься от подобных атак.
Функция EXTRACTVALUE: назначение и синтаксис
EXTRACTVALUE — это встроенная функция MySQL (а также Oracle), предназначенная для извлечения значения из XML-документа с помощью XPath-выражения. Синтаксис:
EXTRACTVALUE(XMLType_instance, XPath_expression)
Функция принимает два аргумента: экземпляр типа XML и выражение XPath. Возвращает скалярное значение узла, соответствующего XPath. Результат должен быть единственным узлом — текстовым, атрибутом или элементом. Если элемент содержит несколько текстовых узлов, возвращается ошибка.
Однако злоумышленники нашли способ использовать эту функцию для вывода произвольных данных через сообщения об ошибках. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданное значение.
Разбор вредоносного запроса
Рассмотрим строку по частям:
%')— закрывает предыдущее выражение в уязвимом запросе. Символ%часто используется в LIKE-запросах, а')закрывает скобку и кавычку, завершая оригинальное условие.AND EXTRACTVALUE(3873,CONCAT(0x7e,((SELECT (ELT(3873=3873,1)))),0x7e))— внедряемая конструкция. Число 3873 — произвольный идентификатор, не влияющий на логику, но необходимый для синтаксиса. Второй аргумент — XPath-выражение, формируемое через CONCAT.-- -— комментарий, который игнорирует остаток оригинального запроса.
Функция CONCAT и тильда (0x7e)
CONCAT объединяет строки. В данном случае к результату подзапроса добавляются символы ~ (0x7e в шестнадцатеричном виде) с обеих сторон. Тильда используется как маркер, чтобы облегчить поиск выводимых данных в сообщении об ошибке.
Подзапрос с ELT и условием 3873=3873
ELT(N, str1, str2, ...) возвращает N-й элемент из списка строк. В нашем случае ELT(3873=3873,1) — условие 3873=3873 всегда истинно, что даёт 1. Значит, ELT вернёт первый элемент — число 1. Это простейший пример; в реальных атаках вместо 1 может быть подзапрос, извлекающий данные (например, имя таблицы, хеш пароля).
Таким образом, CONCAT сформирует строку вида ~1~. Затем EXTRACTVALUE попытается интерпретировать её как XPath. Поскольку ~1~ не является корректным XPath, MySQL выдаст ошибку, в тексте которой будет фигурировать переданная строка. Злоумышленник, анализируя сообщение об ошибке, может получить интересующие его данные.
Зачем нужна такая инъекция?
Error-based SQL-инъекции позволяют извлекать информацию из базы данных, когда прямой вывод результатов (union-based) невозможен. Они эксплуатируют недостаточную фильтрацию пользовательского ввода и вывод ошибок СУБД на страницу. В случае с EXTRACTVALUE атакующий может получить имена таблиц, колонок, логины, пароли и другую конфиденциальную информацию.
Как защититься от SQL-инъекций через EXTRACTVALUE?
- Используйте подготовленные выражения (prepared statements). Параметризация запросов — самый надёжный способ предотвратить инъекции. Данные передаются отдельно от SQL-кода и не интерпретируются как часть запроса.
- Экранируйте пользовательский ввод. Если по каким-то причинам нельзя использовать подготовленные выражения, применяйте функции экранирования, такие как
mysqli_real_escape_string. - Ограничьте права пользователя БД. Учётная запись, используемая веб-приложением, должна иметь минимально необходимые привилегии. Не давайте доступ к системным таблицам без надобности.
- Отключите вывод ошибок СУБД на продакшене. Сообщения об ошибках не должны попадать в браузер пользователя. Логируйте их, но не показывайте.
- Регулярно обновляйте СУБД и фреймворки. Уязвимости в самом MySQL или в библиотеках могут усугубить ситуацию.
- Используйте WAF (Web Application Firewall). Современные WAF могут обнаруживать и блокировать попытки SQL-инъекций по сигнатурам, включая конструкции с EXTRACTVALUE.
Заключение
Запрос %') AND EXTRACTVALUE(3873,CONCAT(0x7e,((SELECT (ELT(3873=3873,1)))),0x7e))-- - — это типичный пример эксплуатации уязвимости error-based SQL-инъекции в MySQL. Понимание механизма работы таких атак помогает разработчикам и администраторам правильно выстраивать защиту. Главный вывод: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий