
CVE-2026-42978 — Condition de compétition Use-After-Free dans les notifications push Windows (WpnService). Diff de patch, analyse des causes racines, laboratoire TOCTOU, règles de détection Sysmon/ETW.
Condition de concurrence dans le service de notifications push Windows (WpnService) qui s'exécute en tant que NT AUTHORITY\SYSTEM. Un attaquant ayant un accès local peut déclencher une use-after-free lors de l'arrêt de la plateforme et potentiellement élever ses privilèges.
WpnService est le service de notifications push Windows. Il s'exécute dans la session 0 en tant que LocalSystem à l'intérieur de svchost.exe -k netsvcs -p. Toute la livraison de notifications — toasts, vignettes, badges — passe par lui.
La vulnérabilité se trouve dans wpncore.dll, plus précisément dans la classe PresentationEndpointFacade. Cette classe encapsule tous les appels API de notification (livraison de toasts, gestion de sessions, requêtes de paramètres, etc.) et délègue à PresentationEndpointImpl.
Le bogue : lors de l'arrêt de la plateforme, l'objet NotificationPlatform est détruit. Mais les méthodes de Facade ne vérifient pas si l'arrêt est en cours — elles récupèrent un pointeur vers la plateforme, la plateforme est libérée par le thread d'arrêt, et la Facade utilise un pointeur pendant. Condition de concurrence classique de type utilisation après libération.
// 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(...);
}
Désassemblage Ghidra de ToastUnblockAll vulnérable — aucune synchronisation avant l'accès à la plateforme
// 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
}
}
Le correctif ajoute trois choses :
AcquireSRWLockShared — verrou partagé lecteurs-écrivain. Plusieurs appels API peuvent s'exécuter simultanément, mais l'arrêt prend un verrou exclusif et les bloque tous.s_platformShutdown — si l'arrêt a déjà commencé, sortir immédiatement avec E_APPLICATION_EXITING.wil::unique_storage, donc il est libéré même si une exception est levée.L'indicateur de fonctionnalité Feature_4097557817 est destiné à un déploiement progressif via WIL (Windows Internal Library). Il permet à Microsoft d'activer le correctif progressivement et de le désactiver si quelque chose se casse.
Ce n'est pas un bogue d'une seule fonction. Le même motif de verrou+protection a été ajouté à 49 fonctions dans wpncore.dll :
| Catégorie | Fonctions |
|---|---|
| Opérations de toast | ToastUnblockAll, ToastCreateSession, ToastCloseSession, ToastRequestAllNotifications, ToastSuppress |
| Opérations de vignette | TileCreateSession, TileCloseSession, TileRequestResourceForeground |
| Inscription | RegisterApplication, UnregisterApplication, RegisterHandler, UpdateRegistration, RegisterSystemApplication |
| Paramètres | ChangeAppSetting, QueryAppSetting, QueryGlobalSetting, RegisterSettingCallback, UnregisterSettingCallback |
| Livraison | Deliver, GetPayloadForNotificationId, Submit, PostScheduledNotification |
| Requêtes | GetRegisteredHandler, GetRegisteredHandlersFromParent, GetSettingsFromHandler, GetAssetsFromHandler |
Toutes les méthodes PresentationEndpointFacade::* qui touchent la plateforme ont reçu le même correctif. Les méthodes PresentationEndpointImpl::* sous-jacentes sont inchangées — le problème était uniquement au niveau de la façade.
WpnService s'exécute en tant que SYSTEM. Si la course est gagnée :
NotificationPlatform libéré peut être récupérée et remplie avec des données contrôlées par l'attaquant (heap spray)NT AUTHORITY\SYSTEML'exploitation réelle — heap spray, détournement de vtable, obtention d'exécution de code — est hors du cadre de cette recherche. Ce dépôt se concentre sur la compréhension de la cause racine et la construction de la détection.
Le répertoire lab/ contient une démo C autonome qui reproduit la classe de bogue sans toucher à WpnService. Il utilise une architecture de pipe nommé + mémoire partagée similaire à WpnService.
Comment ça fonctionne :
vulnerable_service.exe lit une longueur de message depuis la mémoire partagée, la valide, dort 50 ms, puis lit à nouveau la longueur encore une fois (double récupération).race_attacker.exe définit une longueur sûre, déclenche le service, puis bascule immédiatement la mémoire partagée vers une valeur de débordement.Exécutez vulnerable_service.exe --patched pour voir le correctif : capture unique en une variable locale.
Gauche : le service détecte la course (5/5). Droite : l'attaquant bascule les valeurs de la mémoire partagée.
Nécessite GCC (MinGW). Depuis le répertoire lab/ :
build.bat
Terminal 1 :
vulnerable_service.exe
Terminal 2 :
race_attacker.exe 5
Comparez ensuite avec vulnerable_service.exe --patched — même attaque, zéro courses détectées.
detection/etw_wpn_monitor.ps1)Script PowerShell qui vérifie 7 indicateurs :
powershell -ExecutionPolicy Bypass .\detection\etw_wpn_monitor.ps1
Moniteur ETW : WpnService en cours d'exécution (PID 6432), aucun crash, 100 événements/heure, système corrigé
detection/sysmon_wpn_race_detect.xml)Six groupes de règles pour une surveillance continue :
| Règle | Ce qu'il détecte |
|---|---|
WPN_EoP_ChildProcess | svchost (netsvcs) générant cmd/powershell/wscript |
WPN_PipeAccess | Connexions aux pipes nommés liés à WPN |
WPN_FileCreation | Création de fichiers dans les répertoires de données de notification |
WPN_RegistryTampering | Écritures de registre dans les clés PushNotifications |
WPN_ProcessAccess | Handles PROCESS_ALL_ACCESS vers svchost |
WPN_ThreadInjection | CreateRemoteThread dans svchost |
Installation :
sysmon64.exe -accepteula -i detection\sysmon_wpn_race_detect.xml
L'activité de WpnService est enregistrée dans Microsoft-Windows-PushNotifications-Platform/Operational. Événements clés à surveiller :
Observateur d'événements : journal opérationnel PushNotifications-Platform, ID d'événement 1225
Principales découvertes lors de la comparaison de wpncore.dll :
.text a augmenté de 18 432 octets (nouveau code de verrou/protection dans 49 fonctions).data a augmenté de 96 octets (nouvelles globales Wns::s_platformLock et Wns::s_platformShutdown)AcquireSRWLockShared/ReleaseSRWLockShared étaient déjà dans la table d'importation~unique_any_t<...ReleaseSRWLockExclusive...> confirme l'ajout du wrapper de verrouLes rapports complets sont dans reports/.
CVE-2026-42978 fait partie d'un groupe de 9 vulnérabilités liées à WPN corrigées en juin 2026 :
| CVE | Type | CWE |
|---|---|---|
| CVE-2026-42977 | EoP | Condition de concurrence |
| CVE-2026-42978 | EoP | Condition de concurrence |
| CVE-2026-42979 | EoP | Condition de concurrence |
| CVE-2026-42991 | EoP | Condition de concurrence |
| CVE-2026-42969 | Divulgation d'informations | Condition de concurrence |
| CVE-2026-42970 | Divulgation d'informations | Condition de concurrence |
| CVE-2026-42973 | Divulgation d'informations | Condition de concurrence |
| CVE-2026-26167 | EoP | — |
| CVE-2026-32160 | EoP | — |
CVE-2026-42978/
├── README.md
├── lab/
│ ├── vulnerable_service.c # mock WpnService with double-fetch bug
│ ├── race_attacker.c # attacker that exploits the double-fetch
│ └── build.bat # GCC build script
├── detection/
│ ├── etw_wpn_monitor.ps1 # 7-check PowerShell detector
│ └── sysmon_wpn_race_detect.xml # Sysmon rule config
├── reports/
│ ├── PE_DIFF_REPORT.txt # PE section/import diff results
│ └── FUNCTION_DIFF_REPORT.txt # function-level diff (49 changed)
└── img/ # screenshots for this README
Ce projet est destiné à la recherche défensive en sécurité. La vulnérabilité est corrigée. Aucun code d'exploitation armé n'est inclus. Le laboratoire TOCTOU démontre la classe de bogue sur un service simulé autonome — il n'interagit pas avec WpnService ou tout composant système.
Assurez-vous que votre Windows est à jour. Si etw_wpn_monitor.ps1 signale que votre système n'est pas corrigé — installez immédiatement la mise à jour cumulative de juin 2026.
Si vous avez quelque chose à ajouter — meilleures règles de détection, PoC d'exploitation, session de suivi de version Ghidra, signatures YARA, ou analyse des CVE liées dans ce groupe — les PR sont les bienvenus.
Idées de contributions :
Ouvrez un ticket si vous avez des questions ou souhaitez discuter de la recherche.
MIT