SQL Injection Attack, Listing the Database Contents on Oracle

14 hours ago 3
BOOK THIS SPACE FOR AD
ARTICLE AD

A Portswigger Lab

Marduk I Am

Welcome Back!

Lab Description:

This lab contains a SQL injection vulnerability in the product category filter. The results from the query are returned in the application’s response so you can use a UNION attack to retrieve data from other tables.

The application has a login function, and the database contains a table that holds usernames and passwords. You need to determine the name of this table and the columns it contains, then retrieve the contents of the table to obtain the username and password of all users.

To solve the lab, log in as the administrator user.

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.NOTE: I will be using Burpsuite Community Edition to help complete this lab, so you may want to have that up and running. If you’re not sure what Burp is or how to use it, check out this tutorial: Burpsuite Basics (FREE Community Edition) by John Hammond.

This lab is very similar to the previous lab, “SQL Injection Attack, Listing the Database Contents on Non-Oracle Databases”. The only difference being is that we will be working with an Oracle database.

If you followed the previous lab walk-through, you may feel comfortable trying this one on your own using the provided cheat sheet.

If not, then follow along here!

First, let’s create a list of what we need to accomplish in order to solve this lab.

Verify SQLi vulnerability injection point.Determine the exact number of columns AND data types.Verify that the site is, in fact, using an Oracle database.Determine the relevant table name within that database.Determine the relevant column names within the table.Find credentials for ‘administrator’.Log in to the site as ‘administrator’.

With Burp running, access the lab. The SQLi will be in the product category filter. Click on the filter of your choice.

Portswigger lab shopping page showing where the product category filters are.
I chose ‘Gifts’ this time.

You should then be able to find your filter in the Burp target site map. Right-click on your filter and select ‘Send to Repeater’.

Burp target site map showing where the product category filters are and where the Repeater tab is located.

Click on the ‘Repeater’ tab and you will see your request on the left. Clicking send, you can see the original request’s ‘200 OK’ response on the right.

View of Burp repeater, showing the original request and response.
Original request and response

#1 — Verify SQLi vulnerability injection point.

On the left, in your request, replace your filter with a single quote (‘) and click ‘Send’.

Replace the product filter with a single quote. Response is a 500 internal service error.

A ‘500 Internal Service Error’ response tells us this site may be susceptible to a SQLi attack!

#2 — Determine the exact number of columns AND data types.

In order to use a ‘UNION SELECT’ attack the number of columns AND the data types must match exactly.

One way to find out the number of columns is to use the ‘ORDER BY’ clause. Append ‘ORDER BY 1 — — ‘ to your request. This will tell the server to order the results by the first column. If the is one.

-- Payload
' ORDER BY 1 --

-- URL encoded
'+ORDER+BY+1--

Using the cheat sheet, in the ‘Comments’ section, we can see using the double hyphen at the end will comment out the rest of the line.

Comment out characters for different database types.

Now that we have our ‘ORDER BY’ clause, replace the single quote in your request with the payload.

Before clicking send make sure to URL encode your payload. Burp makes it easy. Just highlight your payload and click ‘Ctrl+u’.

Click ‘Send’. You should see a ‘200 OK’ response. This lets us know that this database has at least one column.

Burp repeater showing ‘ ORDER BY 1’ payload and the ‘200 OK’ response.

Let’s check for two columns now. Change the ‘1’ to ‘2’ and click ‘Send’. You should get another ‘200 OK’ response letting us know that, yes, there are two columns.

-- Payload
' ORDER BY 2--

-- URL encoded
'+ORDER+BY+2--

We do indeed have two columns.

Let’s try to sort by three columns. Replace the ‘2’ in your payload with ‘3’ and click ‘Send’.

-- Payload
' ORDER BY 3--

-- URL encoded
'+ORDER+BY+3--

Burp repeater testing our ‘ORDER BY 3’ payload. Response is a ‘500 Internal Server Error’ letting us know there is not 3 columns.

Getting the ‘500 Internal Server Error’ is telling us that there is NOT a third column to sort by.

We now know how many columns we have. What about the data types of the columns?

Looking at the website we can figure out that the two columns should be the product and the product’s description. Both will be text data types.

We can verify this by injecting text strings onto the page itself by using a ‘UNION SELECT’ statement.

First, recall what the ‘Hint’ portion of this lab tells us:

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

In their example they use the string ‘abc’. This will be fine if the table contained only one column, but we need to modify it for our use since we know we have two.

We will need to add another sting following a comma to get this payload to work.

-- Example payload
' UNION SELECT 'abc' FROM dual

-- Our Payload
' UNION SELECT 'Marduk','James' FROM dual --

-- URL encoded
'+UNION+SELECT+'Marduk','James'+FROM+dual+--

Enter our URL encoded payload into your request and click ‘Send’.

Click ‘Render’ in the response side to see the actual page with your strings injected onto it.

#3 — Verify that the site is, in fact, using an Oracle database.

