#!/usr/bin/env python3 """Verify the supplied artifact and reproduce the server-accepted CTF flag.""" from __future__ import annotations import argparse import hashlib from decimal import Decimal, ROUND_DOWN from pathlib import Path EXPECTED_SHA256 = "1d8d606687e584e176a700ca426b237dc3077ea075acec3d8f8114f307690273" # Exilenova+ post 11115 labels these as the phone operator's Lat,Long. OPERATOR_LAT = Decimal("43.431717894702786") OPERATOR_LON = Decimal("39.93346527459446") def sha256(path: Path) -> str: digest = hashlib.sha256() with path.open("rb") as stream: for chunk in iter(lambda: stream.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() def truncate_three_decimals(value: Decimal) -> str: """Match the challenge validator: truncate positive coordinates to 3 dp.""" return str(value.quantize(Decimal("0.001"), rounding=ROUND_DOWN)) def main() -> None: parser = argparse.ArgumentParser() parser.add_argument( "video", nargs="?", type=Path, default=Path(__file__).with_name("Drone.mp4"), ) args = parser.parse_args() actual = sha256(args.video) if actual != EXPECTED_SHA256: raise SystemExit( f"unexpected attachment SHA-256: {actual}\nexpected: {EXPECTED_SHA256}" ) # The live validator contradicts the displayed Long,Lat instruction. It # accepts Lat, Long, truncated to three decimals, including this spacing. print( "RTRTNI26{" f"{truncate_three_decimals(OPERATOR_LAT)}, " f"{truncate_three_decimals(OPERATOR_LON)}" "}" ) if __name__ == "__main__": main()