# DarkCON CTF 2021 - Tony And James1

## The challenge

This challenge basically consisted in recovering a flag that was encrypted using an algorithm based on random numbers generation from a seed, knowing only the first number generated and the encrypted text.

## The algorithm

The algorithm used to encrypt the flag was as follows:

First, the length **l** of the plain message **m** is calculated and used as input for the function getrandbits() from Python’s module random, obtaining a random number rand of l bits. Then, **rand** is bit-shifted to the right (which is equivalent to dividing by 2) until it reaches 0, and its value is added to **seed** and appended to the list **raw** at each iteration. At the end, **raw** would have a size of **l** and \(seed=\sum_{i=1}^l \frac{rand}{2^{i}}\) (the sum of all elements at **raw**). This seed is used in random.seed() to initialize Python’s PRNG (Pseudo Random Number Generator).

The encryption is then performed using a bitwise xor between each character of the text, an element from **raw** with the same index and a random number generated from the seed.

## Tony Stark and James Rhodes

One of the files provided for this challenge was a PDF containing a transcription of the fictional conversation between Tony Stark (the player) and James Rhodes (the guy that encrypted the flag). At the end of this transcription, we have a big clue to solve this challenge, the first random number (**r0**) generated from the seed during the encryption.

## Recovering the seed

Normaly, knowing only the first number from a random sequence would not help that much, but on this case, it is all that we need to recover the seed and with that the whole text.

Remember that for each character with index i, we do a xor with raw[i] and a new random number. What means that if we already know the first random number, and also the first characters of the flag (which has the format darkCON{.+}), we can find raw[0]. Because of how the list **raw** is filled, we have that raw[i+1] is equal to raw[i] / 2. And as **seed** is the sum of the elements on this list, it can be recovered as well.

Looking into the file encrypted.txt we have one line for each character of the flag, with the hex representation of the encrypted character. To recover the list **raw**, we can start with **F0** (the first character) and after converting it to a base 10 number, perform an xor with **r0** and the already known decrypted value of it ‘d’, obtaining raw[0]. After that, we can repeat the steps of the encryption algorithm to find the remaining values:

Finally, we use the value of **seed** to seed the PRNG and repeat the same steps of the encryption routine to get the flag back.

## Full decryption code

My final code was something like:

And the flag was: darkCON{user_W4rm4ch1ne68_pass_W4RM4CH1N3R0X_t0ny_h4cked_4g41n!}