I will share my way of thinking and how I solved two challenges.
Dominoes (Cryptography - 50 points)
We got the encrypted flag:
And we got the python code which encrypted the flag.
Red mark: reads the flag and then sends it to the encryption function (y).
Green mark: (I replaced an obfuscated character with "clearText" for readability). For each character in the flag, it makes an XOR operation (^ - I will use it interchangeably) with the XORed value of it (more precisely, with the integer representation of it - A=65).
For example, if the flag is "BDSEC", the integer representation of "B" (66) will be XORed with "9" (57) which is "{". Then "9" XORed with "D" is "{" as so on, as can be seen in the encrypted flag.
It's possible to make a reverse operation for XOR:
The encrypted flag is: 9{?l)jO;dQa>[oZ#|A)I}N}
9 ^ original_character = {
{ ^ original_character = ?
So I wrote a python code that checks if 9 ^ original_character = { and so on.
Each character of the encrypted message was tested with different characters in order to guess the correct one.
Knight Squad Shop (web - 100 points)
The source code of the web application was provided:
Also access to the web application:
It seemed that there is a 'products' object and one of its instances is 'flags' which contains the flag.
This is what I wanted.
How do I get it? Let's look further into the code.
There are two endpoints: /sell and /buy that are responsible for the buying and selling operations.
Since there was a bug or misconfiguration, I could only try to buy 'digispark'. However, I did not have enough money for it.
I tried to sell products by manually crafting a request to the /sell endpoint and tested some things but I did not see any changes.
How can I get more money?
Looking further into the code, I saw there is another endpoint (/money), that checks if I have an admin session, and if so, it adds the money amount I request in the 'money' parameter.
As I thought and as the code says, I'm not an admin.
How do I get an admin session?
Looking at the code again seems like the request IP should be originated from '127.0.0.1' in order to get an admin session.
Before continuing a bit of information about 'X-Forwarded-For' header:
Basically, front-end servers such as proxies and load balancers use that in order to tell the back-end (web application) server from which IP the request originated.
Let's try it :)
It did not work and I have to find another way.
Maybe if I will cause an error, it will expose interesting information.
I do not know if it is correct but knowing that asynchronous functions are sometimes vulnerable to race condition + I read that 'req.ip' could be affected by 'X-Forwarded-For:' header, I tried to cause some kind of race condition by adding 'X-Forwarded-For: 127.0.0.1' to the request, and changing the 'Origin' and 'Referrer' headers to this IP address, just in case.
And it worked.
"Money added".
Using the same session I added a lot of money.
But still, I do not have enough money. How is it that my session does not have enough money?
Is there a chance that the money is added to the session in the 'Set-Cookie' response header?
I tried to buy the flag by replacing my session with the session in the 'Set-Cookie' header and it worked.
I tried it again and only sometimes it works for me so I am not sure exactly if all of these steps were necessary.
Also, before trying that, I uploaded the source code to Snyk for vulnerability scanning and it found a Prototype Pollution vulnerability, and as far as I understood, it may be another solution for this challenge.
Please let me know if there were inaccuracies or any other insights about this solution.
Orel 🍉
Comments