Take your %00 and shove it

We've recently been optimizing our Local File Inclusion (LFI) audit engine. Part of that effort has included poking around in different frameworks (php, .NET, java, ruby/rails, python, perl... etc) and seeing how many ways a developer might fall prey to this vulnerability. One of the common ways to leverage this vulnerability is by appending  a null byte (%00, 0x00, ASCIIZ), c-style string terminator, to the end of a parameter that might be susceptible to an LFI vulnerability. Sadly, this type of injection has worked in almost all known major web development languages. Microsoft's .NET is the outlier. While there are currently no known API's that allow null bytes, it has had its fair share of issues in the past (fixed in 2007 KB928365).


So how does this happen? Some common ways this might happen in PHP are shown in the following snipit of code...



In the above code, the developer needs to include some file, or some template, and is using a raw HTTP parameter as the file name. Require/fopen/fpassthru will try to load files relative to the current working directory. However, if an attacker were to specify a full path (such as "/etc/passwd"), PHP would automatically try to read that file directly into memory (and in these cases, reflect it). Of course the PHP process user (usually Apache's user) would need to have access to that file but that doesn't exclude a lot of interesting attacks...


So why did you tell me about the null byte? The null byte trick helps when there is an appended value (like ".template"). A crafty attacker knows that the underlying system functions are all written in C and %00 is the url encoded version of the C string terminator (0x00, ASCIIZ). With this information you can effectively cause the appended value to be ignored. When "/etc/passwd\0.template" is passed to the underlying operating system the null byte (\0) will be interpreted as the end of the string, thus "/etc/passwd" will be loaded as the file. This type of vulnerability is severe. It's well known that this generally leads to arbitrary code execution on the server. Clearly, though, there is an even more immediate problem. Attackers now have complete access to your server-side source code. We've run into this problem so often during penetration tests that we wrote a tool to "mirror" website's source code based on a single LFI vulnerability and the pages we crawled.


You might be saying to yourself now, "Ok. Well thats fine, but I've never seen this. Why would anyone do that?". Well.,hopefully you're not thinking that but it is true that our previous example was fabricated... but Google Code Search doesn't index any of my example code, just real code. I wonder...how I can use this to my benefit?


Google Code is pretty awesome. You can search code with full regexs. (I wonder why I can't do this with Google itself! grr). So given that awesome functionality, here is a quick regex search to automatically find opensource PHP projects that have LFI vulnerabilities.


Of course its not all about PHP. Here are some other common ways we've seen LFI happen...


Here is some Ruby on Rails:



Here is some Java:



This is one snip-it of PHP, an image uploader and resizer, that really suprised me. This was essentially an insecure file upload as well as an LFI.




This all begs the question, why the f*$k do web development languages still forward these strings directly into the libc versions? Stefan Esser figured this out years ago when he was creating a the Hardened PHP project (althought not bullet proof as Esser points out himself). Hardened PHP has included file system wrappers that will not allow null bytes to be injected into underlying OS system calls. In fact, this was reported to PHP as early as 2001 in their bug database, but have chosen to ignore this for whatever reason. I have no idea why a developer would need that functionality. Perhaps their rationale is a performance one... but I can't believe the benefits in performace in this instance outweigh the security impact. I imagine thousands of vulnerabilities in OSS projects would not have existed if the uses of open in *nix or OpenFile in windows were wrapped and checked for bad characters. Microsoft has got this right, though. This is exactly what they and the Suhoshin patch do to protect the developers on the web. 


As a side note... Props to Ubuntu for distributing PHP with the Suhoshin patches applied to the default install. And to any other vendors that do this as well... although you should check your PHP install to make sure you have the Hardened PHP patches installed. Stefan et al. have done an excellent job tying up some of the loose ends PHP seems to leave all over the place.

Comments
(anon) | ‎11-04-2009 08:03 PM

Beware of the "grep and gripe" approach. This is why there are dozens of 'myth/fake' entries in OSVDB.org. It's easy to search for vulnerabilities with grep, but they are not always straight-forward.

Searching GoogleCode for vulnerabilities when it came out a while back, showed that searches for "vulnerability" or "security" could find interesting things as developers would comment their code.

matt wood | ‎11-06-2009 09:46 PM

@Jericho. Absolutely, the results from google code are not guaranteed to be vulns. However its a pretty good way to find poor design decisions that use language API's insecurely.

So if your interested, as we were, about the most common ways developers fall prey to LFI, searching code is pretty helpful. Even if each specific search result isn't a vuln, the usage pattern is probably repeated plenty of times.

(anon) | ‎11-11-2009 06:32 PM

For Java, you can try the SafeFile class available in the ESAPI library, which prevents null-byte injection.

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.