
DNN (также известный как DotNetNuke) до версии 9.1.1 допускает удалённое выполнение кода через cookie, также известное как "2017-08 (Важно) Возможность удалённого выполнения кода на веб-сайтах DNN".

Что такое DotNetNuke?
DotNetNuke — это бесплатная CMS с открытым исходным кодом для веб-сайтов, написанная на C# и основанная на платформе .NET. DotNetNuke очень популярен и широко используется в интернете, поскольку вы можете развернуть веб-версию DNN всего за несколько минут, не имея глубоких технических знаний. Ещё одна важная функция DotNetNuke — возможность создавать или импортировать пользовательские сторонние модули, написанные на VB.NET или C#.
DNN можно установить на стек, включающий Windows Server, IIS, ASP.NET и SQL Server для Windows. DNN также поддерживает регистрацию новых пользователей с подтверждением по email, но для работы этой функции безопасности необходимо настроить корректный SMTP-сервер.
Основные функции DNN
• Модульная архитектура: DNN позволяет легко расширяться за счёт установки дополнительных модулей, разработанных сообществом. Администратор может загружать новые модули через интерфейс администратора (загрузка .zip-пакетов) или распаковывать их непосредственно в папку на сервере.
• Управление пользователями: Система предоставляет функции безопасности и детального разграничения прав (роли/разрешения) для порталов и модулей. Учётные записи пользователей, роли и права централизованно управляются в DNN.
• Управление контентом: Поддержка WYSIWYG-редактирования, управление статьями, изображениями, документами и т. д. Имеется система workflow/публикации (публикация материалов по процессу рецензирования) и версионирование контента. Контент хранится в общей базе данных (SQL Server).
• API и расширенная интеграция: DNN предоставляет .NET API для разработчиков, позволяющий создавать пользовательские модули (WebForms, MVC, Razor) и интегрировать внешние сервисы. Множество готовых сторонних библиотек (темы оформления, модули электронной коммерции, форумы и т. д.) позволяют расширять функциональность.
• Интерфейс и темы: Система скинов (тем) отделяет контент от интерфейса, что позволяет гибко проектировать веб-сайты. Сайты, созданные на DNN, могут менять внешний вид путём смены скинов.
• Механизм установки модулей: Модули DNN упаковываются в ZIP-файлы и могут устанавливаться через интерфейс администратора или путём ручной распаковки. DNN поддерживает как скомпилированные модули (.NET DLL), так и динамические модули Razor; любому модулю можно предоставить или запретить доступ через настройки разрешений на каждой странице.
Операционные системы: Windows 10
.NET Framework: 4.5.1+
Веб-сервер: Microsoft IIS 10
Сервер базы данных: Microsoft® SQL Server® 2019 Express, SQL Server Management Studio
Версия DotNetNuke: 9.1.0
Для поиска доступных в интернете развёрнутых версий DotNetNuke можно использовать следующие Google dorks и проверить их на сайте:
inurl:dnn.js
inurl:dnn.modalpopup.js
inurl:dnn.servicesframework.js
inurl:dnn.xml.js
inurl:dnncore.js
inurl:/Portals/0/
inurl:/DesktopModules/
inurl:/DNNCorp/
inurl:/DotNetNuke
inurl:/tabid//Default.aspx
inurl:/tabid//language/*/Default.aspx
intext:"by DNN Corp "
Для создания окружения можно следовать этой статье
Измените атрибуты сборки на «отлаживаемые»; это очень важно, поскольку во время выполнения применяются некоторые оптимизации, которые могут мешать отладке: некоторые точки останова могут не срабатывать, а некоторые переменные — не существовать.
Загрузите DotNetNuke.dll в dnSpy (32 bit), затем выберите Edit Assembly Attributes (C#)

Измените строку
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
на
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

Затем выберите Compile и сохраните этот модуль обратно в прежнее место.
Далее запустите dnSpy с правами администратора и выберите Debug -> Attach to Process

Выберите процесс w3wp.exe

Причина, по которой для отладки нужно подключиться к этому процессу, в том, что веб-приложения на IIS обычно используют рабочие процессы (worker process). Они обрабатывают веб-запросы, поступающие на веб-сервер IIS, для каждого пула приложений; рабочих процессов на одной машине может быть несколько, и все они называются w3wp.exe. Небольшое примечание: может наступить момент, когда процесс w3wp не запущен, — IIS не запускает рабочие процессы, пока не получит первый веб-запрос.

Вернёмся к отладке: после подключения к процессу выберите: Debug -> Windows -> Modules

Нажмите на один из модулей и выберите Open All Modules

Теперь в окне Assembly можно увидеть все связанные модули

Десериализация — это процесс интерпретации байтовых потоков и преобразования их в данные, которые может исполнять приложение.
Основная проблема десериализации в том, что в большинстве случаев она может использовать пользовательские входные данные. Это означает, что вы можете внедрить вредоносные payload'ы в ожидаемый приложением формат и манипулировать логикой, раскрывать данные или даже выполнять код удалённо.
DotNetNuke использует cookie DNNPersonalization для хранения настроек персонализации анонимных пользователей (настройки аутентифицированных пользователей хранятся через их страницу профиля). Согласно отчёту, уязвимость находится в обработке cookie DNNPersonalization. Этот cookie используется для загрузки профиля пользователя, однако его можно вызвать без аутентификации при обращении к несуществующей странице (ошибка 404). Точка входа этой уязвимости находится в функции LoadProfile модуля DotNetNuke.dll; декомпилируем этот модуль с помощью dnSpy и проанализируем подробнее:
В PersonalizationController#LoadProfile(int, int)

Если userId не равен null, переменная text получит значение cookie DNNPersonalization из запроса, после чего будет вызвана Globals#DeserializeHashTableXml

Globals#DeserializeHashTableXml вызывает XmlUtils#DeSerializeHashtable

Процесс обработки выглядит следующим образом:
Используем Burp для отправки запроса, вызывающего статус 404 + cookie DNNPersonalization

Здесь видно, что функция обработки 404 — Handler404OrException — запустила цепочку вызовов и обратилась к Personalization.LoadProfile(int,int).

В приведённом выше коде примечательно условие if, проверяющее, аутентифицирован ли текущий запрос (IsAuthenticated), хотя очевидно, что отправленный нами запрос был неаутентифицированным и направлялся к несуществующей точке входа. Так почему же текущий запрос выполняется как аутентифицированный пользователь?
Продолжаем отладку: в конце стека, в AdvancedUrlRewriter#Handle404OrException, виден блок else if следующего вида:

Здесь проверяется, равен ли context.User текущего запроса null; если это так, context.User присваивается пользователь текущего потока. Установив точку останова, можно увидеть следующий результат:

Теперь переменная IsAuthenticated имеет значение true, а пользователь, назначенный запросу, — это пользователь текущего потока, принадлежащий группе IIS APPPOOL сервера IIS, поэтому запрос выполняется как аутентифицированный. Эта логика существует потому, что обработчик 404 вызывается до того, как устанавливается HttpContext.User, а дальнейший поток обработки зависит от User.IsAuthenticated; чтобы избежать ошибок NullReference, разработчики присваивают объекту User объект WindowsPrincipal текущего потока.
XmlSerializer — это собственный класс сериализации Microsoft, используемый для преобразования между строками и XML-объектами. Его namespace: System.Xml.Serialization.
Пример использования XmlSerializer:


Условие атаки RCE через XmlSerializer — обязательный контроль над типом данных, передаваемым в конструктор XmlSerializer. То есть типы данных, ведущие к gadget, должны быть переданы в свойство XmlSerializer.mapping
Самый популярный gadget для атаки на десериализацию XML — ObjectDataProvider. Этот gadget можно создать с помощью инструмента ysoserrial .net
По сути, используя этот класс, можно вызвать любой метод любого класса.

Например, мы можем вызвать Process.Start с параметрами, как показано ниже:
ObjectDataProvider o = new ObjectDataProvider(); o.MethodParameters.Add("cmd.exe"); o.MethodParameters.Add("/c calc"); o.MethodName = "Start"; o.ObjectInstance = new Process(); Console.ReadKey();
Создадим XML payload для десериализации с приведённым выше кодом:


ResourceDictionary используется для разработки WPF, а поскольку это WPF, он должен использовать язык XAML. Сначала рассмотрим payload, использующий ResourceDictionary для выполнения команд.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"> <ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"> <ObjectDataProvider.MethodParameters> <b:String>cmd</b:String> <b:String>/c calc</b:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary>
Объяснение этого XAML:

Выполнение приведённого выше кода эквивалентно ObjectDataProvider -> Person.Evil(). Если выполнять атаку RCE через XmlSerializer, поток будет выглядеть так: ObjectDataProvider -> XamlReader.Parse() -> ObjectDataProvider -> System.Diagnostics.Process.Start("cmd.exe","/c calc")
Теперь цель — найти объект, который может выполнять код при десериализации. В POC функция PullFile из DotNetNuke.Common.Utilities.FileSystemUtils используется для эксплуатации "arbitrary file upload"


Получаем obj.xml:

Отправляем payload


После того как DNN десериализует cookie, на HTTP-сервере появляется запрос к /cmd.aspx — десериализация прошла успешно, веб-шелл загружен на DNN

Аналогичным образом можно использовать функцию WriteFile из DotNetNuke.Common.Utilities.FileSystemUtils для чтения файла

