Can you recover the flag from this random jumble of characters?
Author: joseph
Tags: crypto
We are offered with a python script and a textfile:
import random
random.seed(random.randrange(0, 1337))
flag = open('./flag.txt', 'r').read().strip()
out = ''.join(random.choices(flag, k=len(flag)*5))
print(out)
bDacadn3af1b79cfCma8bse3F7msFdT_}11m8cicf_fdnbssUc{UarF_d3m6T813Usca?tf_FfC3tebbrrffca}Cd18ir1ciDF96n9_7s7F1cb8a07btD7d6s07a3608besfb7tmCa6sasdnnT11ssbsc0id3dsasTs?1m_bef_enU_91_1ta_417r1n8f1e7479ce}9}n8cFtF4__3sef0amUa1cmiec{b8nn9n}dndsef0?1b88c1993014t10aTmrcDn_sesc{a7scdadCm09T_0t7md61bDn8asan1rnam}sU
The output obviously is generated by the script and contains the flag but very scrambled. Manually assembling the flag from this output will not work. But since the RNG used is producting pseudo random numbers we can reconstruct the random choices by knowing the correct seed. Since the seed is in range 0-1337 the search space is small enough to try all possible seeds.
For every seed we take random choices and remap the character indice from the output to get the original ordering. This is done for each and every seed (in range 0-1337) until we find a seed that gives the correct flag.
import random
data = open("output.txt").read()
flag_len = len(data)//5
indices = list(range(0,flag_len))
for i in range(0, 1337):
random.seed(i)
out = random.choices(indices, k=flag_len*5)
flag = [""]*(flag_len)
for i, x in enumerate(out):
flag[x] = data[i]
flag = "".join(flag)
if flag.startswith("DUCTF"):
print(flag)
break
Flag DUCTF{is_r4nd0mn3ss_d3t3rm1n1st1c?_cba67ea78f19bcaefd9068f1a}