一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java序列化反序列化原理及漏洞解決方案

Java序列化反序列化原理及漏洞解決方案

2020-08-04 23:55大專欄 Java教程

這篇文章主要介紹了Java序列化反序列化原理及漏洞解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

Java序列化

Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節序列,該字節序列包括該對象的數據、有關對象的類型的信息和存儲在對象中數據的類型。

Java反序列化

反序列化就是將字節序列恢復為Java對象的過程

整個過程都是 Java 虛擬機(JVM)獨立的,也就是說,在一個平臺上序列化的對象可以在另一個完全不同的平臺上反序列化該對象,因此可以實現多平臺之間的通信、對象持久化存儲,主要有如下幾個應用場景。

HTTP:多平臺之間的通信,管理等

RMI:是 Java 的一組擁護開發分布式應用程序的 API,實現了不同操作系統之間程序的方法調用。值得注意的是,RMI 的傳輸 100% 基于反序列化,Java RMI 的默認端口是1099端口。

JMX:JMX 是一套標準的代理和服務,用戶可以在任何 Java 應用程序中使用這些代理和服務實現管理,中間件軟件 WebLogic 的管理頁面就是基于 JMX 開發的,而 JBoss 則整個系統都基于 JMX 構架。

系列化反序列化基礎

序列化和反序列化本身并不存在問題。但當輸入的反序列化的數據可被用戶控制,那么攻擊者即可通過構造惡意輸入,讓反序列化產生非預期的對象,在此過程中執行構造的任意代碼。

一個類的對象能夠序列化的成功需要兩個條件

  • 該類必須實現 java.io.Serializable 接口
  • 該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須注明是短暫的。

漏洞基本原理

簡單的反序列化Demo

首先定義對象類Persion,包含兩個參數

?
1
2
3
4
5
6
7
public class implements java.io.Serializable{
  public String name;
  public int age;
  public void info(){
    System.out.println("Name:"+this.name+";nAge:"+this.age);
  }
}

在主類中聲明對象,并且將對象序列化為二進制文件,將其存儲到硬盤中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.*;
 
public class Main{
  public static void main(String [] args){
    將對象序列化為二進制文件
    Persion p = new Persion();
    p.name = "Joner";
    p.age = 18;
    try {
 
      //打開一個文件輸入流
      FileOutputStream fileOut = new FileOutputStream("D:\test\test.db");
      //建立對象輸入流
      ObjectOutputStream out = new ObjectOutputStream(fileOut);
      //輸出反序列化對象
      out.writeObject(p);
      out.close();
      fileOut.close();
      System.out.printf("保存成功");
    }catch(IOException i){
      i.printStackTrace();
    }
}

進行反序列化

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.*;
 
public class Main{
  public static void main(String [] args){
    /*從二進制文件中提取對象*/
    Persion persion = null;
    try{
      FileInputStream fileInputStream = new FileInputStream("D:\test\test.db");
      //建立對象輸入流
      ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
      persion = (Persion) inputStream.readObject();
      inputStream.close();
      fileInputStream.close();
    }catch (ClassNotFoundException c){
      System.out.println("對象未找到");
      c.printStackTrace();
      return;
    } catch (FileNotFoundException e) {
      e.printStackTrace();
      return;
    } catch (IOException e) {
      e.printStackTrace();
      return;
    }
    System.out.println("反序列化對象.......");
    System.out.println("Name:"+persion.name);
    System.out.println("Age:"+persion.age);
    }
}

查看test.db文件的內容可以看見如下內容

其中 AC ED 00 05 是java 序列化內容的特征,其中00 05 是版本信息,base64編碼后為ro0AB

反序列化漏洞Demo

在上面的Demo中可以看到,進行反序列化時會調用readObject()方法,如果readObject方法書寫不當就會引發漏洞。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.*;
 
public class Main{
  public static void main(String [] args)throws Exception{
    Unsafeclass unsafeclass = new Unsafeclass();
    unsafeclass.name = "hhhhh";
    FileOutputStream fileOutputStream = new FileOutputStream("object");
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
    //將對象寫入object文件
    objectOutputStream.writeObject(unsafeclass);
    objectOutputStream.close();
 
    //從文件中反序列化對象
    FileInputStream fileInputStream = new FileInputStream("object");
    ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
    //恢復對象
    Unsafeclass objectFormDisk = (Unsafeclass)objectInputStream.readObject();
    System.out.println(objectFormDisk.name);
    objectOutputStream.close();
  }
}
class Unsafeclass implements Serializable{
  public String name;
  //重寫readObject()方法
  private void readObject(java.io.ObjectInputStream inputStream ) throws IOException , ClassNotFoundException{
    //執行默認的readObdect()方法
    inputStream.defaultReadObject();
    //執行打開計算器命令
    Runtime.getRuntime().exec("calc.exe");
  }
}

程序運行過程為:

  • UnsafeClass類背序列化進入object文件
  • 從object文件中恢復對象
  • 調用被恢復對象的readObject()方法
  • 命令被執行

這樣看感覺并不會有人會這樣寫readobject()這個方法,而且一些成熟的框架都會有防范反序列化的方法,但仍有很大比例的反序列化漏洞,這主要是使用了不安全的庫造成的。上面只是介紹了簡單的Java反序列化過程,接下來會有一篇文章介紹反序列化漏洞檢測方法以及復現一些經典反序列化漏洞。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.dazhuanlan.com/2020/06/12/5ee3439045cce/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91传媒在线观看 | 国产精品免费小视频 | 欧美一区二区三区视视频 | 免费xxxxx大片在线观看影视 | 免费369看片入口 | 免费一级毛片在线播放放视频 | 成人夜视频寂寞在线观看 | 好大好硬好深好爽想要之黄蓉 | 视频网站入口在线看 | 欧美日韩中文国产一区二区三区 | 欧美猛男同志同性video | 亚洲欧美另类在线观看 | 91日本在线 | 91探花在线播放 | 被黑人同学彻底征服全文小说阅读 | 亚洲免费小视频 | 秋葵丝瓜茄子草莓榴莲樱桃 | 美女扒开尿口让男生添 漫画 | 国产亚洲精品自在线亚洲情侣 | 免费一级国产大片 | pregnantxxx孕交 | 午夜一个人在线观看完整版 | 四虎影院网址大全 | 高清不卡免费一区二区三区 | 99久久99热久久精品免 | 欧美视频一区二区三区在线观看 | 天天干天天色综合网 | 九九九九九热 | 成人午夜视频一区二区国语 | 国产一卡二卡3卡4卡四卡在线 | 高清在线观看mv的网址免费 | 久久久无码精品亚洲欧美 | 国产nv精品你懂得 | 久青草国产观看在线视频 | 国产一区二区三区久久精品 | 成人性生交小说免费看 | 黑人破中国女人处 | 日本成年片高清在线观看 | cos美女被黄网站 | 奇米色88欧美一区二区 | 四虎影院在线免费播放 |