🗂️PortSwigger Lab Writeup: SQL Injection UNION Attack - Retrieving Multiple Values in a Single Column

🎯 Objective
The objective of this lab is to exploit a Union-based SQL injection vulnerability in a web application where the application executes a SQL query with user-supplied input in unsafe way to filter the products and our goal is to retrieve all usernames and passwords from a table - users as well as concatenate it to retrieve multiple values within a single column.
- Lab URL:
https://portswigger.net/web-security/sql-injection/union-attacks/lab-retrieve-multiple-values-in-single-column - Category: SQL Injection
- Difficulty: Practitioner
💉 Payloads Used
1. For determining no of columns :-
- Payload 1 - ✅
Gifts'+UNION+SELECT+NULL,NULL--
2. For determining column containing text :-
- Payload 2 - ❌
Gifts'+UNION+SELECT+'a',NULL--
- Payload 3 - ✅
Gifts'+UNION+SELECT+NULL,'a'--
3. For extracting usernames and passwords :-
- Payload 4 - ✅
Gifts'+UNION+SELECT+NULL,username||'~'||password+FROM+users--
🧪 Exploitation Steps
🕵️Step 1: Observe the Website
- Firstly open the lab URL in your browser, and observe what it is about and how it works.


- At first glance, the website seems to be a shopping website with an option to filter products on different categories and also there is a login page. In the lab description, it is mentioned that the vulnerability is in the filter parameter which is being used directly in a SQL query.
🔍Step 2: Find the Vulnerable Endpoint
- Click on any one of the filter to see how website behaves and where the filter parameter is passed to server.

- Here, the site filters the products by supplying the category name in URL -
/filter?category=...
🚀Step 3: Inject the Payload
- Based on my initial observation of the website, it seems that the application is returning two columns, but still we will verify the the no of columns by using payload -
Pets'+UNION+SELECT+NULL,NULL--
- Hence, it is confirmed that the application is returning two columns and now, we will determine which column is returning string data by placing a text value instead of
NULLin each place. - So, lets first place our first payload -
Gifts'+UNION+SELECT+'a',NULL--.
- Hence this payload did not worked and returned an Internal Server Error. So, we try another payload -
Gifts'+UNION+SELECT+NULL,'a'--
- This payload executed successfully, confirming that second column is returning string data.
- Now, we will exploit this functionality by retrieving all the usernames and passwords from a table
usersand concatenating both within a single column as only one columns in query is of string datatype. - Based on my observation, the application might be running a SQL query -
SELECT id, title FROM products WHERE category = '$category';. So, to exploit this query, we will inject the payload -Gifts'+UNION+SELECT+NULL,username||'~'||password+FROM+users--which after injection will become -SELECT id, title FROM products WHERE category = 'Gifts'+UNION+SELECT+NULL,username||'~'||password+FROM+users--';and after successful execution, it will return all the usernames and passwords in a single column.
- Hence, it successfully returned all the three usernames and password stored in
userstable in the format -username~password. - Now, open the login page in new tab and copy paste the details of administrator to complete the final task of this lab.

- And💥Booom!, We got the access of Admin account on the website.
- And Finally, the Lab is solved.
🧠 Conclusion
- This lab involves a basic case of SQL injection vulnerability, where the
categoryparameter is used to filter products where the application directly concatenates the user-supplied category in the SQL query to fetch only the relevant products. - Since the application neither validates the user-input nor uses prepared statement, an attacker can manipulate the SQL query by injecting any arbitrary SQL commands to gain full access of the database.
- By injecting
Gifts'+UNION+SELECT+NULL,username||'~'||password+FROM+users--in thecategoryparameter, we are able to retrieve all the usernames and passwords stored in the database.