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

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

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

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2017-9822 — 针对CVE-2017-9822的逐步技术分析与漏洞利用开发,这是DotNetNuke中一个严重的远程代码执行漏洞,源于DNNPersonalization cookie中存在不安全的XML反序列化。包括环境搭建、使用dnSpy进行调试配置、Gadget链构造(ObjectDataProvider、ResourceDictionary)以及Webshell上传。 | Kitploit
工具/GitHubGitHub/tnot123/cve-2017-9822
漏洞分析代码分析漏洞利用逆向工程Web应用程序漏洞利用调试器渗透测试学习与教育Payload 开发二进制利用实验室与实践
GitHub
10个月前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
tnot123/cve-2017-9822

cve-2017-9822

针对CVE-2017-9822的逐步技术分析与漏洞利用开发,这是DotNetNuke中一个严重的远程代码执行漏洞,源于DNNPersonalization cookie中存在不安全的XML反序列化。包括环境搭建、使用dnSpy进行调试配置、Gadget链构造(ObjectDataProvider、ResourceDictionary)以及Webshell上传。

查看仓库
  • CVE-2017-9822
    • 基本信息
    • 环境搭建
    • 调试设置
    • 分析
    • 调试
      • XmlSerializer
      • 攻击利用链(Gadget)
      • ObjectDataProvider
      • ResourceDictionary
      • 从XML不安全反序列化到RCE

CVE-2017-9822

DNN(也称为DotNetNuke)在9.1.1版本之前存在通过Cookie实现远程代码执行的可能性,即所谓的“2017-08(重要)DNN网站可能存在的远程代码执行漏洞”。

基本信息

  • 受影响产品:DotNetNuke(DNN平台)——一款流行的.NET CMS/门户系统。
  • 公布日期:2017年7月。
  • 严重程度:严重(CVSS评分约9.8)。
  • 漏洞类型:XML外部实体注入(XXE)/不安全反序列化 → 远程代码执行(RCE)。
  • 影响范围:9.1.1版本之前可通过Cookie实现远程代码执行。

alt

什么是DotNetNuke? DotNetNuke是一个免费且开源的Web CMS(内容管理系统),使用C#编写,基于.NET平台。DotNetNuke非常流行且被广泛使用,因为即使没有太多技术知识,你也可以在几分钟内部署一个DNN网站。DotNetNuke的另一个重要功能是能够创建或导入由VB.NET或C#构建的第三方自定义模块。 DNN可以安装在包含Windows Server、IIS、ASP.NET和SQL Server for Windows的堆栈上。DNN还支持通过电子邮件验证新用户注册,但你需要配置有效的SMTP服务器才能使此安全功能生效。 DNN的主要功能 • 模块化架构: DNN允许通过安装社区开发的其他模块(功能模块)轻松扩展。管理员可以通过管理界面上传新模块(上传.zip包)或直接将解压后的文件放入服务器目录。 • 用户管理: 系统提供详细的安全和权限管理功能(角色/权限),适用于门户和模块。用户账户、角色和权限在DNN中集中管理。 • 内容管理: 支持WYSIWYG编辑器、文章、图片、文档等管理。具有工作流/发布(按审批流程发布文章)和内容版本控制功能。内容存储在公共数据库(SQL Server)中。 • API和扩展集成: DNN为开发人员提供.NET API,用于开发自定义模块(WebForms、MVC、Razor)和集成外部服务。大量的第三方库(界面主题、电子商务模块、论坛等)可用于扩展功能。 • 界面和主题: 皮肤系统(主题)将内容与界面分离,实现灵活的网页设计。由DNN生成的网站可以通过更换皮肤来改变界面。 • 模块安装机制: DNN模块打包在ZIP文件中,可以通过管理界面安装或手动解压安装。DNN支持已编译模块(.NET DLL)和动态Razor模块;所有模块都可以通过每个页面的权限设置来授予或撤销访问权限。

环境搭建

