Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cve-2017-9822 — In-depth technical analysis and proof-of-concept for CVE-2017-9822, an insecure deserialization vulnerability in DotNetNuke leading to remote code execution via crafted cookies. | Kitploit
Tools/GitHubGitHub/tnot123/cve-2017-9822
Vulnerability AnalysisCode AnalysisExploitationReverse EngineeringWeb Application ExploitationDebuggersPenetration TestingLearning & EducationPayload DevelopmentBinary ExploitationLabs & Practice
611 months agoNot yet reviewed
GitHub
tnot123/cve-2017-9822

cve-2017-9822

In-depth technical analysis and proof-of-concept for CVE-2017-9822, an insecure deserialization vulnerability in DotNetNuke leading to remote code execution via crafted cookies.

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
  • CVE-2017-9822
    • Key Information
    • Setup Environment
    • Setup Debug
    • Analysis
    • Debug
      • XmlSerializer
      • Attack Gadget
      • ObjectDataProvider
      • ResourceDictionary
      • From XML Insecure Deserialization to RCE

CVE-2017-9822

DNN (also known as DotNetNuke) before version 9.1.1 has the ability to execute remote code via cookies, also known as "2017-08 (Critical) Possible Remote Code Execution on DNN websites".

Key Information

  • Affected Product: DotNetNuke (DNN Platform) – a popular .NET CMS/portal.
  • Disclosure Date: July 2017.
  • Severity: Critical (CVSS ~9.8).
  • Vulnerability Type: XML External Entity (XXE) / Insecure Deserialization → Remote Code Execution (RCE).
  • Impact: before version 9.1.1, remote code execution via cookies is possible.

alt

What is DotNetNuke?
DotNetNuke is a free and open-source web CMS (Content Management System) written in C# and based on the .NET platform. DotNetNuke is very popular and widely used on the Internet because you can deploy a DNN web instance in minutes without much technical knowledge. Another important feature of DotNetNuke is the ability to create or import custom third-party modules built with VB.NET or C#.
DNN can be installed on a stack consisting of Windows Server, IIS, ASP.NET, and SQL Server for Windows. DNN also supports new user registration verification via email, but you need to configure a valid SMTP server for this security feature to work. Main features of DNN • DNN allows easy extension by installing additional modules (functional modules) developed by the community. Administrators can load new modules through the admin interface (upload .zip package) or extract them directly into a directory on the server. • The system provides detailed security and permission features (roles/permissions) for portals and modules. User accounts, roles, and permissions are centrally managed within DNN. • Supports WYSIWYG editing, management of articles, images, documents, etc. It has a workflow/publishing system (post approval process) and content versioning. Content is stored in a common SQL Server database. • DNN provides .NET APIs for developers to build custom modules (WebForms, MVC, Razor) and integrate with external services. A wide range of third-party libraries are available (themes, e-commerce modules, forums, etc.) to extend functionality. • A skin system separates content from the interface, allowing flexible web design. Websites created with DNN can change their appearance by switching skins. • DNN modules are packaged in ZIP files and can be installed via the admin interface or by manual extraction. DNN supports both compiled modules (.NET DLL) and dynamic Razor modules; every module can be granted or revoked access through permission settings on each page.



Modular Architecture:

User Management:

Content Management:

API and Extended Integration:

Interface and Themes:

Module Installation Mechanism:

Setup Environment

Operating Systems: Windows 10
.NET Framework: 4.5.1+
Web Server: Microsoft IIS 10
Database Server: Microsoft® SQL Server® 2019 Express, SQL Server Management Studio
DotNetNuke version 9.1.0
You can use the following Google dorks to find available DotNetNuke deployments on the Internet and check them against the website:
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 "
You can follow this article to build the environment:

Setup Debug

