概述?
序列化與反序列化時相對於對象來說的,在很多應用中讓他們需要將存在內存中的對象離開內存,從而進入硬盤以便長期保存。例如在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️⃣ 修復建議
?對反序列所調用的函數進行審覈檢查.