CVE-2026-42978 — Windows 推送通知服务(WpnService)中的释放后使用(Use-After-Free)竞态条件。包含补丁差异、根因分析、TOCTOU 实验以及 Sysmon/ETW 检测规则。
Windows 推送通知服务(WpnService)中存在竞争条件,该服务以 NT AUTHORITY\SYSTEM 身份运行。拥有本地访问权限的攻击者可在平台关闭期间触发释放后使用,并可能提升权限。
WpnService 是 Windows 推送通知服务。它以 LocalSystem 身份、在会话 0 中运行于 svchost.exe -k netsvcs -p 进程内。所有通知投递——toast、磁贴、徽章——都经由它完成。
漏洞位于 wpncore.dll 中,具体在 PresentationEndpointFacade 类里。该类封装了所有通知 API 调用(toast 投递、会话管理、设置查询等),并委托给 PresentationEndpointImpl。
这个 Bug 在于:在平台关闭过程中,NotificationPlatform 对象会被销毁。但 Facade 方法不会检查关闭是否正在进行——它们获取指向平台的指针,平台随后被关闭线程释放,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 内部库)进行分阶段部署。它让微软可以逐步启用修复,并在出现问题时将其禁用。
这不是单个函数的 Bug。相同的锁+防护模式被添加到了 wpncore.dll 中的 49 个函数:
所有涉及平台访问的 PresentationEndpointFacade::* 方法都获得了相同的修复。底层的 PresentationEndpointImpl::* 方法保持不变——问题仅存在于 facade 层。
WpnService 以 SYSTEM 身份运行。若攻击者在竞争中胜出:
NotificationPlatform 对象的内存可被重新占用,并填充攻击者控制的数据(堆喷)NT AUTHORITY\SYSTEM 身份执行代码实际的利用过程——堆喷、虚表劫持、实现代码执行——不在本次研究范围内。本仓库专注于理解根本原因和构建检测能力。
lab/ 目录包含一个独立的 C 语言演示程序,它复现了此类 Bug,且不会触及 WpnService。它采用与 WpnService 类似的命名管道 + 共享内存架构。
工作原理:
vulnerable_service.exe 从共享内存读取消息长度,验证后休眠 50 毫秒,然后再次读取该长度(双重取用,double-fetch)。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)检查 7 项指标的 PowerShell 脚本:
powershell -ExecutionPolicy Bypass .\detection\etw_wpn_monitor.ps1
ETW 监视器:WpnService 正在运行(PID 6432),无崩溃,每小时 100 个事件,系统已修补
detection/sysmon_wpn_race_detect.xml)用于持续监控的六组规则:
安装:
sysmon64.exe -accepteula -i detection\sysmon_wpn_race_detect.xml
WpnService 的活动记录在 Microsoft-Windows-PushNotifications-Platform/Operational 日志中。需要关注的关键事件:
事件查看器:PushNotifications-Platform 操作日志,事件 ID 1225
对 wpncore.dll 进行差异比较的关键发现:
.text 节增加 18,432 字节(49 个函数中新增锁/防护代码).data 节增加 96 字节(新增 Wns::s_platformLock 和 Wns::s_platformShutdown 全局变量)AcquireSRWLockShared/ReleaseSRWLockShared 已在导入表中~unique_any_t<...ReleaseSRWLockExclusive...> 证实了锁包装器的添加完整报告位于 reports/ 中。
CVE-2026-42978 是 2026 年 6 月修复的 9 个 WPN 相关漏洞集群之一:
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
本项目用于防御性安全研究。该漏洞已修复。项目中不包含任何武器化利用代码。TOCTOU 实验在独立的模拟服务上演示了此类 Bug——它不会与 WpnService 或任何系统组件交互。
请确保你的 Windows 保持最新。若 etw_wpn_monitor.ps1 报告你的系统未修补——请立即安装 2026 年 6 月累积更新。
如果你有想补充的内容——更好的检测规则、sploit PoC、Ghidra 版本跟踪(Version Tracking)会话、YARA 签名,或对该集群中相关 CVE 的分析——欢迎提交 PR。
贡献思路:
如有疑问或想讨论本次研究,请提交 issue。
MIT
| 类别 | 函数 |
|---|
| Toast 操作 | ToastUnblockAll, ToastCreateSession, ToastCloseSession, ToastRequestAllNotifications, ToastSuppress |
| 磁贴操作 | TileCreateSession, TileCloseSession, TileRequestResourceForeground |
| 注册 | RegisterApplication, UnregisterApplication, RegisterHandler, UpdateRegistration, RegisterSystemApplication |
| 设置 | ChangeAppSetting, QueryAppSetting, QueryGlobalSetting, RegisterSettingCallback, UnregisterSettingCallback |
| 投递 | Deliver, GetPayloadForNotificationId, Submit, PostScheduledNotification |
| 查询 | GetRegisteredHandler, GetRegisteredHandlersFromParent, GetSettingsFromHandler, GetAssetsFromHandler |
| 规则 | 捕获内容 |
|---|
WPN_EoP_ChildProcess | svchost(netsvcs)派生 cmd/powershell/wscript |
WPN_PipeAccess | 与 WPN 相关的命名管道的连接 |
WPN_FileCreation | 在通知数据目录中创建文件 |
WPN_RegistryTampering | 对 PushNotifications 注册表项的写入 |
WPN_ProcessAccess | 获取对 svchost 的 PROCESS_ALL_ACCESS 句柄 |
WPN_ThreadInjection | 向 svchost 注入 CreateRemoteThread |
| CVE | 类型 | CWE |
|---|
| CVE-2026-42977 | 权限提升 | 竞争条件 |
| CVE-2026-42978 | 权限提升 | 竞争条件 |
| CVE-2026-42979 | 权限提升 | 竞争条件 |
| CVE-2026-42991 | 权限提升 | 竞争条件 |
| CVE-2026-42969 | 信息泄露 | 竞争条件 |
| CVE-2026-42970 | 信息泄露 | 竞争条件 |
| CVE-2026-42973 | 信息泄露 | 竞争条件 |
| CVE-2026-26167 | 权限提升 | — |
| CVE-2026-32160 | 权限提升 | — |