Modify the assembly attributes to "debuggable" properties; this is essential because at runtime, some optimizations are applied that may inadvertently hinder debugging; some breakpoints may not be hit or some variables may not exist.
Load DotNetNuke.dll into dnSpy (32-bit) then select Edit Assembly Attributes (C#)

alt

Change the line from
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
To
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

alt

Then select Compile and save this module back to its original location.
Next, launch dnSpy with admin privileges and select Debug -> Attach to Process

alt

Select the process w3wp.exe

alt

The reason we must attach to this process for debugging is that web applications on IIS typically use worker processes. They handle web requests sent to the IIS web server for each application pool. There can be multiple worker processes on a machine, all named w3wp.exe. A small note: sometimes there is no w3wp process running; IIS will not start worker processes until the first web request is received.

alt

Returning to debugging, after attaching the process, next select: Debug -> Windows -> Modules

alt

Click on a module and select Open All Modules

alt

At this point, in the Assembly window, you can see all related modules

alt

Analysis

Deserialization is the process of interpreting byte streams and converting them into data that the application can execute.
The main issue with Deserialization is that most of the time it can use user input data. This means you can inject malicious payloads into the required format of the application and possibly manipulate logic, leak data, or even execute remote code.
DotNetNuke uses the DNNPersonalization cookie to store anonymous user personalization preferences (authenticated user preferences are stored via their profile page). According to the report, the vulnerability occurs in the handling of the DNNPersonalization cookie, which is used to load user profiles but can still be triggered unauthenticated when accessing a non-existent page (404 error). The entry point of this bug is in the LoadProfile function belonging to the DotNetNuke.dll module. We will decompile this module using dnSpy and analyze it further:
At PersonalizationController#LoadProfile(int, int)

alt

If userId is not null, then the variable text is assigned the value of the DNNPersonalization cookie from the request, then calls Globals#DeserializeHashTableXml

alt

Globals#DeserializeHashTableXml calls XmlUtils#DeSerializeHashtable

alt

Processing flow as follows:

  • LoadXml from xmlSource
  • Iterate through each item node in the root profile.
  • For each item, get the object type defined based on the type attribute and instantiate an XmlSerializer according to that object type as in lines 160-161
  • Deserialize this item into an object in line 163 and store it in the hashtable
  • Return the hashtable
    We can fully control the value of the DNNPersonalization cookie, thus can modify the deserialized object.

Debug

Use Burp to send a request that triggers a 404 status + DNNPersonalization cookie

alt

Here we can see that the function called to handle 404 is Handler404OrException which triggered a call chain and invoked Personalization.LoadProfile(int,int).

alt

Notable in the above code is the if condition checking whether the current request is IsAuthenticated, and clearly our request was unauthenticated to a non-existent entrypoint. So why was the current request executed as an authenticated user?
Continuing debugging, going back near the bottom of the stack, at AdvancedUrlRewriter#Handle404OrException there is an else-if block as follows:

alt

Here it checks if the request context.User is null; if true, it assigns context.User as the current thread user. Setting a breakpoint shows the following result:

alt

The IsAuthenticated variable is now true, and the user is assigned the user running the current thread, which belongs to the IIS APPPOOL group of the IIS server, so the request is executed as an authenticated user. The reason this logic exists is that the 404 handler is invoked before HttpContext.User is set, and the subsequent processing flow relies on User.IsAuthenticated, so to avoid Null reference errors, developers assign the User object as the WindowsPrincipal object of the current thread.

XmlSerializer

XmlSerializer is Microsoft's own serializer class, used to convert between strings and XML objects. Its namespace is: System.Xml.Serialization.
Example of using XmlSerializer:

alt

alt

The condition for an RCE attack via XmlSerializer is that you must control the data type passed to the XmlSerializer constructor. That is, the data types leading to the gadget must be passed into the XmlSerializer.mapping property.

Attack Gadget

The most common gadget for attacking XML deserialization is ObjectDataProvider. This gadget can be generated by the ysoserial .net tool.

ObjectDataProvider

Basically, when using this class, you can call any method of any class.

alt

For example, we can call Process.Start with parameters as shown below:
ObjectDataProvider o = new ObjectDataProvider(); o.MethodParameters.Add("cmd.exe"); o.MethodParameters.Add("/c calc"); o.MethodName = "Start"; o.ObjectInstance = new Process(); Console.ReadKey();
Construct an XML deserialization payload with the above code:

alt

alt

ResourceDictionary

ResourceDictionary is used for WPF development; because it is WPF, it must use the XAML language. First, let’s look at a payload using ResourceDictionary to execute commands.
<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>
Explanation of this XAML:

  1. xmlns:c refers to the namespace System.Diagnostics and is named c
  2. d:Key="" with an empty name. In XAML syntax, the Key attribute value must exist.
  3. ObjectType represents the object type
  4. d:Type is equivalent to typeof()
  5. MethodName is a property of ObjectDataProvider. Passing Start is equivalent to calling the Start method.
  6. c:Process is equivalent to System.Diagnostics.Process
    After the entire XAML is parsed, it is equivalent to creating an ObjectDataProvider object, which automatically calls System.Diagnostics.Process.Start("cmd.exe","/c calc")

alt

Executing the above code is equivalent to ObjectDataProvider -> Person.Evil(). If performing an RCE attack via XmlSerializer, the flow would look like this: ObjectDataProvider -> XamlReader.Parse() -> ObjectDataProvider -> System.Diagnostics.Process.Start("cmd.exe","/c calc")

From XML Insecure Deserialization to RCE

The goal now is to find an object that can execute code during deserialization. In the POC, the PullFile function of DotNetNuke.Common.Utilities.FileSystemUtils is used to exploit "arbitrary file upload".

alt

alt

We get obj.xml:

alt

Send payload

alt

alt

After DNN deserializes the cookies, the HTTP server receives a request to /cmd.aspx, meaning the deserialization succeeded, and the webshell has been uploaded to DNN.

alt

Similarly, exploiting the WriteFile function of DotNetNuke.Common.Utilities.FileSystemUtils to read files.

alt

alt

Download Tool