SQL Injection Attack, Querying the Database Type and Version on Oracle

A Portswigger Lab

Marduk I Am
6 min readAug 1, 2024
Welcome back!

Lab Description:

This lab contains a SQL injection vulnerability in the product category filter. You can use a UNION attack to retrieve the results from an injected query.

To solve the lab, display the database version string.

Hint:
On Oracle databases, every SELECT statement must specify a table to select FROM. If your UNION SELECT attack does not query from a table, you will still need to include the FROM keyword followed by a valid table name.

There is a built-in table on Oracle called dual which you can use for this purpose. For example: UNION SELECT ‘abc’ FROM dual

For more information, see our SQL injection cheat sheet.

Getting Started:

In this lab, we’ll explore SQL injection (SQLi) techniques to identify the underlying relational database system utilized by the website. Understanding the database type is crucial since various databases require specific query adjustments, as outlined in the provided cheat sheet.

With your Burp proxy running, access the lab, and you will be brought to the lab’s shopping page. The lab description tells us that the SQLi vulnerability lies in the product category filter, so that is where we will start.

Click on one of the given filters. Being an animal lover, I chose ‘Pets’.

Shopping page filtered by pet category. Lists pet products and their descriptions.

At the top of the lab web page you can see the objective of the lab. We are trying to get the page to display the database’s version as a string by using a UNION SELECT.

Before performing a UNION SELECT attack, it’s essential to determine two things:

  • How many columns are in the database.
  • What is the data types of each column.

When executing a UNION SELECT attack, you’re essentially combining the result sets of two SELECT statements. To ensure that the injection query is successful, the SELECT statements being combined must have the exact same number of columns with compatible data types.

You can use techniques like trial and error or inference-based methods to gather this information. This is where Burp Repeater is extremely helpful.

Crafting the Payload:

In Burp, find your filter in the site map on the left hand side. Right-click on it and select ‘Send to Repeater’. We are going to be sending multiple requests and Burp’s Repeater feature make this a lot easier.

Screenshot of Burpsuite, showing our request highlighted in the site map and arrow pointing to the location of the Repeater tab.

Click on the ‘Repeater’ tab and your request can be seen there on the left hand side. Here we can manipulate our GET request and easily see how our injections affect the response.

Let’s start by quickly confirming the presence of a SQLi vulnerability. In the request, add a single quote (‘) to the end of your category filter and click ‘Send’.

View of Burp Repeater with our request on the left and response on the right.

Notice the 500 response in the right hand column? That is telling us that the server is not processing our request properly, making it vulnerable to SQLi.

Since we know we found the correct injection point, we now need to determine the number of columns in this particular database. We can do this in Burp Repeater as well.

On our shopping page we can see that there are at least two columns. The product name and the product description. However, let’s verify this in Burp. We are going to use the ‘ORDER BY’ statement to help us.

If we “order by 1”, we are telling the database to order our results by column 1, and we should get a 200 response from the server telling us there is a column 1. Same with “order by 2”.

Burp Repeater showing modified request with ‘+ORDER+BY+1+ —
200 response
  • Note: In SQL, the double hyphen is used to indicate a single-line comment. In our payload though, it is rendering anything that comes after it useless.
-- Testing for # of columns
' ORDER BY 1 --
' ORDER BY 2 --
' ORDER BY 3 --

Keep doing this until we get a 500 response. The 500 response will tell us “Nope, there is no third column”. Luckily we don’t have a lot of columns to go through.

‘ ORDER BY 3 — showing a 500 response in Burp Repeater.
500. There is no column #3.

So we now know there are only 2 columns. Next, what type of data are in these two columns?

From looking at our shopping page we also have a pretty good idea that these columns contain strings of text. Let’s verify that, of course.

Using our ‘UNION SELECT’ statement we are going to inject some words into this page. The syntax is as follows:

  • Note: ‘dual’ is a default dummy table present in Oracle. A table must be specified when using Oracle. And since we don’t know the names of any of the actual table names used, we can use ‘dual’.
-- You can replace the strings with whatever you like
' UNION SELECT 'Marduk','James' FROM dual --

Add the payload into your Burp request and send it. Don’t forget to URL encode it with ‘Ctrl+U’. URL encoding will replace spaces and special characters with more URL friendly characters.

‘ UNION SELECT ‘Marduk’,’James’ FROM dual — gets a 200 response

If you render your response, or copy and paste the URL into your browser, you will see your strings displayed on the page.

Marduk James being displayed on the page!
Displayed on page!

Lab Solution:

From here we just need the page to display the database version string to solve the lab. To do that let’s take a look at the provided cheat sheet.

SQL cheat sheet showing queries for different databases.

We need to use this first query to solve the lab with just a couple of modifications. This query will retrieve the data in one column, banner, from the table (or view) v$version. Remember, we need two columns.

To fix that we need to specify another column, in our payload, which will be ‘null’.

-- Final Payload
' UNION SELECT banner, null FROM v$version --

Add our payload to your request, URL encode and send it. You should get the ‘Congratulations’ pop up on your page!

Final payload, ’ UNION SELECT banner, null FROM v$version — , gets a 200 response!
Nice!

Render the page in Burp or copy and paste the URL into your browser to see our results.

Version displayed on page.

Congratulations! You solved another one. Keep up the great work!

See you next time!

Next Lab:

SQL Injection Attack, Querying the Database Type and Version on MySQL and Microsoft

Previous Lab:

SQL Injection Vulnerability Allowing Login Bypass

--

--

Marduk I Am

Cybersecurity enthusiast. Currently focusing on write-ups and bug bounties. Twitter: @marduk_I_am | Mastodon: @Marduk_James@infosec.exchange