Apache CVE-2017-7659漏洞重现及利用分析

2017-07-07 +10 680290人围观 ,发现 10 个不明物体 漏洞

近日,apache在其网站发布了最新的安全公告,其中涉及多个漏洞。针对CVE-2017-7659漏洞的介绍是这样的:

A maliciously constructedHTTP/2 request could cause mod_http2 to dereference a NULL pointer and crashthe server process.

可以看到这是apache WEB服务器(httpd)中的一个HTTP 2.0协议处理的漏洞。未然实验室安全研究人员针对此漏洞的技术细节和利用方法进行了深入的研究,欢迎安全爱好者们一起分享和讨论。

0×01补丁分析

在redhat的bugzilla上可以找到该漏洞:

https://bugzilla.redhat.com/show_bug.cgi?id=1463199

在github上有对该漏洞的修复提交:

https://github.com/apache/httpd/commit/672187c168b94b562d8065e08e2cad5b00cdd0e3

修改前后的代码差异比较如下:

1.png

可以看到,修复内容很简单,就是增加了对h2_request_rcreate函数返回值的判断。官方推荐升级到2.4.26修复漏洞。

0×02漏洞成因

https://archive.apache.org/dist/httpd/httpd-2.4.25.tar.gz下载到有漏洞的服务器代码后,通过补丁的修改进行漏洞成因的逆向分析。

首先查看漏洞函数h2_stream_set_request_rec,发现是调用h2_request_rcreat创建http 2.0请求的数据结构req,h2_request_rcreat执行失败时req为空,此时在日志函数ap_log_rerror中直接解引用req导致进程崩溃:

2.png

继续查看函数h2_request_rcreate,看到首先会把req置为0,然后判断4个变量r->method,scheme,r->hostname,path,任何一个为空则返回失败,而此时req还是0,就会导致进程崩溃:

3.png

那么这4个变量是哪一个为空导致的漏洞呢?scheme是先判断了是否为空再赋值的,首先排除;path是从r->parsed_uri中解析出来,解析函数apr_uri_unparse在其它地方有多次使用,直觉path也不会为空;r->method保存请求的方法字段,在HTTP请求中必须存在,因此也不应该为空;因此只有r->hostname,保存请求的主机名,也就是域名,可能为空。

我们知道,HTTP请求中,有2个地方可以表示主机名:

1) 请求的路径以完整URL方式表示,URL中包含主机名,例如GET http://www.example.com/ HTTP/1.1,这里主机名就是 www.example.com。服务器中是在ap_parse_uri函数中解析这种主机名的

2) 在Host请求头中包含主机名,例如:

GET / HTTP/1.1

Host: www.example.com

服务器中是在fix_hostname函数中解析这种主机名的

分别审计ap_parse_uri和fix_hostname函数,发现如果请求中没有Host头,那么r->hostname确实是空。但是服务器也考虑到了这种情况,在ap_read_request函数中做了判断:

4.png

这里的判断逻辑,如果满足下面2个条件之一

1) r->hostname为空,且请求的HTTP版本大于等于1.1

2) 没有Host头,且请求的HTTP版本等于1.1

就会立刻回复400状态码的错误页面,并不会触发后面的漏洞。在注释里也说明了,HTTP/1.1的RFC2616的14.23节中明确指明,HTTP/1.1请求必须包含Host头。

但是,开发者是不是忘了什么,HTTP还有1.0版本啊,且HTTP/1.0和HTTP/1.1的处理流程一样,虽然HTTP/1.0确实没有规定请求必须包含Host头。因此HTTP/1.0请求是可以没有Host头的,程序会一直按照流程执行,最终执行到h2_stream_set_request_rec函数,此时r->hostname为空,从而触发漏洞。

0×03漏洞验证及漏洞利用

综合上面的分析,该漏洞利用成功需要如下条件:

1) 服务器支持HTTP/2

2) 请求是HTTP/1.0版本

3) 请求中没有Host头

服务器配置

在server上要配置开启HTTP/2功能,使用apache默认的站点配置,在配置文件中首先加载mod_http2.so:

5.png

然后加入下面配置,重新启动apache httpd就可以了:

6.png

验证POC

验证时,我们首先起一个单一进程的apache httpd服务,方便验证进程崩溃后的效果:

7.png

正常访问,返回欢迎页面:

8.png

将构造的POC通过burpsuite发送:

9.png

果然超时没有响应,同时在服务器上发现httpd进程已经崩溃:

10.png

再次访问服务器时,页面已经无法访问了:

11.png

漏洞利用

在上一节,我们已经验证了在单一进程模式下,如何通过该漏洞导致apache服务器异常终止。但是通常情况下apache服务器在启动时,会同时启动多个工作进程:

12.png

而且当worker进程崩溃时,apache会自动启动新的worker进程。那么在真实的网络环境中,黑客会如何利用此漏洞对服务器进行攻击呢?

我们尝试编写了一个多线程(并发100个线程)的程序,同时发起多个畸形请求,以不断触发后台worker崩溃,并让apache服务器不断陷入重新分配worker的处理之中:

13.png

执行脚本时,发起的请求:

14.png

请求发起后,我们发现,并不需要特别的并发连接,便可以让服务器进入拒绝服务状态:

15.png

0×04 漏洞影响

在apache的漏洞公告中,只有2.4.25版本的httpd服务器受此漏洞影响。但是根据未然实验室的测试,从2.4.17开始的所有版本的httpd服务器,受到这段POC攻击时都会崩溃,而httpd也是从2.4.17版本开始支持HTTP 2.0协议的。因此可以说这个漏洞会影响httpd的所有支持HTTP 2.0的版本,未然实验室强烈建议用户更新到最新的2.4.26版本。

2.4.25之前的版本代码与2.4.25版本不尽相同,以2.4.17为例,在h2_request_rwrite函数中:

16.png

收到攻击POC后,r->hostname为空,因此req->authority也为空,而ap_strchr_c其实通过下面的宏进行定义的:

17.png

因此在上面的函数中,调用strchr的第一个参数为空,此时会导致进程崩溃。

0×05总结

apache在其HTTP Server 2.4.26版本修复了多个漏洞,业界普遍认为这些漏洞比较鸡肋,难以利用。未然实验室挑选其中个别漏洞进行了深入的分析和利用尝试,发现其中有些漏洞其实影响还是很大,尤其是对于一些高价值站点。

本文讨论的部分方法可能会造成目标网站拒绝服务,影响目标网站的业务正常运行,所以请勿对真实目标进行尝试,否则由此引起的一切后果未然实验室概不负责。

水平所限,文章内容难免有不足之处,欢迎大家指正。您可通过未然实验室公共邮箱weiran.labs@huawei.com或关注我们的微信公众号“WeiRanLabs”与我们联系,期待与各位专家交流。

*本文作者:华为未然实验室,转载请注明来自FreeBuf.COM

这些评论亮了

  • 楼主分析很精致啊,每一步都配图,非常详细。连我这种小白看完,都基本能够对着步奏操作一把。
    不得不说,楼主不但技术好,活好,文笔也nice,文章结构清晰。
    是难得的一篇漏洞分析好文。
    话说连 apache 都被你们逼的下海了,你们未然实验室难道想上天?!
    )15( 亮了
发表评论

已有 10 条评论

取消
Loading...
华为未然实验室

未然实验室是华为网络产品线下属专业安全团队,实验室聚焦主流攻防技术研究和安全知识的普及,秉承“安全需防患于未然”的安全理念,致力于网络空间的安全治理,希望通过我们的努力,为用户提供一流的安全产品和服务。

11 文章数 14 评论数

特别推荐

关注我们 分享每日精选文章

css.php