#!/usr/bin/env python3 """ Brute-forcer for Guess the Seed. Usage: python3 solve.py http://127.0.0.1:9000 What it does: - Fetches /api/observed to retrieve observed tokens and the time window - Brute-forces candidate seeds in the inclusive window to find the seed that reproduces the observed tokens in order - Predicts the next token (the required one) and prints it - Optionally attempts to fetch /flag?token= and prints the response """ import sys import requests import hashlib import random import time def token_from_seed(s): rnd = random.Random(int(s)) val = rnd.getrandbits(64) h = hashlib.sha256(str(val).encode()).hexdigest()[:16] return h if len(sys.argv) < 2: print("Usage: python3 solve.py http://host:port") sys.exit(1) base = sys.argv[1].rstrip("/") api = base + "/api/observed" print("[*] Fetching observed tokens from", api) r = requests.get(api, timeout=5) r.raise_for_status() j = r.json() observed = j["observed"] ws = int(j["window_start"]) we = int(j["window_end"]) print("[*] Observed tokens:", observed) print("[*] Window:", ws, we) found = False match_seed = None # Brute force seed candidates in window for seed in range(ws, we+1): ok = True for idx, obs in enumerate(observed): cand = token_from_seed(seed + idx) if cand != obs: ok = False break if ok: match_seed = seed print("[+] Found matching seed:", seed) found = True break if not found: print("[-] No seed found in window.") sys.exit(1) pred = token_from_seed(match_seed + len(observed)) print("[*] Predicted next token:", pred) # Attempt to fetch flag flag_url = f"{base}/flag?token={pred}" print("[*] Requesting flag from:", flag_url) r2 = requests.get(flag_url, timeout=5) print("[*] Response:", r2.status_code) print(r2.text)