利用 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/

分享到: