What is a SQL Injection attack?
To understand what a SQL injection attack is you first need to understand what SQL is and how it works. We will not go into depth about how to create SQL databases, but I will go over any commands and the processes that are being executed.
SELECT username, password
FROM users
WHERE username="frostbyte";
This is a simple SQL query which will get the username and password from the users table for the user whose name matches “frostbyte”.
SELECT username, password
FROM users
WHERE username="<<user input>>";
A SQL injection exploit is found when a SQL query is built up using user input. For example, if you have a search function to search the users table, then I would have control over this part of the query.
Now, this leaves me in a great position to start altering the query. I can’t remove the beginning of the query, but what I can do is add joins and unions to construct a query to retrieve information from the database.
SELECT username, password, fullname, email, phone
FROM users
JOIN user_profiles
ON id=user_id
WHERE username="frostbyte";
In this example, the attacker not only retrieves the username and password from the ‘users’ table but also the full name, email and phone from the ‘user_profiles’ table.
Unions are used to merge the results of two or more SELECT queries into a single result. For example, let’s say there is a table called ‘admin_users’ that stores usernames and passwords for accounts. Let’s look at a UNION command to retrieve both regular and admin credentials.
SELECT username, password
FROM users
WHERE username = "frostbyte"
UNION ALL
SELECT username, password
FROM admin_users
WHERE username = "frostbyte";
Let’s look at a little more advanced version of a SQL injection attack, called Blind SQL injection. This is a tougher variation of the attack where a flaw exists, but it won’t print the result of the query. It may seem like there is no way to extract the data out of the database, but there is! We will have to change the query to read something like this.
SELECT 1, 2, 3, password
FROM users
WHERE username="<<user input>>
WHERE Id='1' AND ASCII(SUBSTRING(username,1,1))=65 AND '1'='1' waitfor delay '00:00:15'";
Hold up, we are going to break it down step by step and I will explain exactly what is going on here. Does the first letter of the username field in the first row of the users table equal ‘A’? (The ASCII value of uppercase ‘A’ is 65) If the value equals 65, then sleep for 15 seconds.
Ok, but how exactly are we figuring out the results blindly? By timing how long it takes the page to load, you can tell if the first letter of the username field starts with ‘A’ or not. If the response takes at least 15 seconds to come through, then bingo you have a hit. If the page loads sooner than it doesn’t match. There are other ways to perform a blind SQL injection, but the timing based technique is amongst the most common.
SELECT username, password
FROM users
WHERE username="frostbyte"";
Now, do you notice what’s different from our original query? The open double quotes at the end of frostbyte. This open quote will cause an error when the query is passed through the database. If you get that error then you know there is a SQL injection exploit here. This does not work all time, but it is a jumping off point.