#!/usr/bin/env python3
import os
import re
import sys
from scapy.all import rdpcap, ICMP, TCP, Raw

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

PCAP_CANDIDATES = [
    os.path.join(SCRIPT_DIR, "..", "public", "pinecraft_incident.pcap"),
]

pcap_path = None
for candidate in PCAP_CANDIDATES:
    if os.path.exists(candidate):
        pcap_path = candidate
        break

if pcap_path is None:
    print(f"[!] PCAP not found in {PCAP_CANDIDATES}", file=sys.stderr)
    sys.exit(1)

packets = rdpcap(pcap_path)

# Flag 1: Exploited endpoint from HTTP POST (path traversal)

flag1_found = False
xor_key = None

for pkt in packets:
    if TCP in pkt and Raw in pkt:
        payload = bytes(pkt[Raw]).decode("utf-8", errors="ignore")

        if not flag1_found and "POST /api/plugins/upload" in payload:
            m = re.search(r"POST (/[^\s?]+)", payload)
            if m:
                endpoint = m.group(1)
                print(f"Flag 1: vsosh{{{endpoint}}}")
                flag1_found = True

        if xor_key is None and "X-Session-Key:" in payload:
            m = re.search(r"X-Session-Key:\s*(\S+)", payload)
            if m:
                xor_key = m.group(1)

if not flag1_found:
    print("[!] Flag 1 not found — no POST /api/plugins/upload in traffic", file=sys.stderr)

# Flag 2: Hex-encoded data from ICMP covert channel (id=0x1337)

icmp_1337 = []
for pkt in packets:
    if ICMP in pkt and pkt[ICMP].type == 8 and pkt[ICMP].id == 0x1337:
        if Raw in pkt:
            icmp_1337.append((pkt[ICMP].seq, bytes(pkt[Raw])))

if icmp_1337:
    icmp_1337.sort(key=lambda x: x[0])
    hex_str = b"".join(data for _, data in icmp_1337).decode("utf-8", errors="ignore")
    try:
        decoded = bytes.fromhex(hex_str).decode()
        print(f"Flag 2: vsosh{{{decoded}}}")
    except (ValueError, UnicodeDecodeError) as e:
        print(f"[!] Flag 2 hex decode error: {e}, raw hex: {hex_str}", file=sys.stderr)
else:
    print("[!] Flag 2 not found — no ICMP Echo Request with id=0x1337", file=sys.stderr)

# Flag 3: XOR-encrypted data from ICMP covert channel (id=0x4D43)

if xor_key is None:
    # Fallback to known key from generate script
    xor_key = "p1n3cr4ft"
    print(f"[*] X-Session-Key not found in HTTP headers, using default: {xor_key}",
          file=sys.stderr)

icmp_4d43 = []
for pkt in packets:
    if ICMP in pkt and pkt[ICMP].type == 8 and pkt[ICMP].id == 0x4D43:
        if Raw in pkt:
            icmp_4d43.append((pkt[ICMP].seq, bytes(pkt[Raw])))

if icmp_4d43:
    icmp_4d43.sort(key=lambda x: x[0])
    encrypted = b"".join(data for _, data in icmp_4d43)
    key_bytes = xor_key.encode()
    decrypted = bytes(b ^ key_bytes[i % len(key_bytes)] for i, b in enumerate(encrypted))
    try:
        print(f"Flag 3: vsosh{{{decrypted.decode()}}}")
    except UnicodeDecodeError as e:
        print(f"[!] Flag 3 decode error: {e}, raw decrypted: {decrypted!r}", file=sys.stderr)
else:
    print("[!] Flag 3 not found — no ICMP Echo Request with id=0x4D43", file=sys.stderr)
