CVE-2017-5644 Apache POI Dos漏洞原理详解
【POI介绍】
Apache POI 是Apache软件基金会的开源项目,POI提供API接口给Java程序对Microsoft office格式文档读写能力。
【POI结构说明】
包名称 说明
HSSF 提供读写Microsoft Excel XLS格式档案的功能。
XSSF 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
Xls和xlsx的区别
Excel有多种文件类型,xls是Excle 2003版本之前使用的文件格式,二进制的文件保存方式。Xlsx和xls就相差一个X字母,这里的X表示XML,相对于XLS,XLSX支持更多的功能,X也有扩展的意思。
Xls支持最大行数65536行,xlsx支持的最大行数为1048676行。
Xls支持的最大列数256列,xlsx支持的最大列数16384列。
XLSX全称 EXCEL Microsoft Office Open XML Format Spreadsheet file . 通过文件编辑器打开XLSX,我们也能看出来,XLSX本质上是一个ZIP格式的文件。
将某个xlsx文件后缀更改为zip,然后用winrar进行解压,可以看到如下目录结构
_rels:资源文件的结构组成,指定了app.xml/core.xml/workbook.xml
docProps: 文档属性文件的定义
xl:excel文件的主要组成部分,样式styles.xml、workbook、sheet等在此处定义。
对xl目录下的文件进行分析
Theme:设置的主题
Worksheets:工作表
shareStrings.xml:该文件定义了所有的常量
workbook.xml:该excel所有工作表的整合
【漏洞原理】
以上大概介绍了XLSX的文件结构,其实DOCX、pptx都有相同的问题。
根据POI官方网站的描述https://poi.apache.org/changes.html
POI3.11 版本已经解决了之前版本引入的两个漏洞CVE-2014-3529 、CVE-2014-3574
官方声称已经将Dos漏洞在3.11版本彻底修复。
上一节结束了shareString.xml,该文件主要用于常量字符串的定义,sheet.xml中会对该文件中的常量值进行依赖引用,所有要解析Excel,肯定会先将常量进行解析。
用zip打开excel文件,将sharedStrings.xml修改成
在POI 3.11之前的版本,在解析此XLSX时,会造成DOS攻击。
<lolz>&lol9;</lolz>代表引用ENTITY lol9,而ENTITY lol9由10个lol8组成,每个lol8又是由10个1ol7组成,所以将会一直的递归,次数会达到10^9。循环大量的实体引用,会消耗大量的CPU资源,长时间显示占用100%。
一旦不能限制外部提交的xlsx文档,并且使用了低版本的POI,会造成DOS攻击。
不过经过我们的研究,3.11之后的版本并没有彻底的解决Dos漏洞。
我在调试POI3.14版本时,使用了上面的payload,出现了以下的报错。
控制台返回的信息告诉我们,POI在解析XLSX时,并没有循环解析内部实体,而是直接报错了,如果看的不细心的话,可能会忽略这个漏洞,误以为防护成功。
从上图可以看出,POI对实体的大小进行了限制,当实体的大小超出了expandLimit=4096 时,会抛出异常。这和我的预期是不一样的,我希望的是它能限制循环嵌套引用的次数,而不是实体大小。于是我们将上面的payload稍作修改
Lol被设置为空字符。
重新提交xlsx,服务器宕机。
【问题代码】
语法分析器PiccoloLexer.yylex 中:
当yy_action 值为38时,会调用 reportCdata函数,最终会判断 entityBytesLimit 实体的大小限制,为4096。
但是我们将 payload中的 <!ENTITY lol ""> 时,yy_action 始终不为38,无法进入reportCdata函数,也无法进行大小判断,成功的实施了Dos攻击。
【结论】
虽然3.11之后的版本对之前的Dos漏洞进行了修复,但是没有修复彻底,只是判断引用后的实体大小来防止DOS攻击,这种方法是失效的,问题的根本是我们因为限制它实体的引用次数。
【影响版本】
POI-3.15,POI-3.16不受影响,此外所有的POI版本都受到影响(这是官方给出的结论)。
【影响范围】
POI使用场景非常广泛,2016-04-15 POI-3.15.jar才面世,很多互联网公司以及我司产品都在使用3.14之前的版本。鉴于本漏洞影响广泛,希望各个产品及时升级版本。
【小插曲】
这个漏洞在去年的产品渗透测试中就发现了,也和陈辉军讨论过,不过我们一直没有提,主要是考虑到POI已经发布了新的版本3.15,并不存在此漏洞,而且也觉得别人不一定会认这个漏洞,今年在给某产品做渗透时,又有人提POI的问题,就尝试给Apache官方提交了这个漏洞,POI Team 及时的确认问题,并公开致谢。
- 点赞
- 收藏
- 关注作者
评论(0)