38 lines
1.1 KiB
Python
38 lines
1.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
solve.py
|
|
Automates fetching observed outputs, recovering LCG params, computing next token,
|
|
and requesting /flag?token=<predicted>.
|
|
Usage: python3 solve.py http://127.0.0.1:9001
|
|
"""
|
|
import sys
|
|
import requests
|
|
from solve_lcg import recover_params, next_value
|
|
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python3 solve.py <base_url>")
|
|
sys.exit(1)
|
|
|
|
base = sys.argv[1].rstrip("/")
|
|
api = base + "/api/observed"
|
|
r = requests.get(api, timeout=5)
|
|
r.raise_for_status()
|
|
j = r.json()
|
|
observed = j["observed"]
|
|
if len(observed) < 3:
|
|
print("Need at least 3 observed outputs.")
|
|
sys.exit(1)
|
|
|
|
x0, x1, x2 = [int(x) & 0xffffffff for x in observed[:3]]
|
|
a, c = recover_params(x0, x1, x2)
|
|
if a is None:
|
|
print("Failed to recover parameters; difference was not invertible modulo 2^32.")
|
|
sys.exit(1)
|
|
nxt = next_value(x2, a, c)
|
|
print("[*] Recovered a=0x%08x c=0x%08x" % (a, c))
|
|
print("[*] Predicted next token (dec):", nxt)
|
|
print("[*] Requesting flag...")
|
|
r2 = requests.get(base + "/flag", params={"token": str(nxt)}, timeout=5)
|
|
print("[*] Response:", r2.status_code)
|
|
print(r2.text)
|