Interesting Local File Inclusion method

Posted: January 16, 2010 in security
Tags: , , , , , ,

So there I was exploiting a LFI, only problem being I hit a brick wall. I did not see any possible way to leverage my LFI so that I could get RCE or even leverage it in such a way that I would be able to view the source of other PHP files. Now WTF should I do I asked myself?

First of all let me explain the problems I encountered and why I wasn’t able to leverage the LFI:

Of course I also played with encoding the payloads in various ways to try and avoid possible pattern detection schemes. None of this paid off, I spend a some time trying to bypass the limitation I had encountered but without any luck. So I decided to ask for some help on IRC, luckily some people(thank you hdm & darkfig) also decided to help me out and they pointed me into a new direction. They proposed I looked into using my own HTTP POST payload as an possible attack vector to leverage RCE. So how does this attack work(References for everything in this post will be given at the end of the post)?

Using PHP Protocol Wrappers you tell PHP to use the HTTP POST data as the entry point for it’s include. For example:

Then you can for example include the following code snippet in the POST data:

<?php phpinfo(); ?>

According to the PHP documentation it allows you to read raw post data:

php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”.

Now that was EXCELLENT NEWS!!! So I decided to test this all in a test environment. I booted up Ubuntu and did a

sudo apt-get install libapache2-mod-php5

I’m lazy and that will install all dependencies. After it all installed I went ahead and tested the method.

It didn’t work :( AARGH!!!

Now that sucked, after changing the configuration I got it to work, but well that sucks in a normal environment you can’t just change the PHP configuration on your target.


allow_url_include = On

Does NOT work:

allow_url_include = Off

Now that’s a bummer, still it’s a nice trick to have up your sleeve and a pretty darn good reminder to myself: ALWAYS think outside the box! Good thing IRC still exists and that it has nice people on it like hdm and darkfig who help people like me out.

So I could have stopped and given up…then again that would mean ignoring the reminder I just got about thinking outside the box. I decided to go ahead and see if I could maybe abuse any of the PHP features to at least view some sourcecode of local PHP files. So I started to play around with the PHP filter wrapper, since according to the documentation the other ones like memory/temp/input where protected by allow_url_include. An excerpt from the documentation:

php://filter is a kind of meta-wrapper designed to permit the application of filters to a stream at the time of opening. This is useful with all-in-one file functions such as readfile(), file(), and file_get_contents() where there is otherwise no opportunity to apply a filter to the stream prior the contents being read.

So if I understand this correctly it means that I can alter the stream content BEFORE the calling function gets to work with it. Now that’s fun, so after some toying around with it and figuring out stuff(which filters it supports and such), the following command can be used to get the source of the PHP files on the server.

The output from the above URL is the base64 encoded content of the in.php file. YEAH BABY! Now I can go hunt for bugs in other PHP files available on the server.

Here are the references I used while researching this:

I would say this is a nice example of how to abuse intended features for your own fun and profit.

p.s Don’t forget this is also a very nice way to download binary files, since they first get base64 encoded.

  1. […] un ataque LFI utilizando filter, un wrapper de php. Más información sobre esta vulnerabilidad aquí. El ataque se realiza con el siguiente […]

  2. […] came opposing an article that appears to castle a issue, that led me to a following […]

  3. […] de lire le code source de fichier PHP car le code est encodé en base64. Plus de détails ici et […]

  4. 霸王别姬 says:

    In this case,With your approach can succeed?

  5. […] vector es uno de los que más me ha sorprendido descubierto por diablohorn, ya que a priori con un LFI no es posible obtener el código php, porque lógicamente lo interpreta […]

  6. nesk says:


  7. […] Using PHP stream php://filter: ?file=php://filter/convert.base64-encode/resource=index.php (lets you read PHP source because it wont get evaluated in base64. More details here and here)  […]

  8. […] (lets you read PHP source because it wont get evaluated in base64. More details here and […]

  9. n says:

    This is nice but it won’t work if the php script appends a folder name or something before the LFI variable.

  10. Kex says:

    Very nice

  11. nice work man. thank you for sharing!

  12. pentest says:

    Very nice trick,

    You also have the php session file inclusion way ;)

  13. Cd-MaN says:

    What a great blog! The previous post about dev tools for MBR code and now new twists on LFI vulns in PHP! I’m a happy subscriber.

    Thank you!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s