This post spoils a CTF challenge … Don’t read if you want to try it !

Sogeti CTF was a qualifier for the Sogeti Cyber E-Scape. I could not find a team to participate in this event, so I played alone and finally managed to find a team for the final :)

[+] Presentation

Will you be able to beat the machine? This one is programmed to send you an encrypted challenge. Your task is to decipher this challenge and send it back to the machine in less than 2 seconds.

A copy of the program is provided

nc quals.shadow-league.org 5002

[+] Finding the bug

When you connect, the server asks you to decrypt the encrypted challenge it sent in less than 2 seconds.
The server leaks a part of the AES key.

network

The problem is that the key used to encrypt the challenge is ‘random’, and I personally don’t know how to decrypt AES without knowing the key :D
The key is generated by xoring 10 times 0xffffffff with a randomly generated value between 0 and 0xffffffff and hashing the result (SHA-256), so it’s probably unpredictable (at least not in a few seconds).

The fail is right here :

pprint("Random initialization vector", "INFO")
random.seed(random.randint(1,10000))
pprint("Seed generated !", "SUCCESS")

The seed used to initialize the pseudo-random numbers generator is not really random … It’s between 1 and 10000.
For a given seed, the random numbers generation sequence is the same…
As an example :

network

So the ‘random’ AES key is only choosen between 10000 possible keys …
We just have to generate all possible keys, and compare the hint given by the server to our key list to determine which key has been used.
After that, let’s decrypt the challenge received with this key.
Here is my solution script.

network

Flag : SCE{Str0ng_s3eds_are_adv1s3d…}

[+] Bye

Feel free to tell me what you think about this post :)