#!/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)