21.java反序列化-弹出控制面板
21.java反序列化-弹出控制面板
在 Java 反序列化过程中,恶意代码的执行通常是通过自定义的 readObject
方法来实现的。
反序列化的执行流程
-
对象实例化:在反序列化过程中,
ObjectInputStream
会创建一个新的对象实例。这个实例的创建是通过ObjectStreamClass
的newInstance
方法完成的,它通常使用Unsafe.allocateInstance()
来分配内存空间,而不是调用构造函数。 -
字段初始化:在对象实例被创建后,
ObjectInputStream
会通过反射来设置对象的字段值。 -
调用
readObject
方法:如果类定义了自定义的readObject
方法,ObjectInputStream
会调用该方法。这是执行自定义逻辑的地方,包括恶意代码。
反序列化过程,为什么构造函数不被调用
- 默认行为:在反序列化过程中,Java 序列化机制使用
Unsafe.allocateInstance()
来创建对象实例,这绕过了构造函数的调用。 - 自定义逻辑:自定义的
readObject
方法是在对象实例被创建之后调用的,用于初始化对象的字段。因此,任何需要在反序列化过程中执行的逻辑(包括恶意代码)都应该放在readObject
方法中。
代码
首先,我们定义一个恶意类 MaliciousClass
,它实现了 Serializable
接口,并包含一个自定义的 readObject
方法,用于执行恶意代码。
接下来,我们创建一个主函数类 Main
,用于序列化和反序列化 MaliciousClass
对象。
import java.io.*;class MaliciousClass implements Serializable {public MaliciousClass() {System.out.println("调用MaliciousClass的无参构造函数");}// 自定义的 readObject 方法private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {in.defaultReadObject(); // 默认反序列化System.out.println("调用MaliciousClass自定义的readObject函数");// 模拟恶意行为try {Runtime.getRuntime().exec("control.exe"); // 打开控制面板} catch (IOException e) {e.printStackTrace();}}
}public class Main {public static void main(String[] args) {System.out.println("---创建对象+序列化----");// 序列化恶意对象try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("malicious.ser"))) {oos.writeObject(new MaliciousClass());System.out.println("Malicious object serialized to malicious.ser");} catch (IOException e) {e.printStackTrace();}System.out.println("---反序列化----");// 反序列化恶意对象try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("malicious.ser"))) {ois.readObject(); // 反序列化时会执行 readObject 方法中的恶意代码} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}
代码说明
-
MaliciousClass
:- 实现了
Serializable
接口,使其可以被序列化和反序列化。 - 定义了一个自定义的
readObject
方法,用于在反序列化时执行恶意代码。在这个例子中,恶意代码是打开计算器。
- 实现了
-
Main
:- 包含一个
main
方法,用于执行序列化和反序列化操作。 - 使用
ObjectOutputStream
将MaliciousClass
对象序列化到文件malicious.ser
。 - 使用
ObjectInputStream
从文件malicious.ser
反序列化对象,从而触发readObject
方法中的恶意代码。
- 包含一个
运行结果
弹出控制面板
注意事项
- 安全性:在生产环境中,反序列化不受信任的数据可能导致严重的安全漏洞。因此,务必在反序列化之前验证数据的来源和完整性。
- 执行恶意代码:在实际应用中,应避免反序列化不受信任的数据。
总结
- 构造函数:在反序列化过程中,构造函数不会被调用。
readObject
方法:自定义的readObject
方法是执行反序列化逻辑的地方,包括恶意代码。- 安全性:在反序列化不受信任的数据时,始终要小心,因为
readObject
方法可以执行任意代码。
通过这种方式,攻击者可以利用反序列化漏洞来执行任意代码。因此,在处理不受信任的输入时,确保使用安全的反序列化机制和验证措施。