The Question

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.


The Solution

seed.py is a simple program that creates a SHA256 hash of a seeded random number. If the string b9ff3ebf is in the hash, it writes the flag to a file:

#!/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:
                print(f"dam{{{flag}}}")
            f.close()
            break

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

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

log.txt is a red-herring and not necessary.

The vulnerability is that – like most “random” numbers – the numbers aren’t actually random, they are pseudo-random. Using round() with time.time() creates a large integer (the whole number of the time since epoch), and since I can assume the challenge was created somewhat recently, I just bruteforced it by iterating backwards from my current time:

#!/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():
    s = seed()
    random.seed(s, version=2)
    x = random.random()
    flag = hash(x)
    while 'b9ff3ebf'not in flag:
        s -= 1
        random.seed(s, version=2)
        x = random.random()
        flag = hash(x)
    print(f"dam{{{flag}}}")

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

After about a minute, I got the flag: dam{f6f73f022249b67e0ff840c8635d95812bbb5437170464863eda8ba2b9ff3ebf}