Dropping a PHP Webshell

I want to discuss a simple method to get a Webshell on a vulnerable PHP application. A Webshell is basically the ability to run system commands from a malicious uploaded script. I’ve written a stupid little PHP script that just takes a GET parameter ‘cmd’ and runs it though the PHP system() function which will execute the command on the Web server.

echo '<pre>'; system($_GET['cmd']); echo '</pre>';

While the demo code is very basic, a vulnerability like this could allow an attacker full control over your application and server.

I’ve got the DVWA web application running in Metasploitable and I’ll be hacking it from Kali Linux.

Navigating to the “Upload” page of DVWA you can see a simple file upload form. Typically this would be used to upload images to a web application for example profile pictures in your social media account.

Let’s see if we can break it.

I first want to see what type of files we can upload. I’ll start with a normal looking JPEG image.

Uploading a JPEG image worked. What else can we upload? Maybe a PHP script?

Nope that didn’t work. There’s clearly a filter checking for file types. Normally this would take a bit of digging and trial and error to figure out what files are allowed and what files are not, but in DVWA you can actually just view the code.

So it looks like we can upload JPEG images and not much else. But the vulnerability is in how the application is filtering for the file extension. See in the code snippet above we have the variable $uploaded_ext which uses PHP functions to strip the extension from the file name, and then the if condition checks for different variations of the JPEG extension before allowing the upload. This should be fairly easy to tamper with however don’t expect real applications to be this easy.

Let’s change the file extension of the PHP script just to see if the upload is allowed. I don’t expect it to be this easy but this should show us in normal circumstances that the application is not filtering in other ways too, such as looking for file signatures.

Simply changing the PHP script to a JPG image worked and the upload was allowed. However as it’s not a real image the browser can’t render it and PHP doesn’t know to execute it.

I’ll try changing the filename to shell.php.jpg to see if this works to bypass the filter. The PHP code that checks the file extension is fairly simplistic and is only checking for everything after the final period.

Well that worked. Let’s see if we can execute it. The file is uploaded to the ../../hackable/uploads directory, so let’s go there and try to pass a command to GET.

Passing ls to ‘cmd’ has the effect of telling the PHP interpreter to execute the ls Linux system command, which lists directory contents on the server. It will list the contents of the directory we’re in because we haven’t told it to look anywhere else. Let’s try something else.

This time passing “cat /etc/passwd” to cmd which is telling the server to dump out the contents of the passwd file in Linux. As you can see, that worked, however the passwd file doesn’t actually contain passwords. It does give us all the user accounts on the server though.

This Webshell is pretty basic, but it demonstrates a pretty damaging vulnerability if an attacker can upload files to a server that doesn’t filter file extensions properly.

Leave a Reply

Your email address will not be published.