Что такое SQL-инъекция и функция EXTRACTVALUE
SQL-инъекция (SQLi) — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет в запрос к базе данных произвольный SQL-код. Цель — получить доступ к данным, изменить их или выполнить другие нежелательные действия. В данной статье мы разберём конкретный пример инъекции, использующий функцию EXTRACTVALUE и оператор ELT в СУБД MySQL.
Функция EXTRACTVALUE(XML_target, XPath_expr) извлекает значение из фрагмента XML по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться результат вычисления вложенного выражения. Это свойство часто используется в так называемых error-based SQL-инъекциях для извлечения данных.
Разбор payload: " ) AND EXTRACTVALUE(4746,CONCAT(0x7e,((SELECT (ELT(4746=4746,1)))),0x7e))-- -
Рассмотрим структуру запроса по частям.
" )— закрывает строковый литерал и круглую скобку в оригинальном запросе, делая дальнейший код частью SQL-выражения.AND— логический оператор, добавляющий условие к WHERE-клаузе.EXTRACTVALUE(4746, CONCAT(0x7e, ((SELECT (ELT(4746=4746,1)))), 0x7e))— вызов функции EXTRACTVALUE. Первый аргумент (4746) — произвольное число, которое должно быть корректным XML-документом (обычно используется для отладки). Второй аргумент — XPath-выражение, формируемое через CONCAT.0x7e— шестнадцатеричное представление символа~(тильда). Используется как разделитель, чтобы облегчить поиск результата в сообщении об ошибке.(SELECT (ELT(4746=4746,1)))— подзапрос, возвращающий результат функции ELT.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Если N=1, возвращается '1'. Условие4746=4746всегда истинно, поэтому ELT возвращает '1'.-- -— комментарий, обрезающий остаток исходного запроса.
В результате XPath-выражение принимает вид ~1~. При попытке разобрать его как XPath MySQL выдаёт ошибку: XPATH syntax error: '~1~'. В текст ошибки попадает значение, возвращённое подзапросом. В данном случае это константа '1', но в реальной атаке вместо неё могла бы быть, например, версия СУБД или имя пользователя.
Зачем используется ELT и CONCAT
Функция ELT позволяет выбрать одну из строк по номеру. В простейшем случае с двумя аргументами (номер и строка) она возвращает строку, если номер равен 1. Комбинация с CONCAT и тильдами создаёт строку, которая заведомо вызовет ошибку XPath, но при этом содержит полезные данные. Это классический приём error-based инъекции, описанный во многих практических руководствах по SQLi.
Например, запрос SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)); вернёт ошибку с версией MySQL.
Какие ошибки может вызвать такой payload
При выполнении запроса с EXTRACTVALUE и некорректным XPath MySQL возвращает ошибку с кодом 1105 (HY000): XPATH syntax error: '~1~'. Если же количество столбцов в UNION-запросе не совпадает с исходным, возникает ошибка 1222 (21000): The used SELECT statements have a different number of columns. Это часто случается при попытке использовать UNION ALL без предварительного определения числа столбцов.
В нашем случае инъекция не использует UNION, поэтому ошибка 1222 маловероятна. Однако если исходный запрос возвращает несколько столбцов, а внедряемое выражение — один, может возникнуть несоответствие. Важно понимать, что error-based инъекции работают только тогда, когда приложение выводит сообщения об ошибках базы данных пользователю. В противном случае атакующий не увидит результат.
Как защититься от подобных атак
Основной метод защиты — использование параметризованных запросов (prepared statements) с привязкой переменных. Это исключает возможность внедрения SQL-кода, так как данные передаются отдельно от структуры запроса. Дополнительные меры:
- Экранирование специальных символов с помощью функций типа
mysqli_real_escape_string(для MySQL). - Ограничение прав пользователя базы данных: не давайте приложению прав на чтение системных таблиц и выполнение опасных функций.
- Отключение вывода подробных ошибок БД в production-окружении.
- Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов.
- Регулярное обновление СУБД и фреймворков.
Стоит отметить, что функция EXTRACTVALUE устарела начиная с MySQL 5.7.6 и удалена в MySQL 8.0. Однако в старых версиях она по-прежнему представляет угрозу.
Вывод
Рассмотренный payload — типичный пример error-based SQL-инъекции, эксплуатирующей функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание механизма таких атак помогает разработчикам и администраторам правильно выстраивать защиту. Никогда не используйте подобные конструкции на реальных системах без разрешения — это незаконно.
Комментарии
—Войдите, чтобы оставить комментарий