Published on

DownUnderCTF 2023 – Randomly chosen

Authors
  • avatar
    Name
    Lumy
    Twitter

Randomly chosen

Can you recover the flag from this random jumble of characters?

Table of Contents

  1. Source code
  2. Solution

Source code

randomly-chosen.py

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)

output.txt

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

Solution

random.seed is called with an unkown, but small value which may be bruteforced. The random.choices call is taking random characters from the flag to get the string given in the output.txt file. If you know the random seed, you can figure out which random characters it took and reverse the process to unscramble the flag.

import random

output = open('output.txt', 'r').read().strip()
flag_len = len(output) // 5
for seed in range(1337):
    random.seed(seed)
    choices = random.choices(list(range(flag_len)), k=len(output))
    flag = [''] * len(output)
    for i, v in enumerate(choices):
        flag[v] = output[i]
    flag = ''.join(flag)
    if flag.startswith('DUCTF'):
        print(flag)

FLAG : DUCTF{is_r4nd0mn3ss_d3t3rm1n1st1c?_cba67ea78f19bcaefd9068f1a}