0基礎反序列化

0x01:
一、什麼是序列化與反序列化?
Java序列化是指把 Java 對象轉換爲字節序列的過程;
Java反序列化是指把字節序列恢復爲 Java 對象的過程;
漏洞挖掘位置:白盒(以實際情況做參考)
0x02:
一個類的對象要想序列化成功,必須滿足兩個條件:
1:該類必須實現 java.io.Serializable 接口。
2:該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須註明是短暫的。
0x03:
需要用到jdk反序列化API
使用關鍵類
ObjectOutputStream(對象輸出流),ObjectInputStream(對象輸入流)
ObjectOutputStream(對象輸出流)類中:通過使用writeObject(Object object) 方法,將對象以二進制格式進行寫入。
ObjectInputStream(對象輸出流)中:通過使用 readObject()方法,從輸入流中讀取二進制流,轉換成對象。
0x04
我們創建一個 User 類,實現 Serializable 接口,並生成一個版本號

import java.io.Serializable;

public class User implements Serializable {

private static final long serialVersionUID = 3604972003323896788L;//序列號,確定版本一致
private transient int age;
private String name;
private String sex;

public int getAge() {
    return age;
}

public String getName() {
    return name;
}

public String getSex() {
    return sex;
}

public void setAge(int age) {
    this.age = age;
}

public void setName(String name) {
    this.name = name;
}

public void setSex(String sex) {
    this.sex = sex;
}

}
Serializable 接口的作用只是用來標識我們這個類是需要進行序列化,並且 Serializable 接口中並沒有提供任何方法。

SerialVersionUid 序列化版本號的作用是用來區分我們所編寫的類的版本,用於判斷反序列化時類的版本是否一直,如果不一致會出現版本不一致異常。

transient 關鍵字,主要用來忽略我們不希望進行序列化的變量

0x05:
定義一個Person類,實現Serializable接口

import java.io.Serializable;

public class Person implements Serializable {

private static final long serialVersionUID = -5809452578272945389L;
private int age;
private String name;
private String sex;
public void setName(String name) {
    this.name = name;
}
public void setAge(int age) {
    this.age = age;
}
public void setSex(String sex) {
    this.sex = sex;
}

public String getName() {
    return name;
}

public int getAge() {
    return age;
}

public String getSex() {
    return sex;
}

}

0x06:
序列化和反序列化test類對象

import java.io.*;
import java.text.MessageFormat;

//

Description: 測試對象的序列化和反序列


public class test {
public static void main(String[] args) throws Exception {
SerializePerson();//序列化
//反序列Perons對象
Person p = DeserializePerson();
System.out.println(MessageFormat.format("name={0},age={1},sex={2}",p.getName(), p.getAge(), p.getSex()));
}
private static void SerializePerson() throws FileNotFoundException, IOException { //Description: 序列化Person對象
Person person = new Person();
person.setName("gal");
person.setAge(25);
person.setSex("sasa");
// person.setSex("calc.exe");
// ObjectOutputStream 對象輸出流,將Person對象存儲到E盤的Person.txt文件中,完成對Person對象的序列化操作
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("/Person.txt"));
oo.writeObject(person);

    System.out.println("Person對象序列化成功!");
    oo.close();
}
private static Person DeserializePerson() throws Exception, IOException {     //Description: 反序列Perons對象

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Person.txt"));
    Person person = (Person) ois.readObject();//

// System.out.println("Person對象反序列化成功!");
Runtime.getRuntime().exec("calc.exe");
return person;
}

}


漏洞危害 (遠程命令/代碼執行漏洞)

使用參考轉載來源文檔
實現了Serializable的類中的serialVersionUID是幹什麼用的
https://blog.csdn.net/fengqing5578/article/details/103120738
什麼是反序列化 如何實現java反序列化 Serializable作用
https://blog.csdn.net/qq_35868412/article/details/86978141
深入理解JAVA 反序列化漏洞(Seebug Paper)https://paper.seebug.org/312/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章