Wednesday, March 30, 2011

web server version obfuscation

It seems that it's harder then I thought.
Suppose we don't want version leakage through http headers, like:

$ curl -v "http://www.microsoft.com"
...
< Server: Microsoft-IIS/7.5
< X-AspNet-Version: 2.0.50727
...

What we can do is:
  • to change php.ini option expose_php
  • to look at apache's ServerTokens, ServerSignature, TraceEnable options 
  • to "fix" nginx strings in source file src/http/ngx_http_header_filter_module.c (ver. 0.7.x) and src/http/ngx_http_special_response.c (look for NGINX_VER)
  • to make custom error page. Looks like the easiest way but it's also easy to forget about error pages other then 404 and 500. 


Suppose this examples:

 curl -v http://example.com/404doc
...
< HTTP/1.0 404 Not Found
< Server: Apache
< X-Powered-By: PHP/4.3.9

Apache? No, not really. Let's look at err 400.

$ telnet example.com 80
...
Escape character is '^]'.
sdf
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>some garbage instead of nginx version</center>
</body>
</html>
Connection closed by foreign host.


telnet freebsd.org 80
Trying 69.147.83.40...
Connected to freebsd.org.
Escape character is '^]'.
sdf

HTTP/1.0 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
Date: Tue, 29 Mar 2011 16:55:45 GMT
Server: httpd/1.4.x Gualala

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>400 - Bad Request</title>
 </head>
 <body>
  <h1>400 - Bad Request</h1>
 </body>
</html>
Connection closed by foreign host.

This response pattern from FreeBSD site leaves no doubt that this is some version of apache.