CVE-2017-7659 Apache Vulnerability Reproduce

Apache released fix for CVE-2017-7659 last month. It is a mod_http2 Null Pointer Dereference vulnerability. Here is my analysis.

First check the patch for this vulnerability:

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

As we can see, fix just add check return value of function h2_request_rcreate.

reproduce:

First, download apache version 2.4.25: https://archive.apache.org/dist/httpd/httpd-2.4.25.tar.gz. compile it and enable http2. I wrote a bash script to do download and configure it. After that use curl to verify if http2 is ready to go

curl -v --http2 http://192.168.79.136

when you see HTTP/1.1 101 Switching Protocols, that means http2 is good to go.

now in burp send http request:

1
2
3
4
5
6
GET / HTTP/1.0
User-Agent: curl/7.47.0
Accept: */*
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAMAAABkAAQAAP__

The server doesn’t response.

Analysis

First check vulnerable function h2_stream_set_request_rec (in httpd-2.4.25/modules/http2/h2_stream.c)

function h2_stream_set_request_rec calls h2_request_rcreat is used to create http 2.0 request. req will be null when h2_request_rcreat fails. In this situation, log function ap_log_rerror will use req which leads process crash.

next, exam function h2_request_rcreate (in httpd-2.4.25/modules/http2/h2_request.c).

it will set req vaule as NULL, then it will check value of r->method, scheme, r->hostname, path. If any of them is null will return fail. However, at this moment, req vaule is 0 which leads to crash.

Method, scheme and path are checked. So r->hostname is our winner.

in HTTP request, there are two methods can have host name.

(1) in URL. Like: http://fuckyou.com/shit.html. Function ap_parse_uri will handle host value in this request. (2) in HTTP header. Function fix_hostname will handle this.

check function ap_read_request (in httpd-2.4.25/server/protocol.c)

if r->hostname is empty and http request version is great than 1.1 or http version == 0 without host will return http400. But it doesn’t check one situation: when http version is 1.0 and without hostname value. That is the problem.

Debug

See reference how to debug apache: https://httpd.apache.org/dev/debugging.html

set break point in function ap_read_request,

run the poc. it will hit break point at ap_read_request, h2_stream_set_request_rec

continue, it will hit break point at h2_stream_set_request_rec

as we can see, it is in mod_http2.so.

(not finish)