I expect:// a shell!

This blog post covers a fascinating method of leveraging Local File Inclusion to gain Remote Code Execution on a vulnerable host. It has several downfalls, but overall is one of the more interesting methods I have found, and I have not found any references to it anywhere that I looked online.

PHP has many “wrappers” to parse certain types of things. For example, the php://input or php://filter wrappers, which have been used in the past for both code execution and information disclosure – notably the PHP-CGI Arguement Injection exploit, which uses the php://input wrapper to inject code after making modifications to PHP.ini directives.

One of the more entertaining ones I stumbled across is how PHP handles the expect:// “wrapper”. For those who do not know, “expect” is a program/scripting language of sorts that one can use to interact with other interactive programs. Some of you may be familiar with pexpect from Python, which is used to interact with SSH sessions for automation. It is a rather powerful utility, and is often used by sysadmins to automate procedures which would normally require human interaction.

As it happens, amongst PHP’s many wrappers, there is an “expect://” wrapper. I stumbled across it by accident while looking up the correct way to use php://filter to read files via LFI (I will document that method later, it deserves a post of its own). I knew expect looked familiar, so when I looked more into it, I found examples of people using it in PHP scripts to automate things like ssh-ing to remote boxes, etc.

After a while it dawned on me that something interesting might just happen if I passed expect://ls to an include() call in a PHP script, so I decided to see what would happen.

I used the following vulnerable (to LFI) PHP script, and called test.php?hax=expect://ls

<?php
$code = $_GET[‘hax’];
include($code);
?>

It provided me with a directory listing of my webroot.

expecting shell

remote code execution

After a few minutes of thinking “oh, this is interesting”, I decided to see if I could knock up an interactive shell in Python to automate the whole procedure.

First off, I decided to see could I get it all to work out using Pythons “requests” module…

Seeing as it worked, now it was time to write a “shell”.

Gotshell?

got shell :)

Yes, I now had a somewhat interactive “shell” on the vulnerable host (localhost…). I considered releasing the proof of concept right there, however further messing about was warranted first, obviously. I needed to see how far I could “push” this vuln, and how cool I could possibly make the PoC tool before releasing it to the wild, where someone would doubtlessly give me much abuse about my python :P

So, without further ado, here is the video demo of it. It now checks if the host is vuln (very rudimentary check), and offers the “inline shell” or a reverse shell :) Download links at bottom :)

// Err, the video is on its way, I did not have time to clean it up sadly. I will edit this post in a day or so with the finished video, I promise :)

download link

Local File Inclusion to RCE, abusing tempfiles and phpinfo()

“If you want to win a race condition, you best cheat”.

The following article demonstrates a fascinating method of exploiting Local File Inclusion vulnerabilities first thought up of by the guy who runs Gynvael.Coldwind.pl . It is further documented at Insomnia Security

To start, when you are exploiting a Local File Inclusion, in order to gain remote code execution you must “write” some PHP code somewhere on disc that you can “include”. Normally this means injecting into logfiles, or the /proc/self/environ interface.
In the event you cannot locate the logfiles, or access them, most people simply give up and claim “Yep, it is unexploitable”.
This is not true.

When you upload files via HTTP POST to a webserver running PHP, during the upload it creates a tempfile for the files data, normally in /tmp. This file is “randomly named” (I do not trust the PRNG PHP uses), and is stored for the duration of the upload.

Now, it just so happens that it will create this file irrespective of whether or not you are legitimately uploading (i.e. the webapp is accepting an upload) or not, and the file is deleted when the “upload” finishes.

Because these files are randomly named, and there are no wildcards that we can use on Linux (more on this later!), you might think “So, how does this help me at all?”.

Normally, you would be right. Unless you find a flaw in the PRNG that allows you to predict the “dummy name” of the file, this is not so useful to you. What we need is an information disclosure bug that displays the PHP variables at that particular time…

… Enter PHPinfo(). The phpinfo() call, often found in /phpinfo.php or other such files (often forgotten and not removed on webservers), displays the PHP variables as they are at that point in time… Including the “Dummy Filename” that is currently in use.

So, if we are to send a file upload, containing our evil PHP code, and then include() it (via the LFI), using the path given to us by the PHPinfo page, we gain code execution on the remote server.
Simple?

Yes, but not quite.
The file exists there for mere fractions of a second, so we lengthen the duration of the upload (we upload to the phpinfo file) by padding it with trash data. The insomniasec paper (linked at bottom) explains this better than I will, so I advise reading it! This is a race condition, so to further enhance our chances, we use multiple threads and multiple attempts. One of them will succeed, normally within short order (averages at 30 seconds, see the demo video!). If you have LFI and a phpinfo() page, you WILL gain code execution on the server.

The PHP code you “upload” and execute via include() effectively acts as a “Dropper”, dropping some malicious code that is stored in /tmp with a filename you have set. You then simply include() this dropped file via the LFI bug to execute code, as per normal LFI.

The InsomniaSec guys released, along with their paper, a demo script to show how it works. imax, the mantainer of Fimap (which I also develop) released a Fimap plugin that exploits this vulnerability, and that is what I am about to demonstrate. imax’s code drops a file named “eggshell” which is essentially a stripped down version of the Fimap payload.

The Fimap module is extremely reliable, giving me shells in short order. I have never had an issue with it to date, and normally on remote boxes it takes a minute or so to pop a shell.

Demo Video

Next week I will be releasing a demo of doing this against Windows targets without the lovely PHPinfo bug. A much “truer” race condition :)

Whitepaper (InsomniaSec)

Symantec Web Gateway 5.0.2 Remote Root Exploit

So I was browsing the net and happened across Muts’ latest PoC – an LFI bug in Symantec Web Gateway, which he claims gives remote root. You can see it here: Exploit DB

I read the exploit code and noticed, while beautifully elegant, it is a little bit of a pain in the ass to use, as you must edit it every single time.

I also was in the mood to knock up a quick bit of python, so here is what I made: Pastebin – Exploit Code

It is not the best, but was just my attempt to make the exploit code Muts provided a little better in the usability stakes :)

I have no Symantec WebGateway to test it in, but it should do the trick ;)

Anyway, thats it. All credit to Muts for finding the bug and writing the original exploit code, all I am doing is improving it. Will likely do this a lot for fun and to keep my programming skills sharpened :D

~infodox