This page may be out of date

We haven't updated it for a while because we're busy working on new, improved content to help you get the most out of Burp Suite. In the meantime, please note that the information on this page may no longer be accurate.

Visit our Support Center

Using Burp to Exploit SQL Injection Vulnerabilities: The UNION Operator

Once you have established that a database is vulnerable to SQL injection, it is often useful to exploit the vulnerability to demonstrate any potential implications. A successful SQL injection exploit can potentially read sensitive data from the database, modify database data, execute administration operations on the database and in some cases issue commands on the operating system.

The UNION operator is used in SQL to combine the results of two or more SELECT statements. When a web application contains a SQL injection vulnerability that occurs in a SELECT statement, you can often employ the UNION operator to perform an additional query and retrieve the results.

OWASP_AccessControls_1

First, ensure that Burp is correctly configured with your browser.

Ensure "Intercept is off" in the Proxy "Intercept" tab.

Methodology_SQL_Detection_SQL-specific_Parameter_Manipulation_1

Visit the web page of the application that you have identified as having a potential SQL injection vulnerability.

Return to Burp and ensure "Intercept is on" in the Proxy "Intercept" tab.

Now send a request to the server. In this example by refreshing the page.

Methodology_SQL_Detection_SQL-specific_Parameter_Manipulation_2

The request will be captured in the Proxy "Intercept" tab.

The parameter we will attempt to exploit is the "id" parameter in the URL.

The first task is to discover the number of columns returned by the original query being executed by the application, because each query in a UNION statement must return the same number of columns.

Right click on anywhere on the request and click "Send to Repeater".

 

Methodology_SQLi_Exploitation_1

In this example we exploit the fact that NULL can be converted to any data type to systematically inject queries with different number of columns until the injected query is executed.

For example:

UNION SELECT NULL--

UNION SELECT NULL, NULL--

UNION SELECT NULL, NULL, NULL--

Note: In this example we do not need a single quote to terminate any existing string. In addition, the space character must be encoded as %20.

Methodology_SQLi_Exploitation_2

The application displays an error message that can be viewed in the response tab. The error message says that the used SELECT statements have a different number of columns.

 

Methodology_SQLi_Exploitation_3

We can continue adding NULLs to our query until we see a change in the application's response.

Our query is executed when the number of columns returned by our injected query is equal to the number in the original query.

When we inject 8 NULLs, the page displays the content without any issues and there are no error messages. When we add a 9th NULL to the query, the application produces an error. So we can infer that the original query returns 8 columns.

Methodology_SQLi_Exploitation_4

Having identified the number of columns, the next task is to discover a column that has a string data type so that we can use this to extract arbitrary data from the database.

We can do this by injecting a query containing the required number of NULLs, as we have previously, and replacing each NULL in turn with 'a'.

For example:

UNION SELECT 'a', NULL, NULL ...

UNION SELECT NULL, 'a', NULL ...

UNION SELECT NULL, NULL, 'a' ...

Methodology_SQLi_Exploitation_5

When an 'a' is specified at a column that has a string data type, the injected query is executed, and you should see an additional row of data containing the value a.

However, in our example the page is not showing anything other than the original content.

We can see that the query is being executed, but because the application is only showing the first result we cannot see the result of the injected query.

Methodology_SQLi_Exploitation_6

We can ensure that our data is the first row returned by modifying the original query so that it does not return any rows:

0 AND 1=2 UNION SELECT NULL, NULL,'a', NULL, NULL, NULL, NULL, NULL

Methodology_SQLi_Exploitation_7

We can now see in the response that the application is displaying the injected 'a' string instead of the actual user details.

The 'a' is displayed in the data field corresponding to the column in which we supplied it.

Methodology_SQLi_Exploitation_8

We can now use the relevant column to extract data from the database.

0 and 1=2 UNION SELECT NULL, NULL, version(), NULL, NULL, NULL, NULL, NULL

In this example we have altered the injected code to display the version number of the database. We can then continue to use this technique to retrieve any accessible data from the database.