Skip to content

Latest commit

 

History

History
57 lines (47 loc) · 4.57 KB

File metadata and controls

57 lines (47 loc) · 4.57 KB

自定义字节码-本地文件(BytecodeFromLocalFile)

  • 类别:bytecode 别名:— 优先级:200
  • 作者:Ar3h
  • 依赖:无(仅需 JVM 与 Javassist 工具类)

作用

从磁盘上的一个 .class 文件读取原始字节码,作为链尾的「字节码源」交给上游的字节码加载器(如 TemplatesImpl)去 defineClass 并实例化。用于让使用者投递完全自定义的恶意类,而不局限于工具内置的 Exec/DNSLog 等模板。

链接标签

  • 入口 tags
    • Bytecode —— 声明本 gadget 产出「原始字节码 byte[]」,可被 nextTags=Bytecode 的加载器(BytecodeConvert)承接。
    • BytecodeConvertTag —— 同时声明自己可占据「字节码转换器」这一槽位,因此也能被 nextTags=BytecodeConvertTag 的加载型 gadget(如 TemplatesImpl 段)直接承接,省去中间的 BytecodeConvert 处理环节。
    • END —— 链终止标签,本 gadget 是最内层 sink,之后不再有内层对象。
  • 衔接 nextTags:空 —— 它自身就是字节码源头,不再向内包裹。
  • excludes:无。

源码剖析

核心逻辑集中在 getObject

public byte[] getObject(GadgetContext context) throws Exception {
    byte[] bytecode = FileHelper.fileGetContent(this.path);      // 从本地路径读原始 .class 字节
    JavassistHelper javassistHelper = new JavassistHelper(bytecode);
    context.put(ContextTag.CLASS_NAME_KEY, javassistHelper.getClassName()); // 把类名写入上下文
    return javassistHelper.getBytecode();                        // 返回(经 Javassist 归一化的)字节码
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    chain.doCreate(context);          // 触发内层(通常为空/END),保持接口约定
    return this.getObject(context);
}

关键点:

  • FileHelper.fileGetContent(this.path) 直接把攻击者机器上的 .class 文件读成 byte[],内容不做任何加工,因此使用者可以放入任意逻辑(内存马、回显、自定义命令执行等)。
  • new JavassistHelper(bytecode) 仅用于解析类名——javassistHelper.getClassName() 取出该字节码里声明的真实类名,并通过 context.put(ContextTag.CLASS_NAME_KEY, ...) 写入 GadgetContext。上游加载器(TemplatesImpl_name、或 XSLT/BCEL 装载点)需要这个类名才能正确 newInstance(),这一步是本 gadget 能被「即插即用」的关键。
  • invokechain.doCreate(context) 的返回值被丢弃——因为本类携带 END 标签,理论上没有内层对象;该调用仅为遵守 Gadget 接口的「由内向外」构建约定。

BytecodeConvert 的分工:BytecodeConvert 会对内层字节码做改类名、实现 AbstractTranslet 接口、插桩、混淆等加工;而本 gadget 不加工,原样返回,依赖使用者自行保证 .class 已满足目标加载点的接口要求(例如若配合 TemplatesImpl,字节码需已继承 AbstractTranslet)。正因如此它同时挂了 BytecodeConvertTag,可直接顶替转换器位置。

参数(@Param)

字段 名称 说明 默认 可选值
path 本地.class字节码文件路径 攻击者本地待读取的 .class 文件绝对/相对路径 任意路径字符串

适用版本与原理要点

  • 从 description:「从文件中读取字节码,适用于自定义字节码场合,增加了工具拓展性」。
  • 不依赖任何第三方库,只要 JVM 能加载该字节码即可;字节码本身的版本/接口约束由使用者负责。
  • 常见坑:若目标加载点是 TemplatesImpl,自定义类必须继承 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet,否则 newTransformer() 阶段会抛异常——此时应改走 BytecodeConvert 让其自动补接口。

所属预设链

自由构件,未直接出现在 51 条预设链中。作为「自定义字节码」入口,供使用者在需要投递专属 payload 类时手动替换掉内置的 Exec/DNSLog sink。

关联

  • 同族(自定义字节码源):BytecodeFromUploadFile(改为从上传的 Base64 读取)。
  • 上游加载器(承接 Bytecode/BytecodeConvertTag):BytecodeConvertTemplatesImpl
  • 功能对位的内置 sink:ExecDNSLog 等(它们产出模板字节码,本 gadget 产出使用者自带字节码)。