
CVE-2026-11374 の検出スクリプト
CVE-2026-11374 の悪用事前条件を検出するスクリプトです。この脆弱性は予測可能な SSO チケットの欠陥により、ManageEngine AD360 スイート全体で未認証のアカウント乗っ取りを引き起こします。対象となる4製品は共通の ManageEngineADSFramework を共有しています:
| 製品 | 影響を受けるビルド | 修正済みビルド |
|---|---|---|
| ADSelfService Plus | ≤ 6528 | 6529 |
| RecoveryManager Plus | ≤ 6320 | 6321 |
| M365 Manager Plus | ≤ 4816 | 4817 |
| ADAudit Plus | ≤ 8702 | 8703 |
影響を受けるビルドでは、SSO チケットは被害者のログイン時にサンプリングされた System.currentTimeMillis()(予測可能なタイムスタンプ)に過ぎないため、CUSTOM_SSO_TICKET Cookie を通じてリプレイし、そのセッションを乗っ取ることができます。修正ではチケットが UUID.randomUUID()(十分にランダムな識別子)に置き換えられています。リプレイ経路は製品が AD360 統合されている場合にのみ到達可能です。ADSFilter が isProductIntegrated() でこれをゲートしているためです。このツールがチェックするのは、まさにそのゲート(事前条件)です。
注記: この検出器は事前条件を確認するものであり、脆弱性そのものを確認するものではありません。
POTENTIALLY_AFFECTEDという結果は、脆弱性が確定したという判定ではありません。詳細は後述します。
はい。本番環境および評価での使用を想定して作られています。
1700000000000。キャッシュに常駐し得ないほど過去のミリ秒値)を送信するだけなので、セッションが復元されることは決してありません。サーバーは送信した Cookie をクリアするよう指示するだけです。GET であり、影響を受ける Cookie はツールが送信する使い捨てのものだけです。CVE-2026-11374 のパッチはチケットの生成方法(ミリ秒から UUID)のみを変更し、このプローブが実行する Cookie リプレイ経路は変更していません。その結果、パッチ適用済みのインストールは、未認証リクエストに対して脆弱なものとバイト単位で同一の応答を返します。
このツールができること(未認証かつ非破壊的):
できないこと:
POTENTIALLY_AFFECTED の結果は事前条件が満たされていることを意味し、パッチレベルを確認すべきということであり、ホストが脆弱であると確定したわけではありません。conf/product.conf を読む、またはライブチケットを能動的に解決する(実際の悪用であり、意図的に実装していません)ことが必要です。?build= は実際のビルドである場合と、修正ビルド未満の値を返す凍結されたプレースホルダーである場合があるため、修正ビルド未満の値は曖昧であり、ツールはそれを「判定不能」とマークします。修正ビルド以上の値は依然として信頼できるパッチ適用済みシグナルです。プレースホルダーは常に低すぎてそこに到达できないためです。requests ライブラリ。インストールは pip install requests で行います。# 単一ホスト(URL または host:port を推奨。ポートは製品ごとに異なります)
./cve_2026_11374_check.py https://adssp.example.com:8888
# 複数ホスト(スキームは任意。https が最初に試行され、次に http)
./cve_2026_11374_check.py host-a:8081 host-b:8365
# リストをスキャン(1行に1ターゲット。'#' コメント可)、コンパクト出力
./cve_2026_11374_check.py -f targets.txt --brief
# パイプライン向けの機械可読出力
./cve_2026_11374_check.py -f targets.txt --json > results.json
デフォルトのポートは製品ごとに異なります(ADSelfService Plus 8888、ADAudit Plus 8081、M365 Manager Plus 8365、RecoveryManager Plus 8090)。そのため URL または host:port を渡してください。ベアホストの場合は 8888 がデフォルトです。
AD360 統合コンソール(詳細出力。デフォルト)。2行目はこれが事前条件であり脆弱性の判定ではないことを明示し、3行目はベストエフォートのビルドヒントです:
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[!] https://adssp.example.com:8888: POTENTIALLY_AFFECTED
ADSelfService Plus: AD360-integrated, CustomSSO replay path active - precondition met. Not confirmed vulnerable; verify patch level (fixed build 6529).
build: 6519 (below fixed 6529 - inconclusive: ?build= may be a stale placeholder or a hotfix)
同じ製品のスタンドアロンインストールで、リプレイ経路が有効でない場合:
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[+] https://adssp.example.com:8888: UNAFFECTED
ADSelfService Plus: standalone / not AD360-integrated (no cleanup), so the replay path isn't reachable here. Verify build >= 6529 regardless.
リストをスキャンし、ホストごとに整列された1行を出力(--brief)。いずれかのホストが POTENTIALLY_AFFECTED の場合は終了ステータスが 1、それ以外は 0 となり、スクリプトで便利です。末尾の注記は特定された製品と、検出時にはビルド番号を示します:
$ ./cve_2026_11374_check.py -f targets.txt --brief; echo "exit: $?"
POTENTIALLY_AFFECTED https://host-a:8888 ADSelfService Plus 6519
POTENTIALLY_AFFECTED http://host-b:8081 ADAudit Plus 8530
UNAFFECTED http://host-c:8365 M365 Manager Plus
UNAFFECTED https://host-d:443
INCONCLUSIVE http://host-e:8888 ADSelfService Plus
ERROR host-f:8888 timeout
exit: 1
機械可読出力(--json)。各結果には verdict(判定)、その背後にある state と detail、特定された product、そして検出時には build オブジェクトが含まれます。build は見つかった番号、fixed_build はその製品のしきい値、patch_hint は方向性を示す呼び出し(修正ビルド以上なら likely_patched、それ以外は inconclusive)、note は短い説明です:
$ ./cve_2026_11374_check.py https://host-b:8081 --json
[
{
"target": "https://host-b:8081",
"state": "potentially_affected",
"detail": "ADAudit Plus: AD360-integrated, CustomSSO replay path active - precondition met ...",
"product": "ADAudit Plus",
"build": { "build": "8530", "fixed_build": "8703", "patch_hint": "inconclusive", "note": "below fixed 8703 - inconclusive: may be a hotfix" },
"verdict": "POTENTIALLY_AFFECTED"
}
]
| コード | 意味 |
|---|---|
0 | POTENTIALLY_AFFECTED を返したターゲットがない |
1 | 少なくとも1つのターゲットが POTENTIALLY_AFFECTED |
2 | 使い方エラー(不正な引数 / 読み取り不能なターゲットファイル) |
無効なチケットとアプリタグを任意の CustomSSO URL(*.do)に送信します:
GET /AppsHome.do
Cookie: CUSTOM_SSO_TICKET=1700000000000; CUSTOM_SSO_APP_TAG_NAME=AD360
AD360 統合インストールでは、チェーン ADSFilter → CustomSSOFilter → CookieSSOImpl が解決分岐を実行し(タグが別の製品を指定するため appName != prodName)、偽のチケットの解決に失敗して、Cookie クリーンアップ応答ヘッダーを出力します:
Set-Cookie: CUSTOM_SSO_TICKET=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_NAME=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_TAG_NAME=removed; Max-Age=0; ...
スタンドアロンインストールはその経路を実行しないため、クリーンアップは出力されません。製品は、すべての応答で設定される製品固有の Tomcat セッション Cookie(ADSelfService Plus は JSESSIONIDADSSP など)から特定されます。チェックはステータスコードではなくヘッダーを基準にします。統合された ADSSP は 302 を返す一方、ADAudit、M365、RMP は同じプローブに対して 200 を返すためです。
POTENTIALLY_AFFECTED は「脆弱性確定」ではありません。これは悪用事前条件です。パッチはこのコードパスに触れていないため、パッチ適用済みビルドも同一に応答します。したがって、パッチレベルを帯域外で確認する必要があります(次のステップを参照)。これが未認証の観測者が知り得る上限です。HTTP 400 は実際の回答ではなくレート制限ロックである可能性があります。Zoho IAM は URL ローリングスロットルを適用し、送信元 IP を約60秒あたり40リクエストに制限した後、そのパスを約60秒間ロックします。ロック中はリクエストが HTTP 400 を返し、統合シグナルがマスクされます。ツールはこれらを INCONCLUSIVE として報告します。その IP から約1分後に再試行してください。UNAFFECTED として誤報告される可能性があります。そこに ManageEngine 製品が存在すると予想される場合は、直接確認してください。?v=)と M365(?bN=)は常に実際のビルドを公開します。ADSSP の ?build= は実際のビルドである場合と、修正ビルド未満の値を返す凍結されたプレースホルダーである場合があるため、修正ビルド未満の ADSSP 値は曖昧です。RMP は何も公開しません。いずれの場合も、修正ビルド以上のビルドはパッチ適用済みを強く示し、それ未満は判定不能です。ターゲットが POTENTIALLY_AFFECTED を返した場合、それが公開されており確認に値すると見なして、次の手順を実行してください:
パッチレベルを直接確認します(ツールはできません)。ホスト上の conf/product.conf(build_number)を読み、その製品の修正ビルド(ADSelfService Plus 6529、RecoveryManager Plus 6321、M365 Manager Plus 4817、ADAudit Plus 8703)と比較します。方向性として解釈してください: 修正ビルド以上のビルドは、UUID 修正がそのツリーに含まれているため、ホストがパッチ適用済みである強い指標です。修正ビルド未満のビルドは脆弱性の証明ではなく判定不能です。帯域外のホットフィックスやバックポートがビルド番号を増やさずに UUID 修正を適用できるためです。その場合は、以下のチケット形式チェックにフォールバックしてください。
ログインできる場合は、発行されたチケットの形式を確認します。CUSTOM_SSO_TICKET Cookie は HttpOnly ではないため、認証後にその値を読むことができます: 13桁の数値なら脆弱、UUID ならパッチ適用済みです。これが最も明確な陽性チェックです。
脆弱なホスト、またはパッチ適用済みであることを確認できないホストは、修正ビルド(以降)に更新してください。修正は予測可能なチケットをランダムな UUID に置き換えます。
悪用試行を探してください。ホスト上の serverOut_<日付>.txt には、次のようなスロットルのバーストとして記録されます:
IAMSecurityException ErrorCode: URL_ROLLING_THROTTLES_LIMIT_EXCEEDED,
RequestURI: "/showLogin.cc", RemoteAddr: <source IP>
単一の送信元 IP からの SSO/ログインディスパッチパスにおける URL_ROLLING_THROTTLES_LIMIT_EXCEEDED の急増は、チケットのブルートフォースを示す強い指標です。また、最近の成功したログインとセッションアクティビティをレビューして、乗っ取りの兆候がないか確認してください。
その間、露出を減らします。AD360 スイートへのネットワークアクセスを制限し(インターネットに公開すべきではありません)、リプレイ経路が不要な場合は CustomSSO 統合を無効にすると、事前条件自体がなくなります。
影響を受ける製品を少なくとも修正ビルド(ADSelfService Plus 6529、RecoveryManager Plus 6321、M365 Manager Plus 4817、ADAudit Plus 8703)以降に更新してください。修正は、予測可能な System.currentTimeMillis() SSO チケットを UUID.randomUUID() に置き換えます。
このコードは MIT ライセンス の下で配布されています。
事前の相互同意なしにターゲットを攻撃するためにこのツールを使用することは違法です。適用されるすべての地域、州、連邦の法律を遵守する責任はエンドユーザーにあります。開発者は一切の責任を負わず、このプログラムによって引き起こされた誤用や損害について責任を負いません。
| フラグ | 説明 |
|---|
targets | 1つ以上の host、host:port、または https://host:port |
-f, --targets-file FILE | ファイルからターゲットを読み取る(1行に1つ。# はコメント) |
--brief | ターゲットごとに整列された1行を出力。多数のホストのスキャンに適しています |
--json | 構造化された JSON 結果を出力 |
--timeout SECS | リクエストごとのタイムアウト(デフォルト: 15) |
--no-build | 陽性判定時に追加のビルド番号リクエストをスキップ |
--no-color | 色付き出力を無効化(NO_COLOR および非 TTY も尊重) |
| 判定 | 意味 |
|---|
POTENTIALLY_AFFECTED | AD360 統合された対象製品。CustomSSO Cookie リプレイ経路が有効なため、CVE-2026-11374 の悪用事前条件が満たされています。これは脆弱性確定の判定ではありません。パッチレベルを確認してください(次のステップを参照)。 |
UNAFFECTED | リプレイ経路に到達できません。次のいずれか: スタンドアロンの対象製品(AD360 統合されていない。ただし後で統合されると到達可能になるため、ビルドは必ず確認してください)、4つの対象外である ManageEngine ADS フレームワーク製品、または応答に対象製品がまったく存在しない(CVE-2026-11374 の4製品以外、またはセッション Cookie を除去するプロキシ)。 |
INCONCLUSIVE | HTTP 400。おそらく IAM レート制限ロックがシグナルを隠しています。約60秒後に再試行してください。 |
ERROR | 接続/タイムアウト/TLS 障害。 |
| プローブ応答 | 判定 |
|---|
| クリーンアップヘッダーと既知の対象製品 Cookie | POTENTIALLY_AFFECTED |
| 製品 Cookie、クリーンアップなし、ステータス ≠ 400 | UNAFFECTED(スタンドアロン / 統合されていない) |
| 対象製品 Cookie なし、ステータス ≠ 400 | UNAFFECTED(4製品のいずれでもない) |
| クリーンアップヘッダーだが認識できない製品 Cookie | UNAFFECTED(ManageEngine だが対象外) |
HTTP 400 | INCONCLUSIVE(おそらく IAM レート制限ロック。制限事項を参照) |