#!/usr/bin/env python3 from fastecdsa.curve import Curve from fastecdsa.point import Point from base64 import urlsafe_b64decode, urlsafe_b64encode from zlib import crc32 import requests import json import re import sys import time HOST = sys.argv[1] PORT = 14000 url = f"http://{HOST}:{PORT}" r = requests.get(f"{url}/params").text r = r.replace("
", "").replace("
", "") params = json.loads(r) # print(params) C = Curve( "burvesigner", params["p"], params["a"], params["b"], params["n"], params["G"][0], params["G"][1], ) G = C.G Y = Point(params["Y"][0], params["Y"][1], C) b64p = lambda x: x + b"=" * (-len(x) % 4) b64u = lambda x: x.rstrip(b"=") b64e = lambda x: b64u(urlsafe_b64encode(x)) b64d = lambda x: urlsafe_b64decode(b64p(x)) def get_token(): r = requests.post(url, data={"username": "guest", "password": "guest"}).cookies return r["token"] token1 = get_token() token2 = get_token() # print(token1) # print(token2) sig1 = token1.split(".")[1] sig2 = token2.split(".")[1] t = 112 // 8 shift_u = pow(2, 112 - 64) def from_bytes(data): return int.from_bytes(data, "little") def to_bytes(num): return int.to_bytes(num, t, "little") sig1dec = urlsafe_b64decode(sig1) arr1 = [sig1dec[t * i : t * (i + 1)] for i in range(3)] Rx1, Ry1, s1 = map(from_bytes, arr1) sig2dec = urlsafe_b64decode(sig2) arr2 = [sig2dec[t * i : t * (i + 1)] for i in range(3)] Rx2, Ry2, s2 = map(from_bytes, arr2) R1 = Point(Rx1, Ry1, C) R2 = Point(Rx2, Ry2, C) # bf diff for bf in range(1, 2**20): diff = bf * shift_u if R1 + G * diff == R2: # print(bf, diff) break def apa(msg): return crc32(msg) def fake_sign(msg, x): k = 555555 R = k * C.G s = (apa(msg) - x * R.x) * pow(k, -1, C.q) % C.q sig = b"".join(map(to_bytes, [R.x, R.y, s])) return urlsafe_b64encode(sig) def dup_verify(msg, sig): assert len(sig) == 4 * t sig = urlsafe_b64decode(sig) arr = [sig[t * i : t * (i + 1)] for i in range(3)] Rx, Ry, s = map(from_bytes, arr) R = Point(Rx, Ry, C) return apa(msg) * C.G == s * R + Y * R.x payload = b64e( json.dumps( {"user": "admin", "role": "admin", "exp": int(time.time()) + 300} ).encode() ) h1 = apa(token1.split(".")[0].encode()) h2 = apa(token2.split(".")[0].encode()) h3 = apa(payload) k1 = (Rx1 * h2 - Rx1 * s2 * diff - Rx2 * h1) * pow(Rx1 * s2 - s1 * Rx2, -1, C.q) % C.q priv = (h1 - s1 * k1) * pow(Rx1, -1, C.q) % C.q sig3 = fake_sign(payload, priv) # print(k1, priv, to_bytes(priv)) token3 = payload + b"." + sig3 token3 = token3.decode() # print(token3) r = requests.get(url, cookies={"token": token3}).text if "flashes" in r: print("failed") exit(1) flag = re.findall(r'Welcome, admin! (.+)

', r)[0] print(flag)