
CVE-2026-42978 — حالة سباق استخدام بعد التحرير (Use-After-Free) في خدمة إشعارات Windows Push (WpnService). فرق التصحيح، تحليل السبب الجذري، مختبر TOCTOU، قواعد كشف Sysmon/ETW.
حالة سباق في خدمة إشعارات Windows الفورية (WpnService) التي تعمل كـ NT AUTHORITY\SYSTEM. يمكن للمهاجم ذي الوصول المحلي تشغيل خطأ استخدام-بعد-التحرير أثناء إيقاف تشغيل النظام الأساسي وربما رفع الصلاحيات.
WpnService هي خدمة إشعارات Windows الفورية. تعمل في الجلسة 0 كـ LocalSystem داخل svchost.exe -k netsvcs -p. جميع عمليات توصيل الإشعارات — الإشعارات المنبثقة، البلاطات، الشارات — تمر عبرها.
توجد الثغرة في wpncore.dll، تحديدًا في الفئة PresentationEndpointFacade. تلتف هذه الفئة حول جميع استدعاءات API للإشعارات (توصيل الإشعارات المنبثقة، إدارة الجلسات، استعلامات الإعدادات، إلخ) وتفوض إلى PresentationEndpointImpl.
الخلل: أثناء إيقاف تشغيل النظام الأساسي، يتم تدمير الكائن NotificationPlatform. لكن طرق الواجهة (Facade) لا تتحقق مما إذا كان الإيقاف قيد التقدم — فهي تستحوذ على مؤشر للنظام الأساسي، ثم يتم تحرير النظام الأساسي بواسطة خيط الإيقاف، وتستخدم الواجهة مؤشرًا متدليًا. حالة سباق استخدام-بعد-التحرير كلاسيكية.
// PresentationEndpointFacade::ToastUnblockAll — VULNERABLE
long ToastUnblockAll(PresentationEndpointFacade *this) {
// No lock. No shutdown check. Just grab the platform pointer and go.
NotificationPlatformHandle::Get(this + 0x50);
if (platform == NULL) Throw_Hr(...);
// If shutdown frees the platform right here — use-after-free
return PresentationEndpointImpl::UnblockToastsForEachApp(...);
}
Ghidra: ToastUnblockAll الضعيف — لا تزامن قبل الوصول إلى النظام الأساسي
// PresentationEndpointFacade::ToastUnblockAll — PATCHED
long ToastUnblockAll(PresentationEndpointFacade *this) {
if (Feature_4097557817::IsEnabled()) {
AcquireSRWLockShared(&Wns::s_platformLock); // 1. shared lock
if (Wns::s_platformShutdown) // 2. shutdown guard
Throw_Hr(E_APPLICATION_EXITING);
NotificationPlatformHandle::Get(this + 0x50);
// ... do work ...
ReleaseSRWLockShared(&Wns::s_platformLock); // 3. RAII release
} else {
// feature flag off — old behavior preserved for rollback
}
}
يضيف الإصلاح ثلاثة أشياء:
AcquireSRWLockShared — قفل مشترك للقراء-الكتاب. يمكن لعدة استدعاءات API أن تعمل بشكل متزامن، لكن الإيقاف يأخذ قفلًا حصريًا ويحظرها جميعًا.s_platformShutdown — إذا بدأ الإيقاف بالفعل، اخرج فورًا مع E_APPLICATION_EXITING.wil::unique_storage، بحيث يتم تحريره حتى في حالة طرح استثناء.علم الميزة Feature_4097557817 مخصص للطرح التدريجي عبر WIL (مكتبة Windows الداخلية). يسمح لمايكروسوفت بتمكين الإصلاح تدريجيًا وتعطيله في حالة حدوث خلل.
هذا ليس خللًا في وظيفة واحدة. تمت إضافة نفس نمط القفل+الحارس إلى 49 وظيفة في wpncore.dll:
| التصنيف | الوظائف |
|---|---|
| Toast operations | ToastUnblockAll, ToastCreateSession, ToastCloseSession, ToastRequestAllNotifications, ToastSuppress |
| Tile operations | TileCreateSession, TileCloseSession, TileRequestResourceForeground |
| Registration | RegisterApplication, UnregisterApplication, RegisterHandler, UpdateRegistration, RegisterSystemApplication |
| Settings | ChangeAppSetting, QueryAppSetting, QueryGlobalSetting, RegisterSettingCallback, UnregisterSettingCallback |
| Delivery | Deliver, GetPayloadForNotificationId, Submit, PostScheduledNotification |
| Queries | GetRegisteredHandler, GetRegisteredHandlersFromParent, GetSettingsFromHandler, GetAssetsFromHandler |
كل طريقة PresentationEndpointFacade::* تلامس النظام الأساسي حصلت على نفس الإصلاح. طرق PresentationEndpointImpl::* تحتها لم تتغير — كانت المشكلة فقط في طبقة الواجهة.
تعمل WpnService كـ SYSTEM. إذا تم ربح السباق:
NotificationPlatform وملؤها ببيانات يتحكم بها المهاجم (رش الكومة)NT AUTHORITY\SYSTEMالاستغلال الفعلي — رش الكومة، اختطاف جدول الوظائف الافتراضية، تحقيق تنفيذ الكود — هو خارج نطاق هذا البحث. يركز هذا المستودع على فهم السبب الجذري وبناء الكشف.
يحتوي دليل lab/ على عرض توضيحي مستقل بلغة C يعيد إنتاج فئة الخلل دون لمس WpnService. يستخدم بنية أنبوب مسمى + ذاكرة مشتركة مشابهة لـ WpnService.
كيف يعمل:
vulnerable_service.exe طول رسالة من الذاكرة المشتركة، يتحقق منه، ينام لمدة 50 مللي ثانية، ثم يقرأ الطول مرة أخرى (جلب مزدوج).race_attacker.exe طولًا آمنًا، يُشغل الخدمة، ثم يقلب الذاكرة المشتركة فورًا إلى قيمة تجاوز.شغّل vulnerable_service.exe --patched لرؤية الإصلاح: التقاط جلب واحد في متغير محلي.
يسار: الخدمة تكتشف السباق (5/5). يمين: المهاجم يقلب قيم الذاكرة المشتركة.
يتطلب GCC (MinGW). من دليل lab/:
build.bat
الطرفية 1:
vulnerable_service.exe
الطرفية 2:
race_attacker.exe 5
ثم قارن مع vulnerable_service.exe --patched — نفس الهجوم، لم يتم اكتشاف أي سباقات.
detection/etw_wpn_monitor.ps1)نص PowerShell يتحقق من 7 مؤشرات:
powershell -ExecutionPolicy Bypass .\detection\etw_wpn_monitor.ps1
مراقب ETW: WpnService تعمل (PID 6432)، لا أعطال، 100 حدث/ساعة، النظام مُصحح
detection/sysmon_wpn_race_detect.xml)ست مجموعات قواعد للمراقبة المستمرة:
| القاعدة | ما تلتقطه |
|---|---|
WPN_EoP_ChildProcess | svchost (netsvcs) يولد cmd/powershell/wscript |
WPN_PipeAccess | اتصالات بالأنابيب المسماة المتعلقة بـ WPN |
WPN_FileCreation | إنشاء ملفات في أدلة بيانات الإشعارات |
WPN_RegistryTampering | كتابات إلى مفاتيح التسجيل الخاصة بـ PushNotifications |
WPN_ProcessAccess | مقابض PROCESS_ALL_ACCESS لـ svchost |
WPN_ThreadInjection | CreateRemoteThread في svchost |
التثبيت:
sysmon64.exe -accepteula -i detection\sysmon_wpn_race_detect.xml
يتم تسجيل نشاط WpnService في Microsoft-Windows-PushNotifications-Platform/Operational. الأحداث الرئيسية للمراقبة: