Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-19490-check — Citrix NetScalerのSAML認証バイパスCVE-2026-19490を安全に検出 | Kitploit
ツール/GitHubGitHub/bishopfox/cve-2026-19490-check
防御ツール脆弱性スキャナーウェブ脆弱性スキャナー脆弱性分析情報収集ウェブセキュリティネットワークセキュリティペネトレーションテスト認証
GitHubbishopfox/cve-2026-19490-check

CVE-2026-19490-check

Citrix NetScalerのSAML認証バイパスCVE-2026-19490を安全に検出

22621日前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有
リポジトリを見る

Citrix NetScaler SAML nFactor コンテキスト認証バイパス — 脆弱性検出スクリプト

Citrix NetScaler ADC / NetScaler Gateway の SAML サービスプロバイダーパスにおける認証前の認証バイパスである CVE-2026-19490 に対する、安全で非認証の脆弱性チェック (CTX696939、 2026-08-19 公開)。CWE-288、CVSS v4.0 9.3 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L)。JPMorgan Chase のペネトレーションテストチームの Samarth Vashisht 氏により報告されました。

アプライアンスは SAML レスポンスの RelayState パラメータを base64 デコードし、その平文が ctx= で始まる場合、残りの部分を nFactor コンテキストデシリアライザに渡します。未パッチのビルドでは、デシリアライズの失敗がエラーではなく デコードされた RelayState の長さ をリクエストの内部ディスポジションコードとして伝播するため、非認証の攻撃者は RelayState の長さを選ぶだけで、アプライアンスが次に取る内部ブランチを選択できます。一部のブランチは実際の Gateway セッションを発行し、他のブランチはパケットエンジンをクラッシュさせてアプライアンスを再起動させます。このスクリプトはどちらも行いません — セッションを作成せずパケットエンジンにも影響を与えないことが検証済みの単一の長さを送信し、ターゲットごとに 1 つの問いに答えます: このアプライアンスは脆弱か? VULNERABLE 以外の結果は それ自体が安全のお墨付きではありません。

使用方法

# 単一ターゲット
./cve_2026_19490_check.py https://gateway.example.com

# 特定の Gateway または AAA 仮想サーバー
./cve_2026_19490_check.py https://gateway.example.com:9443

# 複数ターゲット; スキームはデフォルトで https://
./cve_2026_19490_check.py gw-a.example.com gw-b.example.com:9443

# リストをスキャン、1 行に 1 ターゲット ('#' コメント可)、コンパクト出力
./cve_2026_19490_check.py -f targets.txt --brief

# パイプライン向けの機械可読出力
./cve_2026_19490_check.py -f targets.txt --json > results.json

Python 3.8+、標準ライブラリのみ — サードパーティパッケージは不要です。

ツールは Gateway または AAA 仮想サーバー を指定してください。管理インターフェースではありません。露出は仮想サーバーごとに異なるため、複数の VIP を持つアプライアンスではそれぞれをテストする必要があります。プローブには厳格な安全エンベロープが組み込まれています — 検証済みの RelayState 長を 1 つだけ使用し、スイープは決して行いません — これについては 実行しても安全か? で説明します。

オプション

