Что такое ' ) OR EXTRACTVALUE(1643,CONCAT(0x7e,...))-- -?
Эта строка — пример полезной нагрузки (payload) для SQL-инъекции, нацеленной на базы данных MySQL. Она использует функцию EXTRACTVALUE для вызова ошибки, которая выводит результат подзапроса. Подобные техники часто применяются пентестерами для извлечения информации из уязвимых веб-приложений, когда обычные UNION-инъекции не работают.
Разбор синтаксиса
Рассмотрим payload по частям:
')— закрывает ранее открытую скобку и строковый литерал в уязвимом SQL-запросе. Например, если исходный запрос былSELECT * FROM users WHERE name = ('$input'), то вставка')завершает строку и условие.OR— логический оператор, который делает условие всегда истинным (или выполняет дополнительное выражение).EXTRACTVALUE(1643,CONCAT(0x7e,((SELECT (ELT(1643=1643,1)))),0x7e))— вызов функции EXTRACTVALUE, которая извлекает значение из XML-документа по XPath-выражению. В данном случае первый аргумент — число 1643 (некорректный XML), а второй — строка, начинающаяся с тильды (0x7e), затем результат подзапросаSELECT (ELT(1643=1643,1))и снова тильда. Функция EXTRACTVALUE генерирует ошибку XPATH, если XPath-выражение некорректно, и в тексте ошибки выводится переданная строка.-- -— комментарий, который обрезает оставшуюся часть оригинального запроса (пробел после--обязателен в MySQL).
Как работает EXTRACTVALUE для извлечения данных
Функция EXTRACTVALUE в MySQL предназначена для работы с XML. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение содержит синтаксическую ошибку, MySQL возвращает сообщение об ошибке, включающее часть переданного выражения. Злоумышленники используют это для вывода данных: они конструируют XPath так, чтобы в тексте ошибки появились нужные значения.
В нашем payload подзапрос SELECT (ELT(1643=1643,1)) возвращает число 1. Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 1643=1643 истинно, что даёт 1, поэтому ELT возвращает первую строку — "1". Затем это значение конкатенируется с тильдами и передаётся в EXTRACTVALUE. Поскольку первый аргумент (1643) не является корректным XML, функция выдаст ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
Таким образом, в сообщении об ошибке отобразится результат подзапроса — в данном случае "1". В реальной атаке вместо ELT может быть подзапрос, извлекающий имена таблиц, столбцов или данные пользователей.
Пример использования в SQL-инъекции
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE id = ('$id')
Если передать $id = ') OR EXTRACTVALUE(1643,CONCAT(0x7e,(SELECT database()),0x7e))-- -, то после подстановки получится:
SELECT * FROM articles WHERE id = ('') OR EXTRACTVALUE(1643,CONCAT(0x7e,(SELECT database()),0x7e))-- -')
MySQL выполнит подзапрос SELECT database(), получит имя текущей базы данных, сконкатенирует с тильдами и вызовет ошибку XPATH, в тексте которой будет имя базы. Например:
ERROR 1105 (HY000): XPATH syntax error: '~mydb~'
Так злоумышленник узнаёт имя базы данных. Аналогично можно извлекать таблицы, столбцы и сами данные.
Почему это работает: особенности MySQL
Функция EXTRACTVALUE доступна в MySQL и MariaDB. Она помечена как устаревшая в MySQL 5.7 и удалена в MySQL 8.0, но во многих старых системах всё ещё используется. Ошибка XPATH возникает, когда XPath-выражение не соответствует синтаксису. Например, если передать строку, начинающуюся с тильды, которая не является допустимым XPath, MySQL сообщит об ошибке и включит эту строку в сообщение.
Важно: в MySQL 8.0 функция EXTRACTVALUE удалена, поэтому данная техника не сработает на современных версиях. Однако существует аналогичная функция UPDATEXML, которая также может вызывать ошибки XPATH.
Защита от SQL-инъекций
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не попадают напрямую в SQL-запрос.
- Экранировать специальные символы при невозможности использовать подготовленные выражения. Но этот метод менее надёжен.
- Ограничить права пользователя базы данных, чтобы даже при успешной инъекции злоумышленник не мог получить доступ к важным данным.
- Обновить MySQL до версии 8.0, где EXTRACTVALUE удалена, но это не панацея — есть другие функции.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Заключение
Строка ') OR EXTRACTVALUE(1643,CONCAT(0x7e,((SELECT (ELT(1643=1643,1)))),0x7e))-- - — это классический пример SQL-инъекции, использующей ошибки XPATH для извлечения данных. Понимание таких техник помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Всегда используйте параметризованные запросы и следите за обновлениями СУБД.
Комментарии
—Войдите, чтобы оставить комментарий