作者:獵戶安全實驗室
公眾號:https://mp.weixin.qq.com/s/SJPXdZWNKypvWmL-roIE0Q
0x00 漏洞概覽
漏洞名稱:Spring Integration Zip不安全解壓
漏洞編號:CVE-2018-1261
漏洞級別:嚴重(官方定級,比高危還高)
漏洞危害:在spring-integration-zip.v1.0.1.RELEASE之前的版本中,惡意用戶通過在壓縮文件中構造包含有特定文件名稱的文件(受影響文件格式有bzip2, tar, xz, war, cpio, 7z),應用程序使用spring-integration-zip進行解壓時,會導致跨目錄任意寫入文件漏洞的攻擊。進而有可能被Getshell,遠程控制。
漏洞加固:更新升級,zip.v1.0.2.RELEASE版本
漏洞利用前置條件:
使用了spring-integration-zip庫
接收并解壓了來自不可信來源的壓縮文件
0x01 漏洞分析
補丁比對

zip.v1.0.1.RELEASE在UnZipTransformer調用ZipUtil.iterate()時定義的回調中增加了一段對文件名稱校驗的代碼片段(在5月11日凌晨更新的zip.v1.0.2.RELEASE版本中,對Byte[]類型的分支邏輯也增加了文件名稱校驗,并且刪除了對名稱中..的判斷,直接校驗名稱是否以工作區目錄開頭)。
通過上述內容我們大致可以猜測這個漏洞的原理:攻擊者可以通過構造一個包含名稱帶../前綴的文件的壓縮包,使spring-integration-zip進行解壓時該文件跳出解壓目錄被創建。
而且在zip.v1.0.1.RELEASE也增加了對這類壓縮包的測試用例,并且十分貼心的附上了一個“惡意”的壓縮包測試文件zip-malicious-traversal.zip。
我們先看看這個壓縮包長什么樣子:

稍微說明一下:
右上,壓縮包正常打開的目錄結構
右下,壓縮包的文本形式數據
左,壓縮包解壓后的目錄結構
從文本數據中不難看出,這個壓縮包中存在一個以很多../開頭為名稱的文件evil.txt。以壓縮工具打開查看時,它以目錄樹形式顯示,而解壓后最深層的有效目錄及文件被提取至根目錄(說明使用的這個工具不存在這類解壓漏洞)。
這樣就可以很清楚的知道,這個壓縮包如果被zip.v1.0.0.RELEASE解壓,evil.txt文件將會被寫入工作區目錄對應盤符下的tmp目錄中。
搭個調試環境跑起來看看。
0x02 環境搭建
IDE:IDEA
JDK:1.7
Libraries
spring-integration-zip.1.0.0.RELEASE
spring-integration-core.4.3.10.RELEASE
spring-integration-file.4.3.10.RELEASE
zt-zip.1.11
關鍵代碼如下(參考官方測試用例即可):

流程跟蹤
流程很簡單,示例中的UnZipTransformer.transform()會調用doZipTransform()解壓,在遍歷壓縮包內目錄及文件時,回調ZipEntryCallback.process()對其進行處理。
當遍歷到evil.txt時,它被識別為一個文件,而并不是多層的目錄結構,那一堆亂七八糟的只是它的文件名:

而對正常壓縮包遍歷到目錄時應該是這樣的:

然后根據文件名在工作區目錄中創建對應文件(子目錄會在遍歷時被提前創建),并調用org.apache.commons.io包中的IOUtils.copy()復制文件數據。
此時,解壓的文件名被轉換為絕對路徑:

程序運行結束,查看E:\tmp\目錄下發現evil.txt文件(由于Win操作系統默認沒有/tmp目錄,因此我在測試前提前創建了一個,也可以直接使用已存在目錄,如Web Root:P):

0x03 POC生成
知道了漏洞原理后,我們比較好奇的是如何生成這種特殊的壓縮文件,已知方法有(如果有更方便的方法,請告訴我):
用二進制數據構造符合壓縮包數據結構的文件
使用spring-integration-zip壓縮
我們用方法2做個測試,關鍵代碼如下:


再解壓試試

可以看到hw.txt跳出解壓目錄外層來了,OK,打完收工。
參考
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/598/