
深刻度: Medium (CVSS 5.3)
コンポーネント: Microsoft CSS-Exchange - HealthChecker 診断ツール
影響を受けるファイル:
Diagnostics/HealthChecker/Analyzer/Get-URLRewriteRule.ps1 (L49, L72, L97)Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerIISInformation.ps1 (L442–459)
報告日: 2026-05-15
クレジット: 報告した研究者による独自の発見 CSS-Exchange issue #2539
参照:Get-URLRewriteRule.ps1, Invoke-AnalyzerIISInformation.ps1Security/src/EOMT/Mitigations/CVE-2026-42897.ps1 (L147–254)Exchange Health Checker (HealthChecker.ps1) は、サーバー構成監査の一環として IIS URL Rewrite ルールを報告します。しかし、ルール列挙関数 Get-URLRewriteRule.ps1 は インバウンド ルール (system.webServer/rewrite/rules) のみを読み取り、アウトバウンド ルール (system.webServer/rewrite/outboundRules) を黙って無視します。
CVE-2026-42897 に対する EOMT (Exchange On-premises Mitigation Tool) の緩和策は、EOMT OWA CSP - outbound という名前の Content-Security-Policy ヘッダーインジェクションルールを IIS アウトバウンド URL Rewrite ルールとして展開します。Health Checker は outboundRules を決して読み取らないため、この緩和ルールは Health Checker のレポートで完全に不可視になります。
EOMT の緩和策が適用されていることを確認するために Health Checker に依存している Exchange 管理者は、アウトバウンド CSP ルールが表示されないレポートを受け取ることになります。これにより、緩和ステータスに関して偽陰性が発生し、誤った露出感、あるいは逆に緩和策が適用されていないにもかかわらず適用されたという誤った確信を生み出します。
Get-URLRewriteRule.ps1 内の3つの異なるコードパスはすべて .rewrite.rules のみを読み取ります:
パス1 - web.config 解析 (L49):
$rules = $content.configuration.'system.webServer'.rewrite.rules
パス2 - applicationHost.config ロケーション別 (L72):
$rules = $location.'system.webServer'.rewrite.rules
パス3 - applicationHost.config グローバル (L97):
$rules = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.rules
これらのパスはいずれも .rewrite.outboundRules にアクセスしません。返された $rules オブジェクトは Invoke-AnalyzerIISInformation.ps1 (L442–459) で反復処理されます:
$displayRewriteRules = ($currentRewriteRules.rule | Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
.rule メンバーはインバウンド <rules> コレクションにのみ存在します。仮に outboundRules が読み取られたとしても、表示ロジックは両方のコレクションから .rule を反復するように更新する必要があります。
IIS は URL Rewrite 構成を <rewrite> の下に2つの別々の子要素として保存します:
<system.webServer>
<rewrite>
<!-- inbound - Health Checkerが読み取るもの -->
<rules>
<rule name="Redirect to HTTPS" enabled="true">
<match url=".*" />
<conditions><add input="{HTTPS}" pattern="^OFF$" /></conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:0}" />
</rule>
</rules>
<!-- outbound - Health Checkerからは見えない -->
<outboundRules>
<rule name="EOMT OWA CSP - outbound" enabled="true">
<match serverVariable="RESPONSE_Content-Security-Policy" pattern=".*" />
<action type="Rewrite"
value="default-src 'self'; script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
| シナリオ | 影響 |
|---|---|
| 管理者が EOMT 適用後に Health Checker を実行 | レポートにアウトバウンド CSP ルールが表示されない → 管理者は緩和策が欠落していると認識 |
| 管理者が Health Checker を唯一の監査ツールとして使用 | IIS 構成を手動で検査しなければ EOMT アウトバウンドルールを確認できない |
| インシデント対応 / コンプライアンスチェック | Health Checker の出力に緩和証拠が存在しない |
| Health Checker JSON を解析する自動監視 | アウトバウンドルールの有無が決して表面化しない |
このディレクトリ内の poc_cve_2026_42897.ps1 を参照してください。
スクリプトの内容:
EOMT OWA CSP - outbound アウトバウンドルールの両方を含むメモリ内モック web.config XML を構築します。.\poc_cve_2026_42897.ps1
脆弱な(パッチ未適用の)Health Checker での期待される出力:
[*] Vulnerable path (inbound only):
Rules found: Redirect to HTTPS
MISSING: EOMT OWA CSP - outbound
[*] Patched path (inbound + outbound):
Rules found: Redirect to HTTPS, EOMT OWA CSP - outbound
Outbound rule visible: TRUE
Get-URLRewriteRule.ps1 の修正 - 各パスで両方のコレクションを読み取る:
# web.config (L49)
$inbound = $content.configuration.'system.webServer'.rewrite.rules
$outbound = $content.configuration.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
# applicationHost.config per-location (L72)
$inbound = $location.'system.webServer'.rewrite.rules
$outbound = $location.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
# applicationHost.config global (L97)
$inbound = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.rules
$outbound = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
Invoke-AnalyzerIISInformation.ps1 の修正 - 両方のコレクションを反復する:
$displayRewriteRules = @()
$displayRewriteRules += ($currentRewriteRules.inbound.rule |
Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
$displayRewriteRules += ($currentRewriteRules.outbound.rule |
Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
| 日付 | イベント |
|---|---|
| 2026-05-15 | EOMT 展開検証研究中に問題を特定 |
| 2026-05-15 | PoC を作成し、モック IIS 構成に対してテスト |
権限のあるセキュリティ研究のみを対象としています。管理されたラボ環境でのみテストしてください。