Serializable
- date
- 2023-09-10 12:08:13
序列化与反序列化
序列化是将对象转换成数据字节流,反序列化时将数据字节流转换为对象。
序列化的是为了进程之间对象的传递。发送方将对象序列化为字节流,接收方从字节序列中恢复出对象完成传递。
在 Java 中,要对一个对象进行序列化,其必须实现 Serializable 接口。
接口 Serializable 用来标识当前类可以被 ObjectOutputStream 序列化,以及被 ObjectInputStream 反序列化。
| import java.io.Serializable;
// Person 类实现 Serializable 接口, 空接口, 不需要实现方法
public class Person implements Serializable {
public String name;
public int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void print(){
System.out.println("name:"+ name);
System.out.println("age:"+ age);
}
}
|
序列化
| import java.io.*;
public class SerializeDemo {
public static void main(String[] args) {
Person person = new Person("fuming",18);
try {
// 创建一个输出流来写入文件
FileOutputStream fileOut = new FileOutputStream("person.ser");
// 创建一个对象输出流
ObjectOutputStream out = new ObjectOutputStream(fileOut);
// 序列化对象
out.writeObject(person);
// 关闭流
out.close();
fileOut.close();
System.out.println("对象已经被序列化并保存在 person.ser 文件中");
} catch (IOException e) {
e.printStackTrace();
}
}
}
|
这里将序列化的对象写入文件流中,.ser 用来表示这是一个序列化文件。
反序列化
创建一个输入流,读取序列化文件,然后将字节流反序列化为对象。
| import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializeDemo {
public static void main(String[] args) {
try {
// 创建一个输入流来读取文件
FileInputStream fileIn = new FileInputStream("person.ser");
// 创建一个对象输入流
ObjectInputStream in = new ObjectInputStream(fileIn);
// 反序列化对象
Person person = (Person) in.readObject();
// 关闭流
in.close();
fileIn.close();
// 输出反序列化后的对象
person.print();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
|
漏洞原理
Java 反序列化漏洞跟 PHP 其实是一样的,或者说反序列化漏洞的成因都是一样的:应用程序对攻击者可控的数据进行反序列化操作。
漏洞检测
黑盒测试可以通过 Java 反序列化特征自己或字符串:
- Base64 :
rO0AB
- 16 进制:
0xac ed 00 05
白盒测试可直接搜索 readObject 方法,再看其输入是否可控。
漏洞利用
Java 反序列化漏洞的利用往往需要组合多个不同的 Serializable 接口实现类的方法调用,形成复杂的调用链。
在 Java 安全领域,习惯称之为反序列化利用链,也叫 Gadget Chain。
前人已经挖掘出了很多的利用链,他们对 Java 标准库以及各种常见的第三方库组件做了大量研究,最终找到了许多可以实现远程代码执行的反序列化利用链,这些利用链以及集成到了著名的 Java 反序列化利用工具 ysoserial 中。
项目地址:https://github.com/frohoff/ysoserial