Skip to content
KitploitKITPLOIT
工具博客
Log in
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2017-9822 — CVE-2017-9822的详细分析与概念验证利用代码,该漏洞为DotNetNuke CMS中的XXE/不安全反序列化漏洞,可通过Cookie篡改实现远程代码执行。 | Kitploit
工具/GitHubGitHub/tranphuc2005/cve-2017-9822
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试Payload 开发二进制利用
GitHubtranphuc2005/cve-2017-9822

CVE-2017-9822

CVE-2017-9822的详细分析与概念验证利用代码,该漏洞为DotNetNuke CMS中的XXE/不安全反序列化漏洞,可通过Cookie篡改实现远程代码执行。

查看仓库
41年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2017-9822

DotNetNuke(通常缩写为 DNN)是一个基于微软 ASP.NET 技术的 CMS(内容管理系统)平台 和 Web应用程序框架。

基本信息

  • 受影响产品: DotNetNuke(DNN Platform)——一个流行的 .NET CMS/门户。

  • 发布日期: 2017年7月。

  • 严重程度: 严重(CVSS ~9.8)。

  • 漏洞类型: XML外部实体(XXE)/ 不安全反序列化 → 远程代码执行(RCE)。

  • 影响范围: 9.1.1 之前的版本,可通过 cookie 远程执行代码。

安装指南

这里我使用的是 Windows 10 来搭建和调试程序。我安装的版本是 9.1.0,你可以参考 此链接 的安装方法。完成后效果如下:

1

分析

1

  • 根据我阅读的报告,此漏洞位于 DotNetNetNuke 处理 cookie 的位置。

  • DNN 对 cookie DNNPersonalization 使用了不安全的反序列化方法。

1

调试

  • 这里我使用 dnSpy,它是一个用于 .NET(C#、VB.NET、F#...) 应用程序的 反编译器和调试器。它允许你 查看、分析和编辑 编译后的 .NET 文件(如 .dll 或 .exe)的源代码。可以从 这里 安装。我们需要下载两个版本用于调试。

1

  • 首先,用 32 位版本打开 DotNetNuke.dll,选择 Edit Assembly Attributes (C#)。

1

  • 然后将下面一行:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
  • 改为:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations |
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

1

然后保存。

  • 以管理员身份打开 64 位版本,选择 Attach to Process。

1

  • 接下来选择 w3wp.exe。

1

选择 w3wp.exe 的原因:

  • w3wp.exe = IIS 工作进程。

  • 它是 IIS 中 应用程序池 的执行进程。

  • 当 HTTP 请求到达网站时,IIS 会创建或重用 w3wp.exe 进程来处理该请求(运行 ASP.NET 代码、处理模块、中间件、数据库连接等)。

  • 每个应用程序池可以有一个或多个 w3wp.exe 进程,具体取决于配置(web garden、回收等)。

接下来,选择 Debug -> Window -> Modules。

1

完成后将显示模块列表,右键点击任意模块,选择 Open All Modules。

1

最后将显示所有与 DotNetNuke 相关的程序集。

1

  • 进入 DotNetNuke.dll -> PersonalizationController#LoadProfile(int, int)。

1

此函数用于 加载用户的个性化(profile)数据 在 DNN 门户中。

  • 如果用户已登录 → 从 数据库 + 缓存 获取 profile。

  • 如果是匿名用户(未登录)→ 从 cookie DNNPersonalization 获取 profile。

这里我们应重点关注 DNNPersonalization。

  • 如果 userId 无效(匿名用户)。

  • 检查请求中是否有 DNNPersonalization cookie。

  • 如果有 → 从该 cookie 中获取 XML 值。

  • 我们将向网站发送一个 404 请求,并使用任意 DNNPersonalization,然后使用 dnSpy 在 DotNetNuke.dll -> PersonalizationController#LoadProfile(int, int) 处设置断点,即可调试。

1

1

  • 在调用栈部分,我们应重点分析 PortalSettings 类。

1

  • 值得注意的地方是,这里使用 if 条件来检查当前请求是否已通过身份验证(IsAuthenticated)。

  • 而我们发送的请求是 404 -> 未通过身份验证。

  • 继续在调用栈部分,我们关注 Handle404OrException。

1

  • 这里它会检查当前请求的 context.User 是否为 null,如果是,则将 context.User 设置为当前线程用户。

1

1

  • 可以看到在 Handle404OrException 中,变量 IsAuthenticated 现在是 true,且用户正是 IIS 服务器的用户,因此该请求将作为已验证用户执行。

  • 问题原因在于这段代码:

else if (transfer)
{
	if (context.User == null)
	{
		context.User = Thread.CurrentPrincipal;
	}
	response.TrySkipIisCustomErrors = true;
	IHttpHandler handler = new CDefault();
	context.Handler = handler;
	server.Transfer("~/" + text, true);
}
  • 如果 context.User 不存在 → 赋值为 Thread.CurrentPrincipal(即当前线程的标识)。

  • 这使得后续处理时请求拥有 用户/角色 信息。

=> 当我们向带有变量 DNNPersonalization 的 cookie 中传入任意内容时,它将以普通用户身份执行。

接下来看看 cookie 的处理流程

  • 仍然在 DotNetNuke.dll -> PersonalizationController#LoadProfile(int, int) 中。

  • 我们看到变量 text 从 cookie 值接收,然后作为输入传递给 Globals.DeserializeHashTableXml()。

1

  • 进入 Globals.DeserializeHashTableXml()。

1

函数 DeserializeHashTableXml 的职责是:

  • 接收一个 XML 字符串(Source)。

  • 解析该 XML 字符串,将其 转换为 Hashtable 对象。

  • 在解析过程中,它调用 XmlUtils.DeSerializeHashtable,参数为 "profile",用于指定 XML 的根节点。

进入 XmlUtils.DeSerializeHashtable 内部,我们看到它的处理方式。

1

函数 DeSerializeHashtable 接收 XML 字符串并将其转换为 Hashtable。对于每个 <item> 节点,函数会:

  • 获取 key 作为键。

  • 获取 type 并调用 Type.GetType(type) 来确定数据类型。

  • 使用 XmlSerializer.Deserialize 将 XML 内容转换为实际对象。

  • 添加到 Hashtable。

👉 问题:因为 type 和 XML 内容完全由用户控制(来自 cookie DNNPersonalization)。

生成 Payload

基于 XmlUtils#DeSerializeHashtable 这个漏洞点,创建一个类似的序列化和反序列化对象的程序:

using System.Xml;
using System.Diagnostics;
using System.Xml.Serialization;

namespace example
{
	public class Test  
	{    
	    private string _name;  
	    public string name  
	    {  
	        get { return _name; }  
	        set { this._name = value; execCMD(); }  
	    }  
	  
	    private void execCMD()  
	    {  
	        Process process = new Process();  
	        process.StartInfo.FileName = this._name;  
	        process.Start();  
	        process.Dispose(); // close  
	    }  
	}

    public class Program
    {
        private static string fileFolder = "D:\\lab\\csharp\\DNN\\example\\serialization\\";
        public static void Serialize(Object obj) // method xml serialize arbitrary object 
        {
            // create xml root element
            XmlDocument xmlDocument = new XmlDocument();
            XmlElement xmlElementRoot = xmlDocument.CreateElement("profile");
            xmlDocument.AppendChild(xmlElementRoot);

            // create child node item with attribute type containing the object type name

            XmlElement xmlElementItem = xmlDocument.CreateElement("item");
            xmlElementItem.SetAttribute("type", obj.GetType().AssemblyQualifiedName);

            // serialize obj into xmlDocumentObj
下载工具