Attacking the vulnerable web application using SQL injection

Purpose:

A few weeks ago we had created a web application using HTML/PHP which connected to a MySQL database. The database stored a username and password in order to receive a login success message. For this walkthrough we are going to attack it using a few methods. Starting with some manual SQL injection. We will then automate this attack using two tools, Burpsuite and SQLmap.

Manual Injection

Lets connect to our website we created last week.

A simple form which only requests a username and password. If we take a look at the source code we can see exactly what is going on (Right click > ‘View Page Source’ or F12 developer tools).

Here we can see that once we submit (POST), the request will be sent to authentication.php. Attacks using SQL injection will mostly be trial by fire. I say this because unfortunately from an attackers perspective we can not see the source code of a PHP file or structure of database. This code is processed on the server and then a response is returned.

This walkthrough is not meant to give you a strong understanding of SQL syntax. I will walk through a few basic statements but it is suggested that you read up on SQL elsewhere.

Since we developed this application last week ourselves, we know the SQL query being used. Again this is all on the server and can not be seen elsewhere.

SELECT * FROM users WHERE username = '$username' AND password = '$password';

In other words we are saying that we will select all (*) from the users table where both username and password matches input provided by login form.

This SQL query is not using a prepared statement. The input we provide may be interpreted directly as SQL syntax and respond as such.

For example. If we were to provide ‘jack’ as our username, it would return a true statement. This is because jack is stored in the database and jack is the input provided by user. What if we created another true statement by comparing two integers?

SELECT * FROM users WHERE username = '' OR 1=1 AND password = '$password';

So we now created a true statement for username because 1 does equal 1. The problem though is that the query is using an AND statement, asking for both statements to be true. Well what if we just commented out the rest of the statement and only cared about username, 1=1?

SELECT * FROM users WHERE username = '' OR 1=1 # AND password = '$password';

Anything after the # will be commented out. So now all the query will see is a true statement and grant access.

Another example would be instead of comparing integers to make a true statement, use a common username. Maybe this would work if the OR was filtered out from the source code, and previous example can no longer be used.

SELECT * FROM users WHERE username = 'jack' # AND password = '' OR 1=1;

Exploiting SQL with Burpsuite

Aside from the two examples provided above, hundreds if not thousands of others are out there and easy to exploit. To save time and automate the process we can use tools like Burpsuite. This can also be used from a blue teaming perspective. Maybe before deploying a web application, you can do a ‘Fuzz’ test. Which is exactly what we are going to do today, throw an entire wordlist at each of the inputs and see what happens. Depending on the response code provided by burp or length of response we can better determine if we were able to find an exploit or not.

Download Wordlist

First lets grab a wordlist containing known vulnerable injections.

SecLists repository has a bunch of wordlists that can be used. SQLi to be more specific is what we are looking for today.

Burpsuite

Next we will open up Burp. If a proxy is not already setup on browser of choice, use the built-in browser in burp under ‘proxy’ tab.

Navigate to our vulnerable web application using this browser. Burp will open up its request and ask for you to take action. Click ‘forward’, to send request as intended without modification.

Next we will want to open the browser back up and send another request. You can send a blank request or just put some input to help determine the injection points.

This time around instead of forwarding the request we are going to want to send this request to intruder.

After clicking ‘Send to Intruder’, we will want to open the intruder tab along the top of toolbar.

Target is already configured from request being sent over. All that is left for some basic testing is positions and payloads.

The positions tab is where we will designate the input we would like to inject. In this example the user and pass, identified with the symbols to the right and left of input provided from request.

Lastly we will want to load the payload (wordlist). First head over to Payloads tab and then under the second option we will click load and load the list we downloaded from GitHub.

After loading the wordlist we can start the attack. Since we are using the community edition, a warning will pop up. This warning is just telling us that the tests are slower then paid version.

Once we start the attack we will see injections being entered.

From here we can see the position (user), payload (vulnerable injection), status (http/https codes) and length. The 200 status code is what we are looking for. Indicating that the request is successful and no errors were found. With that being said that does not necessarily mean the injection was successful. That is where the length will help out.

This entire list will find many vulnerabile injections. With that being said to show an example of what we will see, I used the inputs we already know are vulnerable against attacks that are not.

In the example above we can see several responses and the varying lengths. For starters we see the input blahblahblah passed through position 1 with length of 189. Along with several other random inputs. Then we see the ‘ OR 1 = 1 # payload with length of 208. Giving us an indication that something changed in the response. Now if we were to plug this in manually we would see the results from earlier ‘Login successed’.

SQLMap

At this point we were able to exploit the SQL query in order to process a true statement and gain access to the website. What if we wanted to dump the entire database to get all of the users and passwords? Well with SQLMap we can do exactly that. To make our life easier we will again start inside of burp and capture the request. This time instead of sending to intruder we will copy to a file.

Next we will pass the request file to sqlmap using the following command with -r option

From this point forward it is fairly straight forward. Especially for our lab because it was developed with vulnerabilities in mind. It will ask a few y/n questions. For example

It is asking if we would like to see if there is another parameter vulnerable to SQL injection. Which we already know ‘pass’ is from our previous techniques, so enter ‘y’.

At the end of the results, if you scroll up we will see available databases.

From these databases we can see the tables by selecting a database with -D ‘hackme’ and using –tables

Now if we wanted to get the information from inside of these tables we can use –dump

That’s it! We now have the users table from hackme database and all of the information inside of it. This is not always going to be that easy but it is a tool that can be added to the box.

Conclusion

Probably one of my favorite labs so far. This is primarily because we started from scratch. We developed everything on our own and saw what goes into it behind the scenes. In a production environment most of this is already patched (hopefully). Otherwise it is easy to see how an attacker can get in with just a few clicks.

If interested in a video format of this lab be on the lookout over at the YouTube channel. In the meantime, as always, Never Stop Learning!