操作系统: Windows 10 .NET Framework: 4.5.1+ Web服务器: Microsoft IIS 10 数据库服务器: Microsoft® SQL Server® 2019 Express, SQL Server Management Studio Dotnetnuke版本 9.1.0 可以使用以下Google dork搜索在互联网上可用的Dotnetnuke部署版本,并根据网站进行检测: 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位)中,然后选择“编辑程序集属性(C#)”

alt

将代码行从 [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] 修改为 [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

alt

然后选择“编译”并将此模块保存回原位置。 接下来,以管理员身份运行dnSpy,选择“调试” -> “附加到进程”

alt

选择w3wp.exe进程

alt

我们必须附加此进程进行调试的原因是,IIS上的Web应用程序通常使用工作进程。它们负责处理发送到IIS Web服务器的每个应用程序池的Web请求;一台机器上可以有多个工作进程,它们都名为w3wp.exe。一个小提示:有时可能没有运行中的w3wp进程,IIS在收到第一个Web请求之前不会启动工作进程。

alt

回到调试,附加进程后,选择:调试 -> 窗口 -> 模块

alt

点击一个模块,选择“打开所有模块”

alt

此时,在程序集窗口中,我们可以看到所有相关的模块

alt

分析

反序列化是将字节流解释并转换为应用程序可以执行的数据的过程。 反序列化存在的主要问题是,大多数情况下它可能使用用户输入的数据。这意味着你可以将恶意载荷注入到应用程序所需的格式中,并可能操控逻辑、泄露数据甚至实现远程代码执行。 DotNetNuke使用DNNPersonalization Cookie来存储匿名用户的个性化设置(已验证用户的设置通过其个人资料页面存储)。根据报告,漏洞发生在处理DNNPersonalization Cookie的部分,该Cookie用于加载用户配置文件,但在访问不存在的页面(404错误)时仍可触发未授权访问。此漏洞的入口点位于DotNetNuke.dll模块的LoadProfile函数中,我们将使用dnSpy反编译此模块并进一步分析: 在PersonalizationController#LoadProfile(int, int)中

alt

如果userId不为null,则将变量text赋值为请求中的DNNPersonalization Cookie的值,然后调用Globals#DeserializeHashTableXml

alt

Globals#DeserializeHashTableXml调用XmlUtils#DeSerializeHashtable

alt

处理流程如下:

  • 从xmlSource加载XML
  • 遍历根配置文件中的每个item节点
  • 对于每个item,根据type属性定义对象类型,并根据该对象类型初始化XmlSerializer,如第160-161行所示
  • 在第163行将此item反序列化为一个对象,并存储在哈希表中
  • 返回哈希表 我们可以完全控制DNNPersonalization Cookie的值,因此可以修改反序列化的对象。

调试

使用Burp发送一个触发404状态码的请求,并设置Cookie DNNPersonalization

alt

这里可以看到,处理404的函数Handler404OrException触发了一个调用链,并调用了Personalization.LoadProfile(int,int)。

alt

上述代码中值得注意的是,有一个if条件检查当前请求是否已通过身份验证(IsAuthenticated),而显然我们刚才发出的请求是未经过身份验证的,且访问了一个不存在的入口点。那么为什么当前请求会被当作已验证用户执行呢? 继续调试,回到堆栈的末尾附近,在AdvancedUrlRewriter#Handle404OrException处发现了一个else if循环:

alt

这里它会检查请求的context.User当前是否为null,如果是,则将context.User设置为当前线程的用户。设置断点后可以看到结果如下:

alt

现在IsAuthenticated变量的值为true,并且用户被设置为当前线程的用户,该用户属于IIS服务器的IIS APPPOOL组,因此该请求被视为已验证用户执行。之所以存在这个逻辑,是因为404处理程序在HttpContext.User被设置之前被调用,而后续的处理依赖于User.IsAuthenticated,为避免空引用错误,开发人员将User对象设置为当前线程的WindowsPrincipal对象。

XmlSerializer

XmlSerializer是Microsoft自己的序列化类,用于在XML字符串和对象之间进行转换。它的命名空间是:System.Xml.Serialization。 使用XmlSerializer的示例:

alt

alt

通过XmlSerializer实现RCE攻击的必要条件是必须能够控制传递给XmlSerializer构造函数的类型数据。也就是说,导致利用链(gadget)的类型数据必须传递给XmlSerializer.mapping属性。

攻击利用链(Gadget)

攻击XML反序列化最常用的利用链是ObjectDataProvider。这个利用链可以通过ysoserial .net工具生成。

ObjectDataProvider

基本上,使用这个类,我们可以调用任何类的任何方法。

alt

例如,我们可以调用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反序列化载荷:

alt

alt

ResourceDictionary

ResourceDictionary用于WPF开发,由于是WPF,它必须使用XAML语言。首先,我们看一个使用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:

  1. xmlns:c引用了System.Diagnostics命名空间,并命名为c
  2. d:Key=""是一个空名称。在XAML语法中,Key键值必须存在。
  3. ObjectType表示对象类型
  4. d:Type等价于typeof()
  5. MethodName是ObjectDataProvider的一个属性。传入Start相当于调用Start方法。
  6. c:Process等价于System.Diagnostics.Process 整个XAML解析完成后,相当于创建了一个ObjectDataProvider对象,该对象会自动调用System.Diagnostics.Process.Start("cmd.exe","/c calc")

alt

执行上述代码相当于ObjectDataProvider -> Person.Evil()。如果通过XmlSerializer实现RCE攻击,流程将如下所示:ObjectDataProvider -> XamlReader.Parse() -> ObjectDataProvider -> System.Diagnostics.Process.Start("cmd.exe","/c calc")

从XML不安全反序列化到RCE

现在,我们需要找到一个在执行反序列化时可以执行代码的对象。在POC中,使用了DotNetNuke.Common.Utilities.FileSystemUtils的PullFile函数来利用“任意文件上传”

alt

alt

得到obj.xml:

alt

发送载荷

alt

alt

在DNN反序列化Cookie后,在HTTP服务器上可以看到对/cmd.aspx的请求,即反序列化成功,Webshell已上传到DNN

alt

类似地,利用DotNetNuke.Common.Utilities.FileSystemUtils的WriteFile函数来读取文件

alt

alt

下载工具