Skip to content

Latest commit

 

History

History
56 lines (46 loc) · 3.99 KB

File metadata and controls

56 lines (46 loc) · 3.99 KB

将byte[]字节码转换为BCEL字符串(BcelConvert)

  • 类别:common 别名:— 优先级:20
  • 作者:—
  • 依赖JDK8 < 8u251(依赖 com.sun.org.apache.bcel.internal.util.ClassLoader 类)

作用

把下游产出的 byte[] 字节码转换为 BCEL 格式的类名字符串(形如 $$BCEL$$$l$8b$I$…)。该字符串被上游的 com.sun.org.apache.bcel.internal.util.ClassLoader.loadClass(...) 加载时,会被解码回字节码并 defineClass,从而完成类加载/RCE。是「字节码 → BCEL 类名字符串」的转换构件。

链接标签

  • 入口 tagsBCEL_ExprExpression
    • BCEL_Expr —— 特指 BCEL 类名字符串,供以 BCEL ClassLoader 加载类的上游 gadget 承接。
    • Expression —— 通用表达式/字符串标签。
  • 衔接 nextTagsBytecodeConvertTag —— 之后接一个提供 byte[] 字节码的 gadget(BytecodeConvert 及其变体)。
  • excludes:无。

源码剖析

@GadgetTags(tags={"BCEL_Expr", "Expression"}, nextTags={"BytecodeConvertTag"})
public class BcelConvert implements Gadget {
    private String getObject(byte[] obj) {
        try {
            return PayloadHelper.makeBCELStr(obj);          // 核心:字节码 -> BCEL 字符串
        } catch (IOException e) {
            ThrowsUtil.throwGadgetException(e);
            return null;
        }
    }

    @Override
    public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
        return this.getObject((byte[])chain.doCreate(context));  // 取内层字节码并转换
    }
}
  • 逻辑极简:invoke 通过 chain.doCreate(context) 取到内层 gadget 产出的 byte[] 字节码(通常是 BytecodeConvert 包装的 TemplatesImpl/Exec 恶意类字节码),交给 getObject
  • getObject 调用 PayloadHelper.makeBCELStr(obj) 完成转换:BCEL 编码会先对字节码做 gzip 压缩,再按 BCEL 的 Utility.encode 规则转为 ASCII 字符串,并加上 $$BCEL$$ 前缀。返回的字符串本质是一个「可被 BCEL ClassLoader 识别并还原成类」的伪类名。
  • 上游的 BCEL 加载 sink(如 LazyValueWithBcelTransformerWithBcelXMLBceLoader)拿到该字符串后,通过 com.sun.org.apache.bcel.internal.util.ClassLoaderloadClass 触发 createClass → defineClass,恶意类的静态块/构造器即被执行。

关键点:本 gadget 不加载类,只做「字节码 → BCEL 字符串」编码;类加载动作由上游 BCEL ClassLoader 型 sink 触发。

参数(@Param)

本类无 @Param 可配参数;字节码由下游 BytecodeConvert 提供。

适用版本与原理要点

  • 依赖 JDK 内置的 com.sun.org.apache.bcel.internal.util.ClassLoader,该类在 JDK 8u251 之后被移除,故仅适用于 JDK8 < 8u251priority=20)。
  • 属 java-chains 的一类「表达式/字节码 Convert」构件,与 AviatorConvertGroovyConvert 等并列,负责把字节码适配到不同的类加载 sink。
  • 防御视角:升级 JDK 至 8u251+ 即可消除 BCEL ClassLoader;检测点为流量中出现 $$BCEL$$ 字符串特征。

所属预设链

  • JDK原生BCEL链[ProxyLazyValueUIDefaults, LazyValueWithBcel, BcelConvert, BytecodeConvert, Exec])——本 gadget 位于 LazyValueWithBcel(BCEL 加载 sink)与 BytecodeConvert(字节码源)之间,负责把 Exec 的字节码编码成 BCEL 字符串交给 LazyValueWithBcel 加载。

关联

  • 上游(nextTags=BCEL_Expr,消费本 gadget 产物):LazyValueWithBcelTransformerWithBcelXMLBceLoaderFastjsonBasicDataSourceFastjsonBasicDataSourcemybatis
  • 下游(tags=BytecodeConvertTag):BytecodeConvertBytecodeFromBase64BytecodeFromHexBytecodeFromLocalFileBytecodeFromUploadFile
  • 同类 Convert 构件:AviatorConvertGroovyConvertElConvertSpelConvert