Java序列化与反序列化
- 序列化是将对象的状态转换为字节流的过程,通常用于对象的持久化、网络传输或进程间通信。通过实现 Serializable 接口,类表明其对象的状态可以被序列化,而不需要开发人员手动实现序列化的细节。
Java序列化与反序列化方法
序列化:
ObjectOutputStream --> writeObject()
反序列化:
ObjectInputStream --> readObject()
Java序列化与反序列化函数示例
- 这里创建了两个类,一个用来模拟
readObject
函数重写,在示例中把重写部分注释掉了,一个用来执行序列化与反序列化
Person(readObject函数重写)
import java.io.Serializable;
public class Person implements Serializable {
public int age;
public String name;public class Person implements Serializable {
public int age;
public String name;
}
Test(代码执行)
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p=new Person();
p.age=18;
p.name="xiu";
serialize(p,"byy.bin");
System.out.println("反序列化结果:" + deserialize("byy.bin"));
}
public static void serialize(Object obj, String filePath) throws IOException {
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
objectOut.writeObject(obj);
}
}
public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
try (FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
return objectIn.readObject();
}
}
-
运行代码
-
代码结果如图
Java反序列化漏洞
- 反序列化漏洞的主要问题在于,当使用
ObjectInputStream
来反序列化对象时,它会尝试重新构建对象,并调用对象的私有方法、字段初始化等,它可能会定义到一个危险函数,从而对服务器本身造成危害。
举例代码
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Person implements Serializable {
public int age;
public String name;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Runtime.getRuntime().exec("calc");
// 默认的反序列化操作
in.defaultReadObject();
}
}
- 这是对上面Person函数进行了修改,其中对
readObject
函数进行了重写
Runtime.getRuntime()
Runtime.getRuntime()
是 Java 中用于获取运行时对象的方法。Runtime 类提供了与运行时环境相关的一些信息和操作,例如执行系统命令、获取处理器数量等。- 而
Runtime.getRuntime().exec("calc")
就是要执行系统命令弹出计算器。
执行代码:
反序列化漏洞总结
-
反序列化漏洞常见的有PHP和Java反序列化漏洞
-
php 由于自身魔术方法在反序列化过程中自动调用,魔术方法包含恶意代码产生链式调用执行到危险函数的位置
-
Java反序列化漏洞,由于开发者重写了readobject方法,实现了链式调用,调用到了危险函数的位置