Orel Gispan
BDSEC 2022 CTF Writeups
Updated: Jul 22, 2022
I will share my way of thinking and how I solved two challenges.
Knight Squad Shop (web - 100 points)
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:
https://drive.google.com/file/d/1cHCasWHdfl21q2XrATET_jy0fDQ2gfMK/view
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 🍉