Despite being around for many years, SQL Injection (SQLi) is still a hugely prevalent security flaw in web applications. Just how easy is it to exploit a SQLi vulnerability, and how easy would it have been to prevent?

MySQL-Logo

 

SQL is short for Structured Query Language and is used by web applications to communicate with a database to insert, access, modify and delete data stored there. SQLi is a method of exploiting a poorly protected web application by inserting SQL code into an unsanitised field. The SQL code is then passed to the database and executed. Injection based attacks are currently featured as the number 1 threat to website security according to OWASP. They can have huge implications if exploited by malicious hackers as security company Bit9 found out and were embarrassingly forced to report on their blog earlier this year.

To demonstrate how simple it can be to perform a SQLi attack I first found a website with a vulnerability I could exploit.

SQL-Injection-Test-Site

 

It's worth pointing out at this point that running a SQLi attack against a website without the owners permission could well land you in hot water with the local law enforcement. It's highly recommended that as a good white hat you build your own test platform to launch attacks against.

The code for my login page has been cut down to the bare essentials to demonstrate the dangers of a SQLi attack. You can find it on my Pastebin here.

SQL-Login-Form-Code

 

The aim of the simple login form shown above is to accept credentials from the user in the form of a username and password, check for their existence in the database and then either log the user in or not based on the results.

SQL-Login-Form-Submit

 

After filling in the form and pressing submit the SQL would look something like this (pastebin).

SQL-Query

 

This query would return the ID of any user that matches the supplied username and password. Up to this point everything is working fine and the user is logged in if the correct credentials have been provided. So where does it go wrong?

A very easy and common use of SQLi is to bypass the login forms on websites just like this one. A SQL injection attack in essence is actually very simple. The aim is to insert text in the login form that then alters the interpretation of the query. Let's take a look at this as an example.

SQL-Form-With-Injection

 

If we take the above form data that will be submitted and insert that into the SQL query that will be executed we end up with something that looks like this:

SQL-Basic-Injection

 

At first glance it's clear to see that the above statement has been altered, but let's break it down. As the username field was blank you can see that the associated query string is empty, not a great problem in itself. Moving on to the password field you can see the first apostrophe we inserted has actually closed off the password string in the query so we now have password = ''. Again, this isn't a great problem in itself but the real kicker comes next. By inserting the OR expression and omitting the last apostrophe in our input, we have actually created the statement OR ’1′ = ’1′. This will always evaluate to true. So, as the query now steps over each entry in the table it's going to look for a field where the username = '' and password = '' OR true. As true will always be true, it will return the first entry in the table.

SQL-DB-Table SQL-Logged-In-JBloggs

 

There we have it! With a few seconds of your time and a very small piece of SQL code injected into the input fields you have successfully bypassed the website security. Poor old Joe Bloggs has just had his account compromised!

This is all very useful but what if you didn't want to simply login as the first user in the table, or better yet, do you want to target a specific user? Let's say that you know John Smith uses this particular website and you would like to target his account.

SQL-Target-JSmith

 

Again if we break this query down and we end up with.

SQL-Target-JSmith-Query

 

Now, there is a bit of a leap here in that I made the assumption the attacker knew the field name was username. In a real world environment the attacker would not have known this but guessing through common names like user, users, username, usernames etc... it wouldn't take very long and usually yields favourable results. The results of this query.

SQL-JSmith-Logged-In

 

Dear oh dear, poor John! This of course leads us to, just in case some of you were wondering, the worst case scenario for the site owner.

SQL-Form-Admin SQL-Query-Target-Admin SQL-Logged-In-Admin

 

The potential scope for damage that could be caused with the above vulnerability is limited only by what the administrator can or can't do. Creating malicious user accounts, destroying/defacing the website, and stealing private or sensitive data are all well within reach of the hacker at this point.

In a subsequent blog I will cover more advanced forms of SQLi and begin to cover ways of mitigating the threat. Remember, only ever attempt to exploit vulnerabilities in a site that you own or that you have permission to attack. Use the above information responsibly!

 

Scott.
Short URL: https://scotthel.me/SQLi