Author: shilei && redrain@360CERT
I. 背景介绍
II. 漏洞概述
III. 漏洞攻击面影响
影响面
影响版本
修复版本
IV. 修复建议
V. 漏洞详情
简要技术细节
VI. 漏洞利用验证
VII. 时间线
VIII. 参考来源
I. 背景介绍
A security issue was identified in nginx range filter. A specially crafted request might result in an integer overflow and incorrect processing of ranges, potentially resulting in sensitive information leak (CVE-2017-7529).
-- http://mailman.nginx.org/pipermail/nginx-announce/2017/000200.html
2017年7月11日,Nginx在官方公告中称发现了一个范围过滤器中的安全问题,并分配了CVE-2017-7529。通过精心构造的恶意请求能造成整数溢出,对范围值的不当处理会导致敏感信息泄漏。
II. 漏洞概述
当使用Nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header请求,来获取响应中的缓存文件头部信息。在某些配置中,缓存文件头可能包含后端服务器的IP地址或其它敏感信息,从而导致信息泄露。
III. 漏洞攻击面影响
影响面
该漏洞影响所有0.5.6 - 1.13.2版本内默认配置模块的Nginx只需要开启缓,存攻击者即可发送恶意请求进行远程攻击造成信息泄露。
当Nginx服务器使用代理缓存的情况下,攻击者通过利用该漏洞可以拿到服务器的后端真实IP或其他敏感信息。
通过我们的分析判定,该漏洞利用难度低,可以归属于low-hanging-fruit的漏洞。在真实网络攻击中也有一定利用价值。
影响版本
Nginx version 0.5.6 - 1.13.2
修复版本
Nginx version 1.13.3, 1.12.1
IV. 修复建议
官方补丁已经在7月11日发布
http://mailman.nginx.org/pipermail/nginx-announce/2017/000200.html
http://nginx.org/download/patch.2017.ranges.txt
建议受影响用户尽快升级至1.13.3, 1.12.1或及时patch
V. 漏洞详情
简要技术细节
通过查看patch确定问题是由于对http header中range域处理不当造成,焦点在ngx_http_range_parse函数中的循环:
HTTP头部range域的内容大约为Range: bytes=4096-8192
bytes=<start>-<end>,字符串指针p中即为“bytes=”后面的内容
这段代码是要把“-”两边的数字取出分别赋值给start和end变量,标记读取文件的偏移和结束位置。
对于一般的页面文件这两个值怎么玩都没关系。但对于有额外头部的缓存文件若start值为负(合适的负值),那么就意味着缓存文件的头部也会被读取。
一个缓存文件的例子:
如此我们来看看如何构造Range内容才能把start设计为负值。
首先代码中cutoff和cutlim阀量保证了每次直接从串中读取时不会令start或end成负值。那么能令start为负的机会仅在suffix标记为真的小分支中。
因此我们需令suffix = 1,由此可推知Range的内容必然为Range:bytes=-xxx,即省略初始start值的形式。
那么我们可以通过Range中设end值大于content_length(真正文件的长度),这样start就自动被程序修正为负值了。
但是在写利用过程中发现一个问题,若end值很大那么start的绝对值也会很大,会超过缓存文件的起始头部,造成读取失败。若end值不够大,那么换算下来size = end – 1 >= content_length (end > content_length见前文所述),就不能通过循环外面的检测:
这样的话似乎无论设end为何值都无法达成利用了。继续跟进代码发现这个循环是个无条件循环:
尾部为:
也就是说若Range域形如Range: bytes=start-end,start1-end1,…,就还有机会继续完成利用。
我们可以构造一个Range: bytes=-X, -Y
一大一小两个end值,只需要控制前面一个end值小而后一个end值大,从而实现start值和size值皆为负数,控制start值负到一个合适的位置,那么就能成功利用读到缓存文件头部了。
VI. 漏洞利用验证
Nginx 默认模块配置开启缓存:
缓存文件内容如下:
利用漏洞成功读取反向越界读出491字节:
VII. 时间线
2017-7-11 Nginx官方发布安全通告和patch
2017-7-12 360CERT( https://cert.360.cn)完成漏洞分析和利用情况分析
2017-7-13 发布该预警分析通告
VIII. 参考来源
http://mailman.nginx.org/pipermail/nginx-announce/2017/000200.html