Apache HTTP 0.9 compatible

When sending the ASCII control character null (hexadecimal 00) in the query string of an URI, IIS returns a 400 (Bad Request). Tomcat passes the null to the web application. But Apache returns a HTTP entity (the HTML code), but no HTTP headers. Additionally the URI is truncated (the null and everything after it is missing).

If you have a local apache running, try this python script (you need to have a index.html or index.php in your root directory):

import urllib2
print 'Valid request:'
print urllib2.urlopen('http://localhost/?abc=123&def=456_VALID').read()
print ''
print 'Invalid request:'
print urllib2.urlopen('http://localhost/?abc=123'+chr(0)+'&def=456_INVALID').read()

If you watch it with wireshark you will see that the answer to the second request has no HTTP headers. The apache access.log will look like this:

::1 - - [09/Jun/2010:16:44:41 +0200] "GET /?abc=123&def=456_VALID HTTP/1.1" 200 321 "-" "Python-urllib/2.6"
::1 - - [09/Jun/2010:16:44:41 +0200] "GET /?abc=123" 200 94 "-" "-"

Eric Covener of the apache project:

The null in the invalid URL causes the request line to be terminated before the rest of the URL or the protocol. The response (no headers) is “HTTP 0.9” described here:

http://www.w3.org/Protocols/HTTP/AsImplemented.html

You can find my (invalid) bug report here. I think this can only be used for web server fingerprinting. Or if there is a client (e.g. a browser) that sends the null character as well, there might be some changes for header injection.

New Injection Vector for PHP

I was thinking about a new injection vector for PHP. It exploits the possibility of arrays in GET/POST parameters. I want to show it with a XSS example. Imagine the following code in a PHP script (e.g. index.php):

<?php
//if $_GET['id'] is an array this means (string)$_GET['id'] is "Array"
//and obviously there is no "<" in "Array"...
//strpos returns false if '<' is not in $_GET['id']
if(strpos($_GET['id'],"<") === false)
   someLibraryEchoBack($_GET['id']);
else
   echo "&lt; is not allowed";

function someLibraryEchoBack($value){
   if(is_array($value)){
      foreach($value as $key => $string)
         echo $string;
   }
   else
      echo $value;
}
?>

The script would have the following output:

URI HTML Response
/index.php?id=<h2>A</h2> &lt; is not allowed
/index.php?id[]=<h2>A</h2> <h2>A</h2>

Anyone ever heard of this? At least you get some funny PHP errors for some web applications…

Update: Of course there are already exploits with this kind of attack.

Typo3 encryptionKey

A colleague of mine found a URL in a typo3 homepage that looked pretty strange (HTML tags in GET parameters). After searching through the web we found out that a MD5 sum is calculated over these parameter values. Each time you send this GET request, you have to send the correct MD5 sum. The problem is that an encryptionKey is used as a salt!

This feature is described on line 156 to 164 in this typo3 source file. After searching a while I found a page that already offers a tool to crack typo3’s encryptionKey. Because the script only supports dictionary files and searching for default encryption keys, I wrote my own script to brute force the key. I really wonder if the encryption key is strong enough. My server has nothing to do anyway (this is a offline attack!) so the script is running there…

EDIT: I read the whole encryption key thing again and I think my brute force approach is maybe not the best thing. But on the other side I tested Chris John Riley’s script and it worked quite well ;).

ehlo floyd.ch

As everything starts once, today it’s my blog. This blog is simply about IT Security stuff.

Today I was wondering how a web server reacts on an URI with a pound sign (#) in it. It took me about 3 hours to realise that it is not possible to send a pound sign with Firefox and WebScarab, even my first try with the perl library did not work. They’re just all too URI RFC 3986 compliant. But python’s urllib2 worked (not urllib)!

http://192.168.1.42:80/echoGetParameters.php?abc=123#ABC
http://192.168.1.42:8080/echoGetParameters.jsp?abc=123#ABC
http://192.168.1.43:80/echoGetParameters.aspx?abc=123#ABC

Findings: Apache and IIS simply ignore it and everything after it. Apache Tomcat interprets the pound sign as part of the last GET value.

If you want to try it yourself, use Wireshark to watch if the pound sign is really sent! I’m still thinking about an exploit…