CVE-2017-5644 Apache POI Dos漏洞原理详解

举报
st小龙 发表于 2018/03/19 10:00:00 2018/03/19
【摘要】 这个漏洞在去年的产品渗透测试中就发现了,也和陈辉军讨论过,不过我们一直没有提,主要是考虑到POI已经发布了新的版本3.15,并不存在此漏洞,而且也觉得别人不一定会认这个漏洞,今年在给某产品做渗透时,又有人提POI的问题,就尝试给Apache官方提交了这个漏洞,POI Team 及时的确认问题,并公开致谢。

POI介绍】

Apache POI Apache软件基金会的开源项目,POI提供API接口给Java程序对Microsoft office格式文档读写能力。 

POI结构说明】

包名称                       说明

HSSF                            提供读写Microsoft Excel XLS格式档案的功能。

XSSF                             提供读写Microsoft Excel OOXML XLSX格式档案的功能。

Xlsxlsx的区别

Excel有多种文件类型,xlsExcle 2003版本之前使用的文件格式,二进制的文件保存方式。Xlsxxls就相差一个X字母,这里的X表示XML,相对于XLSXLSX支持更多的功能,X也有扩展的意思。

Xls支持最大行数65536行,xlsx支持的最大行数为1048676行。

Xls支持的最大列数256列,xlsx支持的最大列数16384列。

XLSX全称  EXCEL Microsoft Office Open XML Format Spreadsheet file . 通过文件编辑器打开XLSX,我们也能看出来,XLSX本质上是一个ZIP格式的文件。

将某个xlsx文件后缀更改为zip,然后用winrar进行解压,可以看到如下目录结构

1a.jpg


_rels:资源文件的结构组成,指定了app.xml/core.xml/workbook.xml

docProps: 文档属性文件的定义

xlexcel文件的主要组成部分,样式styles.xmlworkbooksheet等在此处定义。

xl目录下的文件进行分析

2a.jpg


Theme:设置的主题

Worksheets:工作表

shareStrings.xml:该文件定义了所有的常量

workbook.xml:该excel所有工作表的整合

【漏洞原理】

以上大概介绍了XLSX的文件结构,其实DOCXpptx都有相同的问题。

根据POI官方网站的描述https://poi.apache.org/changes.html

POI3.11 版本已经解决了之前版本引入的两个漏洞CVE-2014-3529 CVE-2014-3574

3a.jpg


官方声称已经将Dos漏洞在3.11版本彻底修复。

上一节结束了shareString.xml,该文件主要用于常量字符串的定义,sheet.xml中会对该文件中的常量值进行依赖引用,所有要解析Excel,肯定会先将常量进行解析。


zip打开excel文件,将sharedStrings.xml修改成

4a.jpg


POI 3.11之前的版本,在解析此XLSX时,会造成DOS攻击。

<lolz>&lol9;</lolz>代表引用ENTITY lol9,而ENTITY lol910lol8组成,每个lol8又是由101ol7组成,所以将会一直的递归,次数会达到10^9。循环大量的实体引用,会消耗大量的CPU资源,长时间显示占用100%

一旦不能限制外部提交的xlsx文档,并且使用了低版本的POI,会造成DOS攻击。

不过经过我们的研究,3.11之后的版本并没有彻底的解决Dos漏洞。

我在调试POI3.14版本时,使用了上面的payload,出现了以下的报错。

5a.jpg

控制台返回的信息告诉我们,POI在解析XLSX时,并没有循环解析内部实体,而是直接报错了,如果看的不细心的话,可能会忽略这个漏洞,误以为防护成功。

888.jpg

从上图可以看出,POI对实体的大小进行了限制,当实体的大小超出了expandLimit=4096 时,会抛出异常。这和我的预期是不一样的,我希望的是它能限制循环嵌套引用的次数,而不是实体大小。于是我们将上面的payload稍作修改

1w.jpg

Lol被设置为空字符。

重新提交xlsx,服务器宕机。

【问题代码】

语法分析器PiccoloLexer.yylex 中:

7a.png

8a.jpg

yy_action 值为38时,会调用 reportCdata函数,最终会判断 entityBytesLimit 实体的大小限制,为4096

但是我们将 payload中的  <!ENTITY lol ""时,yy_action 始终不为38,无法进入reportCdata函数,也无法进行大小判断,成功的实施了Dos攻击。

【结论】

虽然3.11之后的版本对之前的Dos漏洞进行了修复,但是没有修复彻底,只是判断引用后的实体大小来防止DOS攻击,这种方法是失效的,问题的根本是我们因为限制它实体的引用次数。

【影响版本】

POI-3.15POI-3.16不受影响,此外所有的POI版本都受到影响(这是官方给出的结论)。

【影响范围】

POI使用场景非常广泛,2016-04-15 POI-3.15.jar才面世,很多互联网公司以及我司产品都在使用3.14之前的版本。鉴于本漏洞影响广泛,希望各个产品及时升级版本。

【小插曲】

这个漏洞在去年的产品渗透测试中就发现了,也和陈辉军讨论过,不过我们一直没有提,主要是考虑到POI已经发布了新的版本3.15,并不存在此漏洞,而且也觉得别人不一定会认这个漏洞,今年在给某产品做渗透时,又有人提POI的问题,就尝试给Apache官方提交了这个漏洞,POI Team 及时的确认问题,并公开致谢。

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。