
严重性: 中 (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 () 在服务器配置审计中报告 IIS URL 重写规则。但是,规则枚举函数 仅读取规则 (),而静默忽略了规则 ()。
HealthChecker.ps1Get-URLRewriteRule.ps1system.webServer/rewrite/rulessystem.webServer/rewrite/outboundRules针对 CVE-2026-42897 的 EOMT (Exchange 本地缓解工具) 缓解措施部署了一条名为 EOMT OWA CSP - outbound 的内容安全策略标头注入规则,作为 IIS 出站 URL 重写规则。由于 Health Checker 从不读取 outboundRules,此缓解规则在 Health Checker 报告中完全不可见。
依赖 Health Checker 确认 EOMT 缓解措施已就位的 Exchange 管理员将收到一份未显示任何出站 CSP 规则的报告——从而给出关于缓解状态的假阴性,造成一种虚假的暴露感,或者反过来,当缓解措施已应用时却误认为未应用。
Get-URLRewriteRule.ps1 中的三条不同代码路径都只从 .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> 下的两个独立子元素:
<system.webServer>
<rewrite>
<!-- 入站 - 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>
<!-- 出站 - 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。
该脚本:
web.config XML,同时包含一条入站规则和 EOMT 的 EOMT OWA CSP - outbound 出站规则。.\poc_cve_2026_42897.ps1
在存在漏洞(未修复)的 Health Checker 上预期的输出:
[*] 漏洞路径(仅入站):
找到的规则:Redirect to HTTPS
缺失:EOMT OWA CSP - outbound
[*] 已修复路径(入站+出站):
找到的规则:Redirect to HTTPS, EOMT OWA CSP - outbound
出站规则可见: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 | 编写并针对模拟 IIS 配置测试 PoC |
仅供授权安全研究使用。请仅在受控实验室环境中测试。