Technically, this step is not needed to solve this lab since we are already told what type of database we are dealing with. Also the use of ‘dual’ in the previous payload. However, it is good to know how it is done.

Refer back to the provided cheat sheet. Scroll down to find the section “Database version”. Here we can find the query we need to extract this information.

 SELECT banner FROM v$version
NOTE — “banner” is a column in the v$version view. In Oracle databases, a view is a virtual table that is based on the result set of a SQL query.
Unlike a physical table, a view does not store data itself but instead fetches data from the underlying tables whenever it is queried.

This query will have to be modified to fit our needs as well. Since we know we have two columns in the database we are trying to access, ‘banner’ is one column, we will have to add another column to our payload before sending the request.

-- Example payload
SELECT banner FROM v$version

-- Our payload - 'Marduk' can be replaced with NULL
' UNION SELECT banner, 'Marduk' FROM v$version --

-- URL encoded
'+UNION+SELECT+banner,+'Marduk'+FROM+v$version+--

Send your URL encoded payload request and you should receive a ‘200 OK’ response from the server.

#4 — Determine the relevant table name within that database.

Looking at our cheat sheet again, under the ‘Database contents’ section, they give us the syntax needed to find the available tables.

View of our cheat sheet showing SELECT * FROM all_tables

In Oracle, ALL_TABLES is a data dictionary view that provides information about all the tables that a user has access to in the database. Some of the key columns contained in ALL_TABLES include:

OWNER — The schema that owns the table.TABLE_NAME — The name of the table.TABLESPACE_NAME — The tablespace where the table’s data is stored.

We are, of course, interested in TABLE_NAME. A complete list of all the columns contained in ALL_TABLES can be found here.

The cheat sheet tells us we can use ‘SELECT * FROM all_tables’. However, we can not use ‘*’ in our UNION SELECT. The ‘*’ indicates we want ALL the columns in the table, but we only have two columns to join in our UNION.

We will need to modify this query. Our two columns will be ‘table_name’ and ‘NULL’.

-- Example payload
SELECT * FROM all_tables

-- Modified payload
-- Replace * with our 2 columns
' UNION SELECT table_name,NULL FROM all_tables --

-- URL encoded payload
'+UNION+SELECT+table_name,NULL+FROM+all_tables+--

Send your URL encoded payload in Burp repeater and you should receive a list of all the tables in the database in the ‘200 OK’ response.

Use the search function in Burp to easily find the table starting with ‘users’.

NOTE — The string following the underscore is random and will change each time you access the lab.

Now we know the table name we were looking for. Next up, finding the relevant columns that contain the user name and password for the administrator.

#5 — Determine the relevant column names within the table.

Back to the cheat sheet. Oracle has another data dictionary view, like ALL_TABLES, called ALL_TAB_COLUMNS.

 SELECT * FROM all_tab_columns WHERE table_name = ‘TABLE-NAME-HERE’

ALL_TAB_COLUMNS provides information about all columns in tables and views accessible to the current user.

Key columns included in ALL_TAB_COLUMNS are:

TABLE_NAME: The name of the table or view containing the column.COLUMN_NAME: The name of the column.DATA_TYPE: The type of data stored in the column (e.g., VARCHAR2, NUMBER).

You can find the complete list here.

Like the last query, we need to modify the request to meet our needs.

-- Example payload
SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'

-- Modified payload
-- Replace * with our 2 columns and TABLE-NAME-HERE with our table name
' UNION SELECT column_name,NULL FROM all_tab_columns WHERE table_name='USERS_TQNENL'--

-- URL encoded payload
'+UNION+SELECT+column_name,NULL+FROM+all_tab_columns+WHERE+table_name%3d'USERS_TQNENL'--

Add your URL encoded payload to your request and click ‘Send’.

#6 — Find credentials for ‘administrator’.

Our final simple query will give us the usernames and passwords for all users. We are only interested in the administrator’s password to solve the lab.

-- Example payload
SELECT * FROM TABLE-NAME-HERE

-- Modified payload
-- Replace * with column names and TABLE-NAME-HERE with your users_ table
' UNION SELECT USERNAME_ENDVJL, PASSWORD_PTICBH FROM USERS_TQNENL--

-- URL encoded payload
'+UNION+SELECT+USERNAME_ENDVJL,+PASSWORD_PTICBH+FROM+USERS_TQNENL--

Send your URL encoded payload in Burp repeater and your ‘200 OK’ response should reveal all the usernames and passwords. Find ‘administrator’ and it’s corresponding password and head back over to the lab site.

Click on the ‘My account’ link in the upper right hand corner and you will be brought to the login page.

#7 — Log in to the site as ‘administrator’.

Use the found credentials for the administrator to log into the site.

View of log in page using the found credentials.

Once you have logged in, you have solve the lab!

Congratulations! You have solved the lab!

Congratulations! You solved another one! Keep up the hard work!

See you next time!

Read Entire Article