概述?
序列化与反序列化时相对于对象来说的,在很多应用中让他们需要将存在内存中的对象离开内存,从而进入硬盘以便长期保存。例如在web服务器中session对象中,当有10万用户并发访问的时候,就有10万个session对象,此时内存可能吃不消,于是web容器就把一些session先序列化到硬盘中,等再要用的时候再再硬盘中反序列到内存中。
1️⃣ 序列化
⚪️ 从概述上来看序列化就是将对象永久序列化保存于硬盘中的一个文件中,或者在网络上传输时将对象序列化为二进制流字节序列来传输的一种技术
⚪️ java进行序列化一般调用java.io.Serializable接口,在Java类中启用可序列化。ObjectOutputStream代表对象输出流,他的writeObject(object obj)方法可以对指定的参数进行序列化
public class Student implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4353290429541109039L;
private String name;
public Student(String name){
this.name = name;
}
public String toSting(){
return "my name is " + name;
}
public static void main(String[] args) throws Exception{
Student student = new Student("ramboo");
File file = new File("D:"+ File.separator+"text_0922.txt");
ObjectOutputStream oos = null;
OutputStream out = new FileOutputStream(file);
oos = new ObjectOutputStream(out);
oos.writeObject(student);
oos.close();
}
2️⃣ 反序列化
?反序列化就是调用函数使字节流转换为对象的过程
ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
public static void main(String[] args) throws Exception{
File file = new File("D:"+ File.separator+"text_0922.txt");
ObjectInputStream ois = null;
InputStream input = new FileInputStream(file);
ois = new ObjectInputStream(input);
Student student = (Student)ois.readObject();
System.out.println("==>:"+student.toSting());
ois.close();
}
3️⃣ 反序列化漏洞
?反序列化漏洞,就是程序传送了不安全的反序列化对象,并且程序没有对此不安全的对象做过滤及限制,导致执行了不安全的对系统造成破坏性的操作。
例如上面如果序列化的是
private void readObject(ObjectInputStream stream)
throws Exception{
Object runTime=Class.forName("java.lang.Runtime")
.getMethod("getRuntime",new Class[]{})
.invoke(null);
Class.forName("java.lang.Runtime")
.getMethod("exec", String.class)
.invoke(runTime,"regedit");
}
那么反序列化的时候就会运行regedit,打开注册表了.
4️⃣ 实例 ?
⚪️正常序列化:在硬盘下生成序列化的文件
⚪️正常反序列化:将在硬盘下序列化的文件反序列化为对象
⚪️在要序列化的文件中写入定制的函数,不仅仅执行了正常反序列的函数还执行了恶意调用的函数
5️⃣ 修复建议
?对反序列所调用的函数进行审核检查.