### BCEL 可以用其他类加载器吗

### BCEL 与类加载器的关系

Java 类加载器（`ClassLoader`）负责在运行时将 `.class` 文件加载到 JVM 中。当一个类加载器加载字节码时，它会调用 `defineClass()` 方法，这个方法接受原始的字节码数据（一个字节数组），并将其转换为一个可用的 `Class` 对象

BCEL 正是在这个过程中发挥作用的。

- 步骤 1：恶意字节码生成：攻击者使用 BCEL 或其他字节码操作库，编写一段恶意的 Java 代码，例如一个可以执行系统命令的 Shellcode。然后，将这段 Java 代码编译成原始的字节码数组
- 步骤 2：编码和传输：为了绕过一些安全过滤，攻击者会使用 BCEL 提供的编码功能，将这个字节码数组编码成一个字符串。这种编码格式以 `$**BCEL$$` 开头，比如 `$**BCEL$$` + Base64 编码的字节码
- 步骤 3：利用类加载器：攻击者找到一个存在漏洞的应用程序，该程序在处理用户输入时，会使用一个可以加载并执行字节码的类加载器。攻击者将前面编码好的 BCEL 字符串作为输入发送给应用程序
- 步骤 4：解码和加载：应用程序在处理这个字符串时，会调用 `sun.misc.BASE64Decoder`（或其他解码器）来解码这个字符串，将其还原成原始的字节码数组。然后，应用程序会使用一个类加载器，调用其 `defineClass()` 方法，将这个字节码加载到内存中
- 步骤 5：反射执行：一旦恶意字节码被加载成 `Class` 对象，攻击者就可以通过反射，调用其 `newInstance()` 方法来创建实例，并执行其中的恶意代码，从而实现远程代码执行

为什么需要其他类加载器？

BCEL 漏洞利用链之所以成立，正是因为它间接利用了应用程序自身的类加载器。攻击者不需要自己上传一个类加载器，而是利用应用程序中已有的、可以加载字节码的类

例如，在一些特定的 Java 框架和库中，存在一些可以加载并执行字节码的类，比如：

- `com.sun.org.apache.bcel.internal.util.ClassLoader`：这是 Java 内部自带的一个类加载器，它能够直接从 BCEL 编码的字符串中加载类
- 自定义的类加载器：一些应用程序为了实现动态加载功能，可能会编写自己的类加载器。如果这些加载器没有做安全校验，同样可以被利用