IPS Evasion with the Apache HTTP Server
This post is the first in a series on IPS evasion techniques. The intent is describe the strange behaviors of network applications and demonstrate the evasion capabilities of the BPS-1000 product.
Microsoft's IIS web server gets a bad rap by security vendors, due to the mind-boggling number of ways an attacker can encode a valid HTTP request. IIS's support for Unicode encoding, case-insensitive file names, and interchangeable path separators have created a series of annoying problems for IPS, IDS, and web application proxy developers. As of June 2007, nearly all vendors in this space have some solution for normalizing HTTP requests destined for IIS web servers.
The Apache Foundation's HTTP server, by contrast, is largely standards compliant and is quite picky about what types of requests it will accept. This has made life comparatively easy for developers trying to normalize HTTP requests destined for Apache web servers. Unfortunately, two quirks in the Apache request parsing code can be abused to evade many commercially-available IPS products.
The first issue relates to how Apache handles invalid request methods with CGI and PHP scripts. By default, Apache allows all methods, even invalid methods, to be used in requests to access dynamic content. For example, if we have an Apache web server with mod_php installed, and create a script called test.php in the web root, each of the following requests would be considered valid and result in test.php being accessed:
- GET /test.php HTTP/1.0
- POST /test.php HTTP/1.0
- HELLO /test.php HTTP/1.0
- GET%20/%20HTTP/1.0%0A%0D /test.php HTTP/1.0
- \r\n\r\n\r\n\r\n\r\n\r\n\r\n /test.php HTTP/1.0
The second issue has been covered before, but still affects most commercial IPS products. In a normal HTTP request, the first line consists of the request method, followed by a space, followed by the URI, followed by a space, followed by the HTTP version. The HTTP RFC states that instead of an ASCII space character (0x20), the horizontal tab character (0x09) is also valid as a separator. The Apache web server, instead of just looking for either 0x20 or 0x09, will process 0x09, 0x0b, 0x0c, 0x0d, and 0x20 as valid separators. Since many IPS products only recognize 0x20 and 0x09, they are not able to decode HTTP requests containing these alternate whitespace characters.
I raised this issue just over one year ago on the Daily-Dave mailing list and described it again it during my Black Hat 2006 presentation with Brian Caswell. Since that time, the Snort HTTP preprocessor has been updated to properly decode these requests (look for the apache_whitespace and whitespace_chars options). Unfortunately, many commercial IPS vendors have not updated their products to detect this evasion technique. One vendor added support for 0x0d, but forgot to check for 0x0b or 0x0c. The end result is that the following requests may not be properly decoded by many vendors:
- GET\x0c/test.php HTTP/1.0
- GET\x0b/test.php HTTP/1.0
- GET\x0d/test.php HTTP/1.0
In the examples above, we used invalid HTTP methods and non-standard whitespace characters to prevent an IPS product from properly decoding a request for /test.php. In most cases, these techniques will work for real attacks, such as an attempt to exploit a buffer overflow in a CGI or trigger a remote file include vulnerability in a PHP script. The BreakingPoint BPS-1000 supports these evasion techniques through the following parameters in the HTTP option group, accessible from the Parameter view of the Attack Manager:
- MethodRandomInvalid: Use randomly-generated request methods
- URIPrependAltSpaces: Use alternate whitespace characters before the URI
- URIPrependAltSpacesSize: The number of alternate whitespace characters to prepend
- URIAppendAltSpaces: Use alternate whitespace characters after the URI
- URIAppendAltSpacesSize: The number of alternate whitespace characters to append
Alternatively, BPS-1000 users can create a new test, add a Security component, select Targeted Attack, and choose the HTTP: Apache High Evasion preset from the Attack Profile drop-down.

