S2-046分析(CVE-2017-5638)

0x00 漏洞简介

今天出现了新的S2-46漏洞,看了下和S2-045漏洞很相似。最终的利用函数也是一样的,具体请参考我之前的分析http://paper.seebug.org/241/

这里,我记录下这个漏洞调试的几个点,和关键地方。

官方公告,请看http://struts.apache.org/docs/s2-046.html

仔细阅读漏洞描述:

Problem
It is possible to perform a RCE attack with a malicious Content-Disposition value or with improper Content-Length header. If the Content-Dispostion / Content-Length value is not valid an exception is thrown which is then used to display an error message to a user. This is a different vector for the same vulnerability described in S2-045 (CVE-2017-5638).

最后一句话很有意思,说是:相同的漏洞,不同的向量。

POC和国外原始文章,请看最后的参考文章。重要信息和原理都在里面了,可以详细阅读下~

漏洞描述明确了以下方面:

  • 通过Content-Dispostion / Content-Length这两个header头,注入OGNL语言,进而执行命令。
  • 最后的利用点和S2-045一样

0x01 漏洞复现

经过我的重现加上官方描述,得到第一种利用方法:

  • 同样不需要找个上传的地方,直接找个action即可~~
  • 利用有条件,配置struts.xml里面的解析器为jakarta-stream

  • 设置Content-Length大于可上传的maxSize。 用来触发错误~

  • filename处,添加OGNL语句,执行命令~~

简单说说复现,Github上下载POC:https://github.com/pwntester/S2-046-PoC~

使用maven运行:mvn jetty:run。使用POC测试即可,返回header中会出现:X-Test: Kaboom

另一种利用方法(空字节),请看参考3,很详细~ 这个就厉害了,没有限制条件和S2-045一致~ 个人觉得非常好,值得研究学习~ 使用和S2-045一样方便,幸好影响版本也一致,用户还是尽快升级到最新版~~

0x01 漏洞关键点调试分析

以下源码版本均为:Struts 2.3.20

第一种方法,调试如下:

通过配置,可以知道在JakartaStreamMultiPartRequest类里面的parse函数下断点~
判断长度大于maxSize后,requestSizePermitted被设置为false,将fileName放到了错误信息中:


看到了buildMessage函数,当然跟进发现又执行了这个函数:LocalizedTextUtil.findText(...);

第二种空字节的利用方法,在commons-fileupload控件的Streams.class中~

获取上传文件的fileName时,它会判断文件名是否有\x00的空字节。如果有,则抛出InvalidFileNameException异常,并且在异常信息中包含了fileName

parse函数捕获异常后,调用了buildErrorMessage函数~~

对于默认配置JakartaMultiPartRequest,同样也捕获异常:

0x02 总结

每次漏洞原理分析,都可以学到许多新的知识~~

0x03 参考

https://community.hpe.com/t5/Security-Research/Struts2-046-A-new-vector/ba-p/6949723#.WNC2Rfl95QK
https://github.com/pwntester/S2-046-PoC
https://gist.github.com/frohoff/a3e24764561c0c18b6270805140e7600