Chronohack

Published: April 2, 2025Updated: December 9, 2025

Description

You intercepted ABC School’s token generator. It seeds Python’s Mersenne Twister with `int(time.time()*1000)` and gives you 50 guesses. Synchronize on the server time, brute-force the nearby millisecond range, and submit the matching token.

Study token_generator.py to learn the alphabet, seed, and token length (20 characters).

Connect to `nc verbal-sleep.picoctf.net 64704` and synchronize with the server time when sending guesses.

pip install pwntools
python3 script.py # see snippet below

Solution

  1. Step 1Replicate get_random
    Reimplement the provided `get_random()` locally but accept a custom time argument. Seed with `int(t*1000)` to mimic the challenge.
  2. Step 2Brute-force nearby timestamps
    When the socket connects, record `time.time()` and iterate ± a few milliseconds (increments of 0.001). For each candidate seed, generate the token and submit it. Within 50 tries one guess matches and the server prints the flag.
    from pwn import * import random, time def get_random(length, t): alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" random.seed(int(t*1000)) return "".join(random.choice(alphabet) for _ in range(length)) p = remote("verbal-sleep.picoctf.net", 64704) base = time.time() for i in range(50): guess = get_random(20, base + i*0.001) p.recvuntil(b"):") p.sendline(guess.encode()) line = p.recvline() if b"Congratulations" in line: print(p.recvline().decode()) break

Flag

picoCTF{UseSecure#$_Random@j3n3r@T0rsd...}

Network jitter means you may need to rerun the script, but scanning a 50 ms window is enough.