利用 EXCEL 文件進行 XXE 攻擊的漏洞分析

語言: CN / TW / HK

最近在閲讀安全類文章時看到有同學分享如何利用excel進行XXE攻擊,閲讀後發現一些模糊的利用方式。由於漏洞場景非常常見,讓我十分感興趣,並決定一探究竟。注意本文驗證僅用於學習與研究,請勿非法利用。

背景知識

Microsoft Office從2007版本引入了新的開放的XML文件格式,新的XML文件格式基於壓縮的ZIP文件格式規範,由許多部分組成。我們可以將其解壓縮到特定的文件夾中來查看其包含的文件夾和文件,可以發現其中多數是描述工作簿數據、元數據、文檔信息的XML文件。

Poi-ooxml.jar的XXE漏洞

Apache POI是提供Microsoft Office系列文檔讀、寫功能的JAVA類庫,Apache POI 3.10-FINAL及以前版本被發現允許遠程攻擊者通過注入XML外部實體讀取任意文件。

漏洞編號

CVE-2014-3529

影響範圍

poi-ooxml-3.10-FINAL.jar及以下版本

利用文件

[Content-Types].xml

漏洞利用

新建test.xlsx進行解壓縮,得到以下文件:

打開[Content-Types].xml注入外部實體:

保存後壓縮回test.xlsx文件: 

編寫解析程序執行,發現報錯:

此時ceye上已產生記錄: 

漏洞分析

調用鏈

所列函數的調用順序從上到下: 

class="org.apache.poi.xssf.usermodel.XSSFWorkbook" method="XSSFWorkbook()" class="org.apache.poi.util.PackageHelper" method="open()" class="org.apache.poi.openxml4j.opc.OPCPackage" method="open()" class="org.apache.poi.openxml4j.opc.OPCPackage" method="getParts()" class="org.apache.poi.openxml4j.opc.ZipPackage" method="getPartsImpl()" class="org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager" method="ZipContentTypeManager()" class="org.apache.poi.openxml4j.opc.internal.ContentTypeManager" method="ContentTypeManager()" class="org.apache.poi.openxml4j.opc.internal.ContentTypeManager" method="parseContentTypesFile()"

關鍵函數

程序執行至getPartsImpl()函數中匹配出了[Content-Types].xml文件,並文件數據流傳入至ZipContentTypeManager中: 

ZipContentTypeManager調用ContentTypeManager()函數,ContentTypeManager()函數中把數據傳入了parseContentTypesFile()函數進行處理:

parseContentTypesFile()函數未進行XXE漏洞防護,直接對XML數據進行解析:

至此,漏洞觸發。

修復方案

升級poi-ooxml.jar到3.16或以上版本。

看到這裏,有同學會問,為什麼我在閲讀其他文章時發現,文章描述的利用方式不是[Content-Types].xml文件,而是另外的xml文件呢?彆着急,下面我們繼續另一個漏洞分析。

xlsx-streamer.jar的XXE漏洞

當Excel中的數據量較大時,在用Apache POI讀取文件流時很容易引起失敗,需要引入xlsx-streamer來進行資源的解析。而xlsx-streamer的2.0.0及以下版本被發現允許遠程攻擊者通過注入XML外部實體讀取任意文件。

影響範圍

xlsx-streamer.jar-2.0.0及以下版本

利用文件

xl/workbook.xml

漏洞利用

新建1.xlsx進行解壓縮,得到以下文件: 

打開xl/workbook.xml注入外部實體: 

保存後壓縮為2.xlsx文件:

編寫解析程序執行,發現報錯: 

此時ceye上已產生記錄:

漏洞分析

調用鏈

所列函數的調用順序從上到下: 

class="com.monitorjbl.xlsx.StreamingReader" method="open()" class="com.monitorjbl.xlsx.impl.StreamingWorkbookReader" method="init(InputStream is)" class="com.monitorjbl.xlsx.impl.StreamingWorkbookReader" method="init(file f)" class="org.apache.poi.xssf.eventusermodel.XSSFReader" method="getWorkbookData()" class="com.monitorjbl.xlsx.XmlUtils" method="document()"

關鍵函數

程序使用用户傳入的xlsx文件內容重新生成一個臨時文件,並使用XSSFReader解析文件: 

然後在getWorkbookData()函數中會取到xl/workbook.xml文件流傳入document()函數: 

document()函數未對XXE攻擊進行防禦,直接解析XML文件: 

至此,漏洞觸發。

修復方案

升級xlsx-streamer.jar到2.1.0版本

總結

除上述兩個第三方庫本身的漏洞外,系統開發人員在編寫代碼解析xlsx文件時,也有可能導致XXE漏洞。如CVE-2016-5000是在Poi-examples.jar的某個示例中被發現的XXE漏洞。感興趣的同學可再進行進一步的研究。

參考文章

https://www.cnblogs.com/zlcom/archive/2013/09/21/3332060.html http://www.zhutougg.com/2018/11/13/excel-streaming-reader-xxelou-dong/

分享到: