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
$code = $_GET[‘hax’];
It provided me with a directory listing of my webroot.
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”.
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
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