Sunday, September 11, 2011

Disabling TRACK / TRACE in Apache

Currently, Apache does not deny TRACE requests (per RFC2616) by default. Therefore, when an HTTP TRACE request is sent to a web server that supports it, that server will respond echoing the data that is passed to it, including any HTTP headers. By definition, HTTP TRACE method ask a web server to echo the contents of the request back to the client for debugging purposes. The complete request, including HTTP headers, is returned in the entity-body of a TRACE response. An example of the response of Apache when TRACE is enabled,

# telnet myserver.com 80
Trying 10.10.10.10...
Connected to myserver. (10.10.10.10).
Escape character is '^\]'.
TRACE / HTTP/1.0
Host: myserver.com
TestA: Hello
TestB: World\\

HTTP/1.1 200 OK
Date: Tue, 19 Jul 2011 10:31:38 GMT
Server: Apache
Connection: close
Content-Type: message/http

TRACE / HTTP/1.0
Host: myserver.com
TestA: Hello
TestB: World

Connection closed by foreign host.
The output in the 2nd and 3rd paragraph is actually the response from Apache with the exact data sent in the 1st paragraph. Status code of 200 indicate that TRACE request is allowed and hence this response. It is possible for the attackers prepare carefully crafted page to trick a browser on a user’s box to issue the TRACE request and after which pass on the cookies or authentication data to the attacker. TRACE requests can be disabled by making a change to the Apache server configuration. There are 2 methods to achieve this 1) Setting “TraceEnabled off” in httpd.conf This is only available for Apache 1.3.34, 2.0.55 and 2.2.x. 2) Using rewrite to deny TRACE request in all the vhost. This can be used universally in all the Apache versions. You can deny TRACE requests for both HTTP and HTTPS depending on your business system requirement and using either method depending on your Apache version. For example, using method 2 to disable TRACE support in Apache, here’s the example in the configuration file httpd.conf. For this purpose I have added additional lines to capture the log when the rules are invoked. After note: Apache version 1.3.34, 2.0.55 and 2.2.x and newer, please use option 1. The rest will use option 2 on all the pair.

    Servername myserver.com
    ErrorLog logs/myserver-error.log
    CustomLog logs/myserver-access.log common

    Block TRACE/TRACK XSS vector
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} \^TRAC(E\|K)*
    RewriteRule .\* - \[F\]*
    RewriteLogLevel 9
    RewriteLog logs/rewrite_log
 
After TRACE support is disabled, below is the rerun of the TRACE request.
# /usr/local/apache2/conf>telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^\]'.
TRACE / HTTP/1.0
Host: myserver.com
TestA: Hello
TestB: World

HTTP/1.1 403 Forbidden{*}
Date: Thu, 21 Jul 2011 08:06:02 GMT
Server: Apache
Content-Length: 202
Connection: close
Content-Type: text/html; charset=iso-8859-1

<\!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

403 Forbidden

Forbidden

You don't have permission to access / on this server. Connection to localhost closed by foreign host.
We can see that Apache now response with a 400 series status code which indicate client request was denied. Output of the log shown below when the rewrite rules are invoked.
10.10.10.10 - - [21/Jul/2011:17:09:34 +0800] [myserver.com/sid#552add28f8][rid#552b2f0bf8/initial] (2) init rewrite engine with requested uri /
10.10.10.10 - - [21/Jul/2011:17:09:34 +0800] [myserver.com/sid#552add28f8][rid#552b2f0bf8/initial] (3) applying pattern '.*' to uri '/'
10.10.10.10 - - [21/Jul/2011:17:09:34 +0800] [myserver.com/sid#552add28f8][rid#552b2f0bf8/initial] (4) RewriteCond: input='TRACE' pattern='^TRAC(E\|K)' => matched
10.10.10.10 - - [21/Jul/2011:17:09:34 +0800] [myserver.com/sid#552add28f8][rid#552b2f0bf8/initial] (2) forcing '/' to be forbidden
The examples so far shows only for HTTP, XST vulnerability can also be shown for HTTPS where we just use “openssl s_client --connect hostname:port” and using the same commands after the telnet command. Please note that this is not a vulnerability in TRACE, nor in Apache. This is more of a need to harden Apache not to divulge more information than it should.


Reference:
http://www.kb.cert.org/vuls/id/867593
http://www.apacheweek.com/issues/03-01-24

No comments: