Tags: xor recovery seed

Rating:

# Tony And James Writeup (45 solves / 472 points)
> :arrow_down: [Chall FIle](https://github.com/r3yc0n1c/CTF-Writeups/raw/main/2021/darkCON-2021/Crypto/Tony%20And%20James/dist/Tony%20And%20James.zip)

### [Source Script](dist/src.py)
py
#!/usr/bin/env python3
import random

# custom seed generation
def get_seed(l):
seed = 0
rand = random.getrandbits(l)
raw = list()

while rand > 0:
rand = rand >> 1
seed += rand
raw.append(rand)

if len(raw) == l:
return raw, seed
else:
return get_seed(l)

def encrypt(m):
l = len(m)

raw, seed = get_seed(l) # get raw_state and seed
random.seed(seed)

with open('encrypted.txt', 'w') as f:
# char by char encoding of the FLAG
for i in range(l):
r = random.randint(1, 2**512)
if i == 0:
print("r0 =",r) # the 1st random number (r0) that we have
encoded = hex(r ^ m[i] ^ raw[i])[2:]
f.write(f"F{i}: {encoded}\n")

def main():
encrypt(m.encode()) # Encrypt the FLAG

if __name__=='__main__':
main()


The leakage of 1st generated random number makes the encryption vulnerable because we already know the flag format.

So we can use the leaked random number and the **Known Plaintext Attack** on the **XOR Encryption** to obtain the **seed**.

After generating the seed, we can set the seed and we will obtain the same random numbers that were used in the encryption

([same seed produces same random numbers](https://stackoverflow.com/questions/22639587/random-seed-what-does-it-do#answer-22639752))
and then decrypt the flag.

### [Solve Script](sol/apex.py)
py
import random

def get_seed(raw_00, l):
seed = 0
raw = [raw_00]
for i in range(1,l):
seed += raw_00
raw.append(raw_00 >> 1)
raw_00 = raw_00 >> 1
return raw, seed

def decrypt(file, r0):
"""
By Properties of XOR,

encoded[i] = r ^ m[i] ^ raw[i]
raw[i] = r ^ m[i] ^ encoded[i]

For i = 0 we know,
m = 'd' ( because flag format is darkCON{} )
r = r0
encoded = first encoded hex (F0)
"""
# Calculate start of seed
raw_00 = r0 ^ ord('d') ^ int(file.split(': '), 16)
l = len(file)
raw, seed = get_seed(raw_00, l)
random.seed(seed)

flag = ''
for i in range(l):
x = int(file[i].split(': '), 16)
r = random.randint(1, 2**512)
flag += chr(x ^ raw[i] ^ r)
print(flag)