• 10 hours
  • Medium

Free online content available in this course.

course.header.alt.is_certifying

Got it!

Last updated on 9/27/24

Attack the Database With SQL Injections

Fortunately, they are becoming increasingly rare. But it’s really important to know how to detect and exploit them!

Retrieve Database Content With SQL Injections

SQL injections are generally considered critical, as they can be used to:

  • retrieve (or even modify) the contents of a database, especially usernames, passwords, and their hashes.

  • take control of the server (through Remote Code Execution, or RCE), depending on the database engine used (e.g., MySQL, Oracle, or Microsoft SQL), which is particularly serious.

Note that once we have the contents of the database, we usually have all the data, which is ultimately an application’s most important asset.

How does SQL injection work?

In most applications, data is stored in a database. This database may be on the same server as the application, or it may reside on its own dedicated server (known as n-tier architecture).

To store its data in the database and then read it, the application needs to run SQL queries using an account that has been set up for that purpose.

The web server sends a SQL query to the database server to retrieve the data it needs. Sometimes, these queries include data provided by the application’s users.

How do you modify a SQL query?

By injecting special SQL characters into one or more fields that are used as parameters to build the SQL query:

How SQL injection works
How SQL injection works

Let’s see how they differ.

Error-Based SQL Injections

Error-based SQLi vulnerabilities are the easiest to identify and exploit. We tend to find them less frequently in the real world. We can usually identify and correct them quickly, because they are fairly easy to detect.

If the code is vulnerable, the query will crash when you enter a special character (such as an apostrophe  '  or a quotation mark  "  ) in a field that the SQL query uses as a parameter.

If the client displays the returned error message, it will sometimes even tell you what’s wrong, just like the demo application’s response here:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'test'' at line 1

We refer to this type of injection as error-based because detecting and exploiting it relies on the page displaying an error message.

Boolean-Based SQL Injections

Boolean-based SQLi vulnerabilities are more complicated to explain and detect.

Instead, the server returns a default page or result.

So, how do we know whether the request is vulnerable?

Detecting these injections is based on how the server’s response differs depending on the result of the injection. If the SQL query is vulnerable and the injection works, we get response A. If it doesn’t work, we get response B, such as a default page.

Let’s look at a real-world example. You have a login page asking for a username and password. The associated SQL query has the following structure:

SELECT username FROM users WHERE username like '$_GET[username]' AND password like '$_GET[password]'

The use of “wildcard” characters (i.e., those replacing zero or more characters), such as  %  , should result in a valid query.

We can then iterate through the vulnerable parameter, until we’ve extracted the desired information from the database. In our case, if we wanted to find the password, all we’d have to do is test all possible characters followed by  %  until we find the right letter, then start over with an additional character until we find the complete password!

Time-Based SQL Injections

The last type of SQL injection is also blind.

Let’s imagine you have the same query as before, but this time the application correctly handles returned error messages by not sending them to the client. Even the use of wildcards doesn’t tell you whether the query is vulnerable or not.

So, what do we do in this case?

We play with time! We can add instructions such as  sleep()  to pause a SQL query. If the query is vulnerable to a SQL injection, and we manage to get the  sleep()  to be interpreted, we’ll be able to tell that there’s a SQL injection by measuring the time it takes for the queries to execute! These injections are known as time-based SQL injections.

There’s one last type of injection that’s even more difficult to detect and that depends on many factors: blind SQL injections with data exfiltration over auxiliary channels or Out-of-band Application Security Testing SQL Injections (OAST SQLi). These injections involve the exfiltration of data from the query result into channels other than the HTTP response, such as a DNS query.

Exploit SQL Injections

Let’s look at an example of a potential SQL injection involving a feature of our  example.com  application.

In this application, doctors can create a profile for themselves, specifying their first name, last name, address, and other details. This data needs to be stored in a database so that the application can retrieve the information when needed.

Now let’s assume that the application has a feature for searching for other users of the application and that this search field is vulnerable to SQL injections. The SQL query would look like this:

SELECT firstname, lastname FROM users WHERE lastname like '$param'

$param  is our variable containing what the user is searching for.

If the user writes  Bob  as the last name, everything will work perfectly. But if the user writes  'bob  , what will happen to the query? It will look something like this:

SELECT firstname, lastname FROM users WHERE lastname like ''bob'

In this case, you’re likely to receive an error indicating that there is no closing apostrophe or that bob is not a valid keyword. You’ve found a SQL injection vulnerability! Now all you have to do is exploit it correctly to exfiltrate the data you’re interested in.

How do we exploit this vulnerability in practice?

The simplest way to exploit SQL injections with  WHERE  conditions (as in the example) is to make the condition always return “true” by adding a statement that is always true, such as  1=1  or  'a'='a' .

Instead of  bob  in the field on its own, we’ll send  bob'  or  1=1 --  . Going back to our example, this will give us the following modified query:

SELECT firstname, lastname FROM users WHERE lastname like 'bob' or 1=1 --

The database engine will then interpret this as:

“Select the first and last names of users where this is true.”

In fact, the conditionlastname  like  'bob'  or   1=1 -- will always return true, since it’s a Boolean  OR  . The query will therefore return the first and last names of all the users in the database.

To retrieve more interesting data, such as user passwords, you’d have to expand this query. We won’t be looking at this in this course, as it’s really part of “post-exploitation” (i.e., activities that usually take place after the successful exploitation of a target).

The SQLMap tool featured in the demonstration video is very useful for automating the exploitation of SQL injections. You can use this tool to detect and automate the exploitation of SQL injection vulnerabilities. However, I recommend that you only use it to exploit and help you find injections, rather than to do all the work for you, as it’s by no means foolproof!

Although we’re not going to discuss countermeasures in detail, these vulnerabilities are relatively “easy” to avoid or correct. All you need to do is use what are known as prepared SQL statements. They are available for most, if not all, programming languages.

Over to You!

Challenge

It’s now your turn to exploit a SQL injection on one of Root Me’s official challenges.

So, fingers to keyboard—and good luck!

Solution

Remember the hacker’s philosophy: To learn, we encourage you to search, test, trial, and tinker. There are no cookie-cutter answers here, as this would be counterproductive. That said, you’ll find all the concepts you need in this chapter!

Let’s Recap!

  • SQL injections are server-side injections, meaning that they run on the server and—specifically for this type of vulnerability—on the database.

  • These injections can occur whenever the SQL query contains parameters that a user can control, such as a search field or a username.

  • There are a number of different types of SQL injections, listed here in order of difficulty of detection: 

    • Error-based

    • Blind Boolean-based

    • Blind time-based

    • Blind OAST-based

  • The most common use of SQL injections is to retrieve content from a database.

  • They can also be used to modify a database by adding or deleting data.

  • The worst case scenario may allow an attacker to run code on the server, although this depends on the database engine. (Microsoft SQL is particularly vulnerable to this.)

In the next chapter, we’ll look at vulnerabilities involving file system manipulation and arbitrary command injections. Let’s get started!

Example of certificate of achievement
Example of certificate of achievement