Swag Shop
Challenge URL: https://hackyholidays.h1ctf.com/swag-shop
Methodology
This is Grinch’s swag shop, time to see what’s on sale!
Clicking on “Purchase” of any of these items brings up a login modal. Unfortunately, an attempt of SQL injection (or 1; -- -
) did not allow us to bypass the authentication.
Looking at the requests being sent from my previous actions, I observed that there were 2 POST
requests made:
/api/purchase
/api/login
Both requests were responded with a 401 Unauthorized
response code.
With nowhere else to go, it was time to fuzz the API end-points of this swaggity-swag shop.
Fuzzing API End-points
I did not wish for things to head this direction, but seems like there are no other options. 😩
My choice of tool was Burp Intruder and I used the objects.txt
wordlist from Daniel Miessler’s seclists here. Then, setting up Intruder to fuzz the end-points at /api/<FUZZ>
:
Since the wordlist contained (what I think are) irrelevant entries like version strings, I made sure to ignore them in my Intruder settings, using the regex /v[\d]*\.*[\d]+/
:
And going for a short ☕ break while waiting for the attack to run…
When I returned, I was greeted with 2 valid end-points (no 404
response):
/api/sessions
/api/user
I examined the sessions
end-point first, noticing that there are 8 sets of base-64 encoded strings, so I went to decode them:
$ echo "eyJ1c2VyIjoiQzdEQ0NFLTBFMERBQi1CMjAyMjYtRkM5MkVBLTFCOTA0MyIsImNvb2tpZSI6Ik5EVTBPREk1TW1ZM1pEWTJNalJpTVdFME1tWTNOR1F4TVdFME9ETXhNemcyTUdFMVlXUmhNVGMwWWpoa1lXRTNNelUxTWpaak5EZzVNRFEyWTJKaFlqWTNZVEZoWTJRM1lqQm1ZVGs0TjJRNVpXUTVNV1E1T1dGa05XRTJNakl5Wm1aak16WmpNRFEzT0RrNVptSTRaalpqT1dVME9HSmhNakl3Tm1Wa01UWT0ifQ==" | base64 -d; echo
{"user":"C7DCCE-0E0DAB-B20226-FC92EA-1B9043","cookie":"NDU0ODI5MmY3ZDY2MjRiMWE0MmY3NGQxMWE0ODMxMzg2MGE1YWRhMTc0YjhkYWE3MzU1MjZjNDg5MDQ2Y2JhYjY3YTFhY2Q3YjBmYTk4N2Q5ZWQ5MWQ5OWFkNWE2MjIyZmZjMzZjMDQ3ODk5ZmI4ZjZjOWU0OGJhMjIwNmVkMTY="}
After decoding, I realized that all but 1 of them had the user
parameter set to null
. So, it is possible that only this session string is valid.
Next, I examined the user
end-point, which had a 400
response code from the server, stating that there are missing parameters. Well, since I had to fuzz to find these end-points, maybe the parameter had to be fuzzed as well? 🤔
Setting up my Burp Intruder yet again, this time using burp-parameter-names.txt
wordlist from the same seclists repository here. I was going to fuzz /api/user?<FUZZ>=aaa
(random string used as value):
… Maybe a 🍕 break this time? 😋
After the fuzz has completed, I found that uuid
is the mystery parameter that I need for this user
end-point!
Since the server response mentioned about matching uuid
, remember where we obtained a uuid
-looking string? That’s right, at the sessions
end-point!
"user":"C7DCCE-0E0DAB-B20226-FC92EA-1B9043"
Time to utilize the decoded string:
Which gave me the flag at last!
Flag: flag{972e7072-b1b6-4bf7-b825-a912d3fd38d6}
Thoughts 🎯
This challenge was unexpectedly tricky, probably because I did not expect there to be fuzzing challenges (server load and all, with such a large participation too). However, once the mental barrier has been cleared, I just had to find a nice wordlist. Luckily, seclists can always be depended on. 😎
There were rabbit holes that I fell into, such as trying to use the decoded session cookie
key to gain authentication at previously known end-points. Being too fixated on gaining authentication was most likely a common pitfall for most of us, especially when the client-side JavaScript code looked so sus.