フラグ説明
TARGET1 つ以上の [https://]HOST[:PORT] ターゲット; スキームはデフォルトで https://
-f, --targets-file FILEファイルからターゲットを読み込む (1 行に 1 つ; # コメント)
--timeout SECSリクエストごとのタイムアウト (デフォルト: 15)
--workers N同時ターゲット数 (デフォルト: 16); 出力は入力順を維持
-b, --briefターゲットごとに整列された 1 行 — 多数のホストのスキャンに最適
--json構造化 JSON を出力、ターゲットごとに送信されたすべてのリクエストを含む
--no-color色付き出力を無効化 (NO_COLOR および非 TTY も尊重)

例

脆弱なアプライアンス (デフォルトの 2 行出力)。[!] マーカーと VULNERABLE は TTY 上で赤く表示されます:

$ ./cve_2026_19490_check.py https://gateway.example.com:9443
[!] https://gateway.example.com:9443: VULNERABLE  [internal-error-43524]
      HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error, so the CTX696939 fix is absent

パッチ済みのアプライアンス:

$ ./cve_2026_19490_check.py https://vpn.example.com
[+] https://vpn.example.com: PATCHED  [fixed-error-returned]
      HTTP 200 "Malformed Assertion": the fixed error was returned on the path this probe reached, so the CTX696939 fix is present (>= 13.1-63.21 / 14.1-73.32)

偽陽性ガードが発動した例。 プローブ と 同じ長さのコントロールの両方が未パッチのシグナルを返したため、応答は送信内容に依存せず、決定的に見える回答は撤回されます:

$ ./cve_2026_19490_check.py https://sp-strict.example.com
[?] https://sp-strict.example.com: INCONCLUSIVE  [flat-response]
      the probe and the same-length control both answered HTTP 500 / 43524, so the reply does not depend on what was sent and the fix was never exercised; unknown, not patched

資産全体のスイープ (--brief)。2 つの gateway.example.com 行は同じアプライアンス上の SP と IdP 専用の仮想サーバーです — どちらも応答しますが、構成前提条件チェックでは対応できません:

$ ./cve_2026_19490_check.py -f targets.txt --brief; echo "exit: $?"
VULNERABLE    https://gateway.example.com:9443         internal-error-43524
VULNERABLE    https://gateway.example.com:9444         internal-error-43524
PATCHED       https://vpn.example.com                  fixed-error-returned
INCONCLUSIVE  https://sp-strict.example.com            flat-response
UNAFFECTED    https://lb.example.com                   no-saml-endpoint
ERROR         https://www.example.com                  not-identified
exit: 1

機械可読出力 (--json)。すべてのリクエストが含まれるため、検出結果は信頼するのではなく証拠から再導出できます。コントロールは独自の判定としてではなく、プローブとの 関係 によって記録されます。パッチ済みビルドのように読めるコントロールは、どのビルドでも期待される結果だからです:

$ ./cve_2026_19490_check.py https://gateway.example.com:9443 --json
[
  {
    "target": "https://gateway.example.com:9443",
    "verdict": "VULNERABLE",
    "reason": "internal-error-43524",
    "detail": "HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error, so the CTX696939 fix is absent",
    "netscaler_indicators": [
      "CSP contains citrixng://",
      "CSP contains com.citrix.nsgclient://",
      "CSP contains nsgcepa://",
      "CSP report-uri /nscsp_violation/report_uri",
      "/vpn/js/rdx/ present (HTTP 404)"
    ],
    "attempts": [
      {
        "kind": "probe",
        "path": "/cgi/samlauth",
        "status": 500,
        "state": "unpatched",
        "detail": "HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error"
      },
      {
        "kind": "control",
        "path": "/cgi/samlauth",
        "status": 200,
        "state": "differs-from-probe",
        "detail": "same-length control: HTTP 200 \"Malformed Assertion\": the fixed error was returned"
      }
    ]
  }
]

実行しても安全か?

はい。本番環境および評価での使用を想定して設計されています:

  • 固定長を 1 つだけ、スイープは決して行わない。 プローブの RelayState は正確に 20 バイトにデコードされ、ツールはいかなるフラグでも他の長さを送信しません。未パッチのアプライアンスでは、デコードされた長さが ブランチセレクタそのもの であり、ブランチにはセッションを作成するものとパケットエンジンを SIGSEGV させるものが含まれます — これは NetScaler 全体を再起動させ、約 45 秒間トラフィックを落とします。20 バイトはセッションを作成しないクリーンな内部エラーブランチに到達し、ペイロードビルダーは他の長さの構築を拒否するため、他の箇所の編集でプローブが密かに広がることはありません。
  • 測定による検証。 20 バイトのプローブは未パッチの 13.1-63.18 に対して 10 回連続で実行され、コアは 1 つも生成されず、パケットエンジンの再起動もありませんでした。チェック自体はその後、両方のメンテナンスブランチ、修正の両側、およびサービスプロバイダーと IdP 専用の仮想サーバーの両方に対して実行され、いずれもパケットエンジンの再起動はありませんでした。
  • 認証なし、資格情報なし、状態変更なし。 このチェックではアサーション、署名、タイムスタンプ、セッション、クライアント証明書のいずれも提示されません。SAMLResponse パラメータは RelayState ブランチに到達するために 存在 する必要がありますが、その内容は無関係であるため、4 バイトのジャンクです。このブランチは Cookie を発行せず、構成も書き込みません。
  • 偽陽性ガード。 VULNERABLE は単一の応答では決して報告されません — コントロール を参照してください。

プローブを変更する場合、デコードされた RelayState の長さを変更しないでください。また、長さをスイープしないでください。 20 バイトは重要な意味を持ち、短ければ安全というわけではありません。他の長さは良くても未テストであり、最悪の場合はアプライアンスの停止を招きます。

リクエストとログのフットプリント

ターゲットごとに 3 つの HTTP リクエスト、アプライアンスが未パッチのシグナルを返した場合のみ 4 つ目:

#リクエスト目的
1GET /logon/LogonPoint/tmindex.htmlNetScaler の識別 (Content-Security-Policy トークン)
2GET /vpn/js/rdx/core/rdx.jsNetScaler の識別
3POST /cgi/samlauthプローブ
4POST /cgi/samlauthコントロール、未パッチのシグナルの後にのみ送信

リダイレクトは追跡されず、Cookie も一切返送されません — NetScaler は期限切れの NSC_DLGE を提供し、これを再生するクライアントはリクエスト 4 に持ち込み、POST をログオンページに切り替えてしまいます。

nsppe は SAML POST を /var/log/ns.log に情報レベルで記録します。デバッグノブは不要で、nFactor コンテキストのデシリアライズ失敗として、次の行を含みます: nFactor: ctx deserialize aaa_info, base64 decode failed。この長さではセッション作成やログインの行はなく、これがスキャンとバイパスの試行を区別するものです。

仕組み

修正は 1 つの命令です。コンテキストのデシリアライズが失敗した際、脆弱なビルドはデコードされた RelayState の長さをリクエストのステータスとして引き継ぎますが、修正済みビルドは定数エラー 0xe0005 を引き継ぎ、Malformed Assertion としてレンダリングされます。したがって 1 回の POST で両者を区別できます:

プローブへの応答ビルド判定
500 Internal Server Error 43524未パッチVULNERABLE
200 Malformed Assertion sent to Netscalerパッチ済みPATCHED

パッチ済みビルドは あらゆる 長さで Malformed Assertion を返します。これにより、未パッチの応答は偶然ではなくオラクルとなるのです。

コントロールが 500 に意味を与える

VULNERABLE は単一の識別応答に依存するため、ツールは応答が実際に送信内容に依存していることを検証します。未パッチのシグナルの後、同じ 20 バイトのデコード長を持つコントロール RelayState でリクエストを繰り返します。異なるのは ctx= の後の 16 バイトのみです。この内容はデシリアライザの前段のガードによって拒否されるため、テストされたすべてのビルド — パッチ済みと未パッチの両方 — が 200 Malformed Assertion を返します。判定は 2 つの応答が異なる場合にのみ成立します。一致する場合、何かが入力に関係なく 500/43524 を返しており、結果は偽の VULNERABLE ではなく flat-response タグ付きの INCONCLUSIVE となります。コントロールを同じデコード長に保つことで、検証済みの安全エンベロープ内に収め、内容のみを唯一の変数として分離します。

ガードは一方向です。 これは PATCHED 判定を検証できません。真にパッチ済みのアプライアンスはプローブとコントロールに同一に応答するからです — ここでパッチ済みであるとはそういう意味です。制限事項 を参照してください。

IdP 専用の仮想サーバーでも応答する

ツールをダウンロード