记一个黑盒挖到的C#程序反序列化漏洞
字数 1065 2025-08-03 16:42:22

C#程序反序列化漏洞分析与利用教学

漏洞概述

本文详细分析一个黑盒发现的C#程序反序列化漏洞,该漏洞存在于客户端与服务端的通信过程中,由于使用了不安全的BinaryFormatter进行序列化/反序列化操作,导致远程代码执行风险。

前置知识

在深入分析前,建议阅读以下背景资料:

漏洞发现过程

初始接触

  1. 获取到一个客户端程序压缩包,包含可执行文件和多个DLL
  2. 通过分析配置文件发现加密的账号密码
  3. 意外运行程序后发现登录界面预填了账号密码

流量分析

  1. 抓包发现通信流量被加密,无法直接爆破
  2. 决定逆向分析客户端处理逻辑

代码逆向分析

登录流程调用链

this.btnLogin_Click 
--> this.OnLoginEvent() 
--> this.SendLoginMsg() 
--> this.zip.GetBuffer() 
--> this.ZipData() 
--> this.GetZipBuffer() 
--> new BinaryFormatter().Serialize() 
--> this.CompressToByte() 
--> new YYEncrypt().EncryptData() 
--> this.dh.Login()

关键漏洞点

  1. GetZipBuffer方法中使用BinaryFormatter序列化用户输入数据
  2. 数据经过压缩和自定义加密后发送到服务端
  3. 服务端预期会进行相反的解密、解压和反序列化操作

服务端预期处理流程

XXX.MsgReceive 
--> new YYEncrypt().DecryptData
--> this.DeCompressToBytes 
--> new BinaryFormatter().Deserialize() 
--> this.msgSysInfo.getLoginInfo() 
--> XXX

漏洞验证与利用

利用思路

  1. 构造恶意序列化数据
  2. 按照客户端相同的处理流程(序列化->压缩->加密)
  3. 发送到服务端触发反序列化

利用步骤

  1. 使用Ysoserial.NET生成Gadget
  2. 将生成的payload按照客户端相同流程处理:
    • BinaryFormatter序列化
    • 压缩(CompressToByte)
    • 加密(YYEncrypt.EncryptData)
  3. 发送到目标服务端

实际利用经验

  1. 本地测试成功弹出计算器
  2. 目标环境需要尝试多个Gadget才能成功执行
  3. 命令执行无回显,通过写入Web目录获取shell

防御建议

  1. 避免使用BinaryFormatter进行反序列化
  2. 如必须使用,实现SerializationBinder限制反序列化类型
  3. 使用安全的序列化替代方案如:
    • JSON.NET
    • Protobuf
    • XML序列化(注意XXE风险)
  4. 对输入数据进行严格验证

扩展思考

  1. 加密通信不能替代输入验证,只是增加了攻击复杂度
  2. 通用组件漏洞影响范围广,发现一个漏洞可能影响多个系统
  3. 内网系统同样需要严格的安全防护

参考工具

  1. Ysoserial.NET - .NET反序列化payload生成工具
  2. dnSpy - .NET程序逆向分析工具
  3. 360杀毒/Virustotal - 初步安全检测

总结

本案例展示了即使有加密通信的保护,不安全的反序列化操作仍可能导致严重漏洞。开发人员应避免使用危险的序列化机制,安全人员测试时应关注所有数据处理环节,特别是序列化/反序列化点。

C#程序反序列化漏洞分析与利用教学 漏洞概述 本文详细分析一个黑盒发现的C#程序反序列化漏洞,该漏洞存在于客户端与服务端的通信过程中,由于使用了不安全的BinaryFormatter进行序列化/反序列化操作,导致远程代码执行风险。 前置知识 在深入分析前,建议阅读以下背景资料: .NET反序列化漏洞系列文章 BinaryFormatter序列化机制 Ysoserial.NET工具使用 漏洞发现过程 初始接触 获取到一个客户端程序压缩包,包含可执行文件和多个DLL 通过分析配置文件发现加密的账号密码 意外运行程序后发现登录界面预填了账号密码 流量分析 抓包发现通信流量被加密,无法直接爆破 决定逆向分析客户端处理逻辑 代码逆向分析 登录流程调用链 关键漏洞点 GetZipBuffer 方法中使用 BinaryFormatter 序列化用户输入数据 数据经过压缩和自定义加密后发送到服务端 服务端预期会进行相反的解密、解压和反序列化操作 服务端预期处理流程 漏洞验证与利用 利用思路 构造恶意序列化数据 按照客户端相同的处理流程(序列化->压缩->加密) 发送到服务端触发反序列化 利用步骤 使用Ysoserial.NET生成Gadget 将生成的payload按照客户端相同流程处理: BinaryFormatter序列化 压缩(CompressToByte) 加密(YYEncrypt.EncryptData) 发送到目标服务端 实际利用经验 本地测试成功弹出计算器 目标环境需要尝试多个Gadget才能成功执行 命令执行无回显,通过写入Web目录获取shell 防御建议 避免使用BinaryFormatter进行反序列化 如必须使用,实现SerializationBinder限制反序列化类型 使用安全的序列化替代方案如: JSON.NET Protobuf XML序列化(注意XXE风险) 对输入数据进行严格验证 扩展思考 加密通信不能替代输入验证,只是增加了攻击复杂度 通用组件漏洞影响范围广,发现一个漏洞可能影响多个系统 内网系统同样需要严格的安全防护 参考工具 Ysoserial.NET - .NET反序列化payload生成工具 dnSpy - .NET程序逆向分析工具 360杀毒/Virustotal - 初步安全检测 总结 本案例展示了即使有加密通信的保护,不安全的反序列化操作仍可能导致严重漏洞。开发人员应避免使用危险的序列化机制,安全人员测试时应关注所有数据处理环节,特别是序列化/反序列化点。