Skip to content

Latest commit

 

History

History
62 lines (50 loc) · 4.42 KB

File metadata and controls

62 lines (50 loc) · 4.42 KB

生成 Jetty 命令执行明文回显的字节码(JettyEcho)

  • 类别:bytecode 别名:— 优先级:—
  • 作者:ReaJason
  • 依赖:无(产物为纯字节码,运行时依赖目标环境的 Jetty)

作用

产出一段预写好的 Jetty 回显恶意类字节码:该类被目标 JVM 加载/实例化后,会从当前 Jetty 请求线程上下文中取出 HTTP 请求,读取指定 Header(默认 X-Authorization)作为命令执行,并把结果以明文写回响应,实现「无文件落地」的命令执行回显。是一个链尾字节码 sink(END)。

链接标签

  • 入口 tagsBytecodeEchoEND —— Bytecode 表示本 gadget 的产物是字节码 byte[]Echo 标识其属于回显类载荷;END 表示它是链的终点(sink),其后不再接任何 gadget。
  • 衔接 nextTags:空 —— 作为终点不向后衔接。
  • excludes:无。

作为一段字节码 sink,它通常由上游的「字节码装载器」承接:即前一环需要能吃下 byte[] 并把它 defineClass/实例化,例如 BytecodeConvert 把字节码塞入 TemplatesImpl 再由某个 Java 反序列化跳板触发 newTransformer()

源码剖析

本类逻辑极简,核心是「取一个模板类 + 回填 Header 字段 + 导出字节码」:

@GadgetTags(tags={"Bytecode", "Echo", "END"})
@GadgetAnnotation(name="生成 Jetty 命令执行明文回显的字节码", authors={"ReaJason"})
public class JettyEcho implements Gadget {
    @Param(name="请求头 key", description="执行命令的 Header 头")
    public String header = "X-Authorization";

    public byte[] getObject() throws Exception {
        JavassistHelper javassistHelper = new JavassistHelper(JettyEchoBytecode.class);
        javassistHelper.modifyStringField("header", this.header);
        return javassistHelper.getBytecode();
    }

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

逐段解释:

  • 模板类:真正的回显逻辑写死在 com.ar3h.chains.gadget.impl.bytecode.echo.template.JettyEchoBytecode 中(一个预编译好的 Java 类)。JavassistHelper 以该类为蓝本读入其原始字节码。
  • 字段回填modifyStringField("header", this.header) 通过 Javassist 直接改写模板类里 header 字段的常量初值,把用户配置的 Header 名(如 X-Authorization)写进字节码,从而无需重新编译即可定制「读哪个请求头取命令」。
  • 导出getBytecode() 返回改写后的 byte[],即最终注入目标的恶意类字节。
  • invoke:先 chain.doCreate(context) 触发内层(本例中链一般为空/收尾),再 getObject()。注意本 gadget 只产出字节码,不负责让目标加载它——加载动作由上游装载器(如 TemplatesImpldefineTransletClasses)完成。

由于回显逻辑固定在模板类,本条目不涉及运行时反射构造,其安全语义完全取决于 JettyEchoBytecode 模板在被加载时会执行的操作(取 Jetty 请求线程的 request/response、读 Header、Runtime.exec 并写回响应)。

参数(@Param)

字段 名称 说明 默认 可选值
header 请求头 key 恶意类从该 Header 读取待执行命令 X-Authorization 任意字符串

适用版本与原理要点

  • 适用于运行 Jetty 的目标(回显逻辑针对 Jetty 的请求上下文获取方式定制)。
  • 属于「回显」类:无需外连、无需落地文件,命令与结果都走同一个 HTTP 请求/响应,隐蔽性高。
  • 本 gadget 只生成字节码,必须搭配能把 byte[] 变成「被加载的类」的上游装载器才能真正触发。

所属预设链

usedInChains 为空——自由构件,未直接出现在 51 条预设链中。作为回显 sink,可替换任意「命令执行 sink」(如 Exec)用于回显场景。

关联

  • 上游(吃 Bytecode 的装载器):BytecodeConvertTemplatesImpl 等字节码装载跳板。
  • 同族(其它中间件回显字节码 sink):TomcatEchoResinEchoWebLogicEchoUndertowEchoGlassFishEcho 等,均以相同的「模板类 + JavassistHelper 回填」方式产出,仅回显逻辑针对各自中间件不同。