Friday, October 16, 2009

null byte injection



In this 2008 blog post, Portswigger says that null byte attacks against web applications are nothing new. It's almost 2010, and they're still nothin' new, but they sure can be fun!

During a recent web app assessment, I found one very similar to the example in Portswigger's post. I tampered with it a few times, but wasn't really sure if it was an exploitable condition or not.

I saw some requests containing a file name, similar to:
/servlet?file=image_N.jpg

I began trying some basic attacks, like:
/servlet?file=../../../../etc/passwd

These attacks always resulted in the application cleanly handling the exception, and giving me a friendly error message in a HTTP 200 response. Not quite ready to give up, I decided to try the following:

/servlet?file=../image_N.jpg

This also generated an error, but this time it was a 500 Internal Server Error from the application container. This meant that the validation routine was not necessarily aware of my ../'s, but was probably concerned with the format of the file name. To be sure, I tried the following:

/servlet?file=image_N.foo /servlet?file=../image_N.foo

Both of the above requests generated the clean error message. Only when the string ended with _N.jpg, did I get a 500 error, which told me that the logic was:

1. Validate the file name extension is .JPG.
2. Validate that the file name is of the format image_N, where N is a random integer.
2. Try to read the JPEG from the file system.

This is great if you want to read JPEGs, but I had my heart set on arbitrary file access. So how do we by-pass the _N.JPG filter? I pressed the staples easy button on my desk and it injected a null byte like:

/servlet?file=../../../../etc/passwd%OOimage_N.jpg

After a number of attempts to determine the directory depth of the file system, I was happy to see the contents of the passwd file in my browser.

Then things got interesting . . .

This application had been pen-tested before. It had also been scanned using a popular commercial static analysis tool, and had gotten a clean bill of health. So, let's just say that management was a little, um, curious about why this bug was still alive and well. And by curious, I actually mean furious.

So what went wrong? After the first pen-test, the blatant directory traversal bug was "fixed" with a new validation routine that scrutinized the end of the file name. This new routine was declared a validation routine in the static analysis tool, and any subsequent data flows that passed through it were considered safe. Game over. Hooray for tools!

Lessons Learned

Behind every tool is the person who wrote it, and the person operating it. These people are just as likely to make mistakes as the developer who wrote the target application. Once again, we're reminded that there is no silver security bullet. Tools help, but it comes down to proper education, process, and people to actually find and fix bugs.

No comments: