Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых видов атак на веб-приложения. Злоумышленник внедряет вредоносный SQL-код в запрос, чтобы получить доступ к данным, изменить их или выполнить произвольные команды. Существует несколько типов инъекций: union-based, boolean-based, time-based и error-based. Последний тип часто использует функцию EXTRACTVALUE в СУБД MySQL.
Запрос %" OR EXTRACTVALUE(4133,CONCAT(0x7e,((SELECT (ELT(4133=4133,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции. Давайте разберём его по частям.
Разбор внедряемого кода
Символы и операторы
%"— это часть оригинального запроса, которая, вероятно, подставляется в SQL-шаблон. Символ%часто используется как подстановочный знак в LIKE, а"закрывает строковый литерал. Злоумышленник добавляетOR, чтобы внедрить своё условие.OR— логический оператор, который делает условие истинным, если хотя бы одна часть верна. Это позволяет обойти проверки.EXTRACTVALUE(4133, CONCAT(0x7e, ((SELECT (ELT(4133=4133,1)))), 0x7e))— вызов функции EXTRACTVALUE, которая извлекает значение из XML-строки по XPath-выражению. Синтаксис:EXTRACTVALUE(XML_document, XPath_expression).
Функция EXTRACTVALUE возвращает текст из XML, соответствующий XPath. Если XPath содержит ошибку, MySQL генерирует сообщение об ошибке, которое включает результат вычисления выражения. Это и есть основа error-based инъекции: злоумышленник заставляет базу данных выдать нужные данные в тексте ошибки.
Как работает EXTRACTVALUE в инъекции
В нашем случае первый аргумент — число 4133 (может быть любым). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(4133=4133,1)))), 0x7e). Функция CONCAT объединяет строки: 0x7e — это шестнадцатеричное представление символа ~ (тильда), который используется как маркер для облегчения поиска результата в сообщении об ошибке.
Внутри CONCAT выполняется подзапрос SELECT (ELT(4133=4133,1)). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 4133=4133 — всегда истинное условие, которое возвращает 1. Таким образом, ELT(1, 1) вернёт строку '1'.
Итоговый XPath, передаваемый в EXTRACTVALUE, будет содержать тильды и результат подзапроса. Поскольку XPath синтаксически некорректен (начинается с ~), MySQL выдаст ошибку вида: XPATH syntax error: '~1~'. В этом сообщении злоумышленник увидит результат выполнения подзапроса — в данном случае '1'.
Зачем это нужно злоумышленнику?
Error-based инъекции позволяют извлекать данные посимвольно или целыми строками, если они помещаются в сообщение об ошибке. В реальных атаках вместо ELT(4133=4133,1) подставляются подзапросы, возвращающие имена таблиц, столбцов, логины, пароли и другую конфиденциальную информацию. Например, можно получить версию СУБД, имя текущей базы данных или хеши паролей.
Ограничение: длина сообщения об ошибке обычно ограничена (около 64 символов для XPath ошибок в MySQL), поэтому данные извлекаются по частям с помощью функций SUBSTRING, MID или LIMIT.
Пример реальной атаки
Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Запрос в коде: SELECT * FROM products WHERE id = '$id'. Злоумышленник подставляет:
1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -
В ответе сервера появится ошибка с именем базы данных. Так пошагово можно вытащить всю структуру БД.
Меры защиты
Чтобы предотвратить SQL-инъекции, включая error-based через EXTRACTVALUE, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не интерпретируются как SQL-код.
- Экранировать специальные символы с помощью функций типа
mysqli_real_escape_string(для MySQL). Но это менее надёжно, чем подготовленные выражения. - Ограничить права пользователя БД: не давать приложению прав на чтение системных таблиц, если они не нужны.
- Отключить вывод ошибок БД в продакшене, чтобы злоумышленник не получал подсказок. Ошибки должны логироваться, а пользователь видеть общее сообщение.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов, хотя это не панацея.
- Регулярно обновлять СУБД и фреймворки, чтобы закрыть известные уязвимости.
Заключение
Запрос %" OR EXTRACTVALUE(4133,CONCAT(0x7e,((SELECT (ELT(4133=4133,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий использование функции EXTRACTVALUE для вызова ошибки с внедрёнными данными. Понимание таких атак помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Всегда используйте параметризованные запросы и следите за актуальностью мер защиты.
Комментарии
—Войдите, чтобы оставить комментарий