keyboard_arrow_up

title: Writeup DamCTF 2021 - seed
date: Nov 10, 2021
tags: DamCTF writeups reverse


Writeup DamCTF 2021 - seed

Description:

Having a non-weak seed when generating "random" numbers is super important! Can you figure out what is wrong with this PRNG implementation?

seed.py is the Python script used to generate the flag for this challenge. log.txt is the output from the script when the flag was generated.

What is the flag?

Author: m0x
342 solves / 249 points

Files:

seed.py

log.txt


It seems like we will have to deal with a not-really-random number generator considering what the description says.

Let's take a look at the provided code and log:

#!/usr/bin/env python3
import sys
import time
import random
import hashlib

def seed():
    return round(time.time())

def hash(text):
    return hashlib.sha256(str(text).encode()).hexdigest()

def main():
    while True:
        s = seed()
        random.seed(s, version=2)

        x = random.random()
        flag = hash(x)

        if 'b9ff3ebf' in flag:
            with open("./flag", "w") as f:
                f.write(f"dam{{{flag}}}")
            f.close()
            break

        print(f"Incorrect: {x}")
    print("Good job <3")

if __name__ == "__main__":
   sys.exit(main())

It uses the timestamp to generate a random number, then creates it's hash and check if a string is present in the hash.

Incorrect: 0.3322089622063289
Incorrect: 0.10859805708337256
Incorrect: 0.39751456956943265
Incorrect: 0.6194981263678604
Incorrect: 0.32054505821893853
Incorrect: 0.2674908181379442
Incorrect: 0.5379388350878211
Incorrect: 0.7799698997586163
Incorrect: 0.6893538761284775
Incorrect: 0.7171513961367021
Incorrect: 0.29362186264112344
Incorrect: 0.06571100672753238
Incorrect: 0.9607588522085679
Incorrect: 0.33534977507836194
Incorrect: 0.07384192274198853
Incorrect: 0.1448081453121044
Good job <3

The log shows that it works for a certain timestamp. We will modify the script to return to the past by decreasing the timestamp at each test!

#!/usr/bin/env python3
import sys
import time
import random
import hashlib

def seed():
    print(round(time.time()))
    return round(time.time())

def hash(text):
    return hashlib.sha256(str(text).encode()).hexdigest()

def main():
    timestamp = round(time.time()) # get current timestamp
    while True:
        s = timestamp
        random.seed(s, version=2)

        x = random.random()
        flag = hash(x)

        if 'b9ff3ebf' in flag:
            with open("./flag", "w") as f:
                f.write(f"dam{{{flag}}}")
            f.close()
            break

        # print(f"Incorrect: {x}\nTime: {timestamp}")
        timestamp-= 1 # decrease the timestamp (time traveling!)
    print("Good job <3")

if __name__ == "__main__":
   sys.exit(main())

After a little time, the program stops and the file flag is created:

$ ./seed_modified.py
Good job <3

$ cat flag
dam{f6f73f022249b67e0ff840c8635d95812bbb5437170464863eda8ba2b9ff3ebf}

Flag: dam{f6f73f022249b67e0ff840c8635d95812bbb5437170464863eda8ba2b9ff3ebf}