CVE-2017-7659 (Apache Vulnerability)

Recently, apache released the latest security bulletin on its website , which involves multiple vulnerabilities. The introduction to the CVE-2017-7659 vulnerability is as follows:

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

It can be seen that this is a HTTP 2.0 protocol processing vulnerability in the apache WEB server (httpd). Security researchers of Weiran Lab have conducted in-depth research on the technical details and utilization methods of this vulnerability, and security enthusiasts are welcome to share and discuss together.

0x01 Patch Analysis

The vulnerability can be found on redhat's bugzilla:

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

There is a fix commit for this vulnerability on github:

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

The code differences before and after the modification are compared as follows:

It can be seen that the repair content is very simple, that is, the judgment of the return value of the h2_request_rcreate function is added. The official recommendation is to upgrade to 2.4.26 to fix the vulnerability.

0×02 Vulnerability Cause

After downloading the vulnerable server code from https://archive.apache.org/dist/httpd/httpd-2.4.25.tar.gz , reverse the cause of the vulnerability by modifying the patch.

First look at the vulnerability function h2_stream_set_request_rec, and find that it calls h2_request_rcreat to create the data structure req of the http 2.0 request. When the execution of h2_request_rcreat fails, the req is empty. At this time, dereferencing the req directly in the log function ap_log_rerror causes the process to crash:

Continue to view the function h2_request_rcreate, see that req will be set to 0 first, and then judge the four variables r->method , scheme , r->hostname , path , if any one is empty, it will return failure, and at this time req is still 0, just will cause the process to crash:


So which of these 4 variables is the vulnerability caused by being empty? The scheme is to first determine whether it is empty and then assign it, and exclude it first; the path is parsed from r->parsed_uri, the parsing function apr_uri_unparse is used many times in other places, and the intuitive path will not be empty; r->method is saved The method field of the request must exist in the HTTP request, so it should not be empty; therefore, only r->hostname, which saves the requested hostname, that is, the domain name, may be empty.

We know that in an HTTP request, there are 2 places where the hostname can be represented:

1) The path of the request is expressed as a complete URL, and the URL contains the host name, such as GET  http://www.example.com/  HTTP/1.1, where the host name is www.example.com . The server parses this hostname in the ap_parse_uri function

2) Include the hostname in the Host request header, for example:

GET / HTTP/1.1

Host: www.example.com

The server resolves this hostname in the fix_hostname function

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

这里的判断逻辑,如果满足下面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:

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


验证POC

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

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


将构造的POC通过burpsuite发送:


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


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


漏洞利用

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

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

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

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


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


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函数中:

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


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

0×05总结

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

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

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

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324845129&siteId=291194637