Voucher Vault
Redzone Rewards — an internal employee rewards portal — exposes a voucher search that concatenates user input straight into a SELECT. Find the hidden administrative voucher.
Room Description
https://dashboard.webverselabs-pro.com/challenges/voucher-vault

Scenario
One of the Redzone security interns was auditing the new Rewards portal during launch week and flagged something off in the voucher-search logic. Before they could open a ticket they got pulled into a different project. Finish what they started: pull the hidden admin voucher.
Objective
Redzone Rewards — an internal employee rewards portal — exposes a voucher search that concatenates user input straight into a SELECT. Find the hidden administrative voucher.
Initial Analysis
When opening the URL we are met with the following landing page:

I don't see anything of value here, I think this is just fluff to immerse the user in to the application and real world application. We have the credentials under staging credentials if we ever need them.

Okay, so, the challenge description explicitly states that we are looking for a voucher search function and unsurprisingly there is a Search Vouchers tab :eyes:.
Finding the bug
Going over to /search.php we see the following function:


We have control over the q parameter. Let's try to add ' or " and see if we can get an error.

Okay, so we know that there were no matches for test, so we can be 100% sure this isn't the response when there is no match, we are definitely causing issues with the query that is being sent to the backend, this confirms our injection point.
Let's try to inject an always true statement. We will add a trailing dash (I usually try with and without to see if the rest of the query needs to be commented out)
' OR 1=1-- -

Okay! So we have output, and this should return all of the vouchers we have, but this isn't our goal currently (or well, in a production environment, that LEARNBUDGET and QUARTER100 look amazing to me), we need to see how many columns this query is working with.
Exploitation
We start off with:
' ORDER BY 1-- -
until we get an error, then we know that the last query that worked is the number of columns we are working with.


We know we have 3 columns now! We can try UNION based attacks to start gathering information!
https://portswigger.net/web-security/sql-injection/union-attacks
' UNION SELECT 1,2,3-- -

Okay, we now see where our output would be, let's find the database name.
' UNION SELECT database(),2,3-- -

Now that we know the database name we can add a WHERE clause that would help us with enumerating the tables within, otherwise we get a bunch of results that we might not need (not necessarily, for harder labs, it is best if we can search through everything)
' UNION SELECT table_name,2,3 FROM information_schema.tables-- -

As we can see, a bunch of table names, we need that WHERE clause.
' UNION SELECT table_name,2,3 FROM information_schema.tables WHERE table_schema=database()-- -

Well the challenge states the following twice:
Finish what they started: pull the hidden admin voucher.Find the hidden administrative voucher.
So it's a no-brainer which table we need. Let's list all the column names in admin_vouchers.
' UNION SELECT column_name,2,3 FROM information_schema.columns WHERE table_name='admin_vouchers'-- -

Make sure to add quotes around admin_vouchers.
We have control over 3 column outputs, so we might need to disregard id if we want the output to show all at once for example, since know id is probably going to be 1,2,3++ etc.
' UNION SELECT code,value,expiry FROM admin_vouchers-- -

Conclusion
This is a Challenge marked as Medium, but is more or less the same tactic as the Foundational lab Flower. So it is nice to start off with an easy challenge and then work your way up, methodology repetats itself during engagements as well.