TG:HACK CTF 2020 has been very interesting and intellectually challenging. It made me bang my head on the desk repeatedly in the hopes of numbing the pain of not being able to solve some of the challenges. In the end, I managed to figure out all but the two of the hardest challenges. My writeups are intended to cover the whole process of solving a challenge, so if you don’t want a detailed explanation, just scroll to the payloads.
This one was my favorite out of the bunch. It involves a form that allows you to borrow and return money and a store that lists a flag for the mere price of 1337. All you need for this challenge is an intercepting proxy of your choice, be it Burp or ZAP. The goal here is to find a vulnerable parameter by checking which ones have validation. If you test the borrow and return functions, you will notice that they do not accept negative values, values that are too large or special characters that might break the functionality. If you go to the store and try to buy something, you will see that a purchase only succeeds if the submitted ID and Price correspond to an item with those parameters in the store. If you try to submit ID 13 for the flag with any price other than 1337, you will get an insufficient funds error. The vulnerability here can be discovered by playing around with the id parameter. If you issue a post request to an id that is not used anywhere in the store, you will not get an insufficient funds error, you will have the funds deducted. Since this functionality is unintended, we should expect that there would be no validation of the price parameter, since users were never intended to be able to submit arbitrary values there. If you supply the server with a negative value to a non-existent id, you will get that money back. So, if you issue a post with:
you will now have enough money to buy the flag.
For whatever reason this payload would post everything but the cookie and as it turned out later, the cookie held the flag. I am a little disappointed that a simple bug like this prevented me from properly solving this and forced me to spend over 12 hours on this challenge, but hey, I’ve learned a lot about XMLHttpRequest. The challenge author posted this payload in his writeup:
This should have posted the flag to the forum, but did not in my repeated attempts.
Bobby has forgotten his password for this website. This website greets us with a login prompt and a function for changing the password. This kind of functionality screams “SQL Injection” and the first thing you should of course do is supply special characters to all parameters to see if anything breaks. After I supplied single quotes in every parameter for the password change function, it became apparent to me that there’s SQL Injection here, because the website would spit out the words “unrecognized token” when supplied a single quote in the new password parameter. We know this is a Change Password function, not a regular SELECT query, therefore a normal payload such as ’ OR 1=1 –‘ wouldn’t work. If it’s not a regular SELECT query, what is it? It’s an UPDATE query. We can guess that if we comment out the rest of the query through the new password parameter. It responds with:
We can infer that it takes the username and the old password, finds the record that corresponds to them and then sets the password to the new password that we supply. Here’s the UPDATE query syntax from W3:
We can infer that the query for Bobby looks something like this:
This query expects exactly 3 variables from us and if we supply any less, it will give an error, so that should be the first thing we fix. Since we are able to comment out the WHERE clause of the query, we can replace it with our own:
The following payload would change the password of the user bobby to 123, if there is a user named bobby:
However, if we try to login with these new credentials, we will fail, perhaps because the name is spelled differently or the casing is different, so that problem is easily fixed by also updating the user field like this:
This payload will match the records and change them to bobby with password 123. If we log in with those credentials, we get the flag.