
CVE-2026-42897 - بقعة عمياء في Exchange Health Checker: قواعد إعادة كتابة عنوان URL الصادرة لـ IIS يتم تجاهلها بصمت، مما يجعل إجراءات التخفيف من EOMT غير مرئية في تقارير التشخيص.
الخطورة: متوسطة (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).
يقوم التخفيف الخاص بـ EOMT (أداة تخفيف Exchange المحلي - Exchange On-premises Mitigation Tool) لثغرة CVE-2026-42897 بنشر
قاعدة حقن ترويسة Content-Security-Policy باسم EOMT OWA CSP - outbound كقاعدة
IIS صادرة لإعادة كتابة URL. ولأن Health Checker لا يقرأ outboundRules أبدًا، فإن
قاعدة التخفيف هذه تكون غير مرئية تمامًا في تقارير Health Checker.
مدير Exchange الذي يعتمد على Health Checker لتأكيد أن تخفيفات EOMT مطبّقة سيحصل على تقرير لا يُظهر أي قاعدة 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 مع طفلَين منفصلين تحت <rewrite>:
<system.webServer>
<rewrite>
<!-- inbound - what Health Checker reads -->
<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 - INVISIBLE to 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>
| السيناريو | التأثير |
|---|---|
| تشغيل المدير لـ Health Checker بعد تطبيق EOMT | لا يُظهر التقرير أي قاعدة CSP صادرة → يعتقد المدير أن التخفيف مفقود |
| استخدام المدير لـ Health Checker كأداة تدقيق وحيدة | لا يمكن التحقق من قواعد EOMT الصادرة دون فحص إعدادات IIS يدويًا |
| فحوصات الاستجابة للحوادث / الامتثال |
انظر poc_cve_2026_42897.ps1 في هذا الدليل.
يقوم السكربت بما يلي:
web.config محاكى XML في الذاكرة يحتوي على قاعدة واردة وقاعدة EOMT
الصادرة EOMT OWA CSP - outbound..\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 | كتابة إثبات المفهوم واختباره ضد إعدادات IIS محاكاة |
لأغراض البحث الأمني المصرح به فقط. اختبر حصريًا في بيئات معملية خاضعة للتحكم.
| أدلة التخفيف غائبة عن مخرجات Health Checker |
| المراقبة الآلية التي تحلل مخرجات Health Checker بصيغة JSON | وجود / غياب القاعدة الصادرة لا يظهر أبدًا |