利用 EXCEL 檔案進行 XXE 攻擊的漏洞分析
最近在閱讀安全類文章時看到有同學分享如何利用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/