Like handing a burglar the building's master-key floor plan right before they try to pick the lock
CVE-2026-20805 is an information disclosure flaw in the Windows Desktop Window Manager (dwm.exe) that leaks ALPC port section addresses from user-mode memory. By calling NtQuerySystemInformation with the SystemHandleInformation class and filtering for ALPC Port (type index 24/25) and Section Object (type index 36) handles, a local authenticated attacker recovers valid 64-bit kernel virtual addresses. These addresses defeat Kernel Address Space Layout Randomization (KASLR), converting unreliable kernel exploitation attempts into repeatable, weaponized chains. Every supported Windows version is affected: Windows 10 (1607 through 22H2), Windows 11 (23H2, 24H2, 25H2), and Windows Server 2012 through 2025 — essentially every system running a desktop session or Desktop Experience.
Microsoft rated this Important / CVSS 5.5 (Medium), and technically that score is correct for a standalone info-disclosure with no integrity or availability impact. But the vendor score catastrophically undersells the operational reality. This bug was exploited *as a zero-day before the January 2026 patch shipped*, CISA added it to KEV on January 13, 2026, and the ShinyHunters collective weaponized it between January 22–28, 2026. A public PoC exists on GitHub. The EPSS score of 0.072 (88th percentile) further confirms elevated exploitation probability. Information-disclosure bugs that defeat KASLR are the skeleton key of kernel exploit chains — as ZDI noted, *memory leaks can be as important as code execution because they make RCE reliable*. The vendor MEDIUM does not reflect the threat actor demand signal.
5 steps from start to impact.
Attacker obtains local code execution
- Initial access to a Windows endpoint
- Authenticated user-level session (PR:L)
- Requires prior compromise — this is a post-initial-access step
- EDR / email gateway should intercept common initial-access vectors
Enumerate DWM handles via NtQuerySystemInformation
PoC_Script.py) that calls NtQuerySystemInformation(SystemHandleInformation) to enumerate system-wide handles. The tool filters for handles belonging to dwm.exe with ALPC Port (type 24/25) and Section Object (type 36) type indices. This API call requires no elevated privileges — any authenticated user can invoke it.- Local code execution as any authenticated user
- dwm.exe running (present on all Desktop Experience installations)
- Server Core installations do not run dwm.exe — these are not exploitable
- EDR with API-level telemetry may flag bulk handle enumeration
NtQuerySystemInformation abuse patterns; the PoC leaves obvious forensic artifacts (Python process querying system handles)Extract leaked kernel addresses
- Successful handle enumeration from step 2
- Unpatched DWM with improper ALPC structure initialization
- January 2026 cumulative update eliminates the leak
- Virtualization-based security (VBS) with HVCI adds additional isolation layers that reduce the value of leaked addresses
Chain with kernel EoP for SYSTEM
- A chained kernel EoP vulnerability (separate CVE required)
- Leaked addresses from step 3 to calculate gadget/object locations
- Requires a *second* exploitable bug — this CVE alone grants no code execution or privilege escalation
- Exploit Guard / CFG / HVCI raise the bar for kernel code execution even with known addresses
- Kernel exploit development is a specialized skill set
Post-exploitation: credential theft and lateral movement
- SYSTEM-level access from step 4
- Network adjacency to additional targets for lateral movement
- Credential Guard protects LSASS on modern Win11 Enterprise deployments
- Network segmentation limits lateral movement blast radius
- PAM / tiered administration limits value of harvested credentials
dwm.exe. Domain controllers, file servers, and application servers on Server Core are not affected by this vulnerability at all. This is a long-term architectural control; migrate DCs and critical servers to Server Core within the noisgate remediation SLA of 180 days for HIGH.NtQuerySystemInformation(SystemHandleInformation) to enumerate system-wide handles and filter for DWM ALPC/Section objects. EDR products with API-level telemetry (CrowdStrike, Defender for Endpoint, SentinelOne) can alert on this pattern. This is a detection control, not prevention — it reduces dwell time but does not block exploitation.- Network segmentation / firewalls — This is a local vulnerability (AV:L). Network controls do not prevent exploitation once the attacker has local code execution. Segmentation helps limit *lateral movement after* the chain completes, but does not address the vulnerability itself.
- Web Application Firewalls (WAF) — DWM is a local OS component, not a web service. WAF rules have no visibility into local API calls to NtQuerySystemInformation.
- Disabling DWM — DWM cannot be disabled on modern Windows (Windows 8+). It is a protected system process. Any guidance suggesting 'disable Desktop Window Manager' is outdated and inapplicable.
- AppLocker / WDAC alone — Application control can block the Python-based PoC, but a motivated attacker will reimplement the same NtQuerySystemInformation calls in a whitelisted process (e.g., PowerShell with AMSI bypass, or a compiled .NET assembly). AppLocker raises the bar but does not eliminate the attack surface.
The supporting signals.
| In-the-wild exploitation | Confirmed. Exploited as a zero-day before the January 14, 2026 patch. ShinyHunters collective weaponized it January 22–28, 2026 per Proofpoint. CISA added it to KEV on January 13, 2026. |
|---|---|
| Proof-of-concept | Public. Uzair-Baig0900/CVE-2026-20805-PoC — Python script using NtQuerySystemInformation + handle filtering. Trivial to adapt. |
| EPSS | 0.07203 (7.2%) — 88th percentile. Significantly elevated exploitation probability relative to the general CVE population. |
| CISA KEV | Listed. Added January 13, 2026. FCEB remediation deadline: February 3, 2026 (now past). |
| CVSS vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N — Local attack vector, low complexity, low privileges, no user interaction. Confidentiality impact is High; no integrity or availability impact. Scope Unchanged limits blast radius to the vulnerable component's authorization scope. |
| Affected versions | Windows 10 (1607, 1809, 21H2, 22H2), Windows 11 (23H2, 24H2, 25H2), Windows Server 2012/R2, 2016, 2019, 2022, 23H2, 2025. Both x64 and ARM64 where applicable. Essentially every supported Windows SKU. |
| Fixed versions | January 14, 2026 cumulative updates (Patch Tuesday). Any CU from January 2026 or later includes the fix. KB5073455 confirmed for Server 2025. |
| Scanning / exposure | Local-only vulnerability (AV:L) — not remotely scannable via Shodan/Censys/GreyNoise. Exposure is measured by unpatched endpoint count, not internet-facing surface. Shodan CVEDB tracks affected build distributions. |
| Disclosure date | January 7, 2026 (pre-disclosure); patched January 14, 2026 (Patch Tuesday); KEV added January 13, 2026. |
| Reporter | Reported to Microsoft via coordinated disclosure. Microsoft Threat Intelligence Center (MSTIC) confirmed active exploitation. Detailed analysis by Kev Breen (Immersive Labs), Rapid7, and Tenable. |
Sources.
- CISA KEV Alert — January 13, 2026
- SOC Prime — CVE-2026-20805 Analysis
- Rapid7 — January 2026 Patch Tuesday
- Tenable — January 2026 Patch Tuesday (113 CVEs)
- Krebs on Security — Patch Tuesday January 2026
- Penligent — DWM Memory Leak Analysis
- GitHub PoC — Uzair-Baig0900/CVE-2026-20805-PoC
- NSFOCUS — January 2026 Microsoft Security Update
Why this verdict
- Active exploitation overrides standalone CVSS. This was exploited as a zero-day before the patch shipped, KEV-listed on day one, and weaponized by ShinyHunters within two weeks. The CVSS 5.5 measures theoretical standalone impact; the real-world signal says attackers value this bug enough to burn it in live campaigns.
- Chain-multiplier effect. This is not a standalone info-disc — it is an exploit reliability amplifier. KASLR bypass converts ~5% success-rate kernel exploits into near-deterministic chains. ZDI's observation that 'memory leaks can be as important as code execution' applies directly. Scoring this as a standalone 5.5 ignores how threat actors actually use it.
- Universal blast radius. DWM runs on every Desktop Experience Windows installation — workstations, RDP servers, domain controllers with Desktop Experience, and application servers. The affected population is effectively the entire Windows fleet.
- Public PoC lowers the bar. The GitHub PoC requires only Python and an authenticated user session. No exploit development skill is needed to use the info-disc primitive; the attacker's only remaining challenge is sourcing the chained EoP.
- Role multiplier: On workstations (majority of installs), the chain ends in SYSTEM → credential theft → lateral movement — blast radius is host-level, extending to network-level via pass-the-hash. On RDP/terminal servers (~10–15% of server installs), SYSTEM compromises all concurrent user sessions — blast radius is tenant-level. On domain controllers running Desktop Experience (~20–30% of DCs in SMB environments), SYSTEM means domain admin — blast radius is domain/fleet-level. The DC scenario meets the HIGH floor: chain succeeds in a high-value role, outcome is domain takeover, and ≥1% of the installed base occupies that role.
- Friction is real but insufficient to stay MEDIUM. Local access is required (post-initial-access), and a second bug is needed for meaningful impact. These are genuine narrowing factors — but they apply to *every* local EoP chain, and threat actors demonstrably clear these hurdles in practice, as the KEV listing proves.
Why not higher?
CRITICAL would require standalone impact or a self-contained chain. CVE-2026-20805 alone achieves no code execution, no privilege escalation, and no data exfiltration — it only leaks kernel addresses. The attacker *must* source and chain a separate kernel EoP vulnerability to achieve meaningful impact. The local-access prerequisite (AV:L, PR:L) means the attacker is already past initial access. While the DC/fleet-compromise scenario is real, it requires both the second bug AND a high-value target, making CRITICAL an overstatement for the general population.
Why not lower?
MEDIUM would ignore the KEV listing, confirmed active exploitation, and the chain-multiplier role that threat actors have demonstrably weaponized. The EPSS 88th percentile confirms this is not theoretical. The universal Windows footprint means the exposed population is enormous, and the floor rule is triggered by the domain-controller scenario where the chain ends in domain takeover. Downgrading to the vendor's 5.5 would be negligent given the operational evidence.
Crowdsourced verification payload.
Run on each target Windows host with local administrator privileges. Execute: powershell -ExecutionPolicy Bypass -File .\Check-CVE-2026-20805.ps1. The script checks for the January 2026 cumulative update and verifies whether dwm.exe is present (Server Core exclusion). Exit code 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN.
#Requires -RunAsAdministrator
<#
.SYNOPSIS
CVE-2026-20805 patch verification for Desktop Window Manager KASLR bypass.
.DESCRIPTION
Checks whether the January 2026 (or later) cumulative update is installed,
which includes the fix for CVE-2026-20805. Also checks for Server Core
(dwm.exe absent = not affected).
.OUTPUTS
VULNERABLE | PATCHED | UNKNOWN with exit codes 1, 0, 2 respectively.
#>
$ErrorActionPreference = 'SilentlyContinue'
# Check if DWM is present — Server Core does not have it
$dwmPath = Join-Path $env:SystemRoot 'System32\dwm.exe'
if (-not (Test-Path $dwmPath)) {
Write-Output 'PATCHED - dwm.exe not found. Server Core installation is not affected by CVE-2026-20805.'
exit 0
}
# Determine OS build
try {
$currentBuild = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name CurrentBuild).CurrentBuild
$ubr = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name UBR).UBR
$displayVersion = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name DisplayVersion -ErrorAction SilentlyContinue).DisplayVersion
$productName = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ProductName).ProductName
$fullBuild = "$currentBuild.$ubr"
} catch {
Write-Output "UNKNOWN - Unable to read OS build information from registry."
exit 2
}
Write-Output "[*] OS: $productName ($displayVersion) Build $fullBuild"
Write-Output "[*] Checking for January 2026 or later cumulative update..."
# Check installed hotfixes for any CU from January 2026 onward
$patchCutoff = [datetime]'2026-01-14'
$recentUpdates = Get-HotFix | Where-Object {
$_.InstalledOn -ge $patchCutoff
} | Sort-Object InstalledOn -Descending
if ($recentUpdates -and $recentUpdates.Count -gt 0) {
$latest = $recentUpdates[0]
Write-Output "PATCHED - Update $($latest.HotFixID) installed on $($latest.InstalledOn.ToString('yyyy-MM-dd')). January 2026 CU or later is present. CVE-2026-20805 is remediated."
exit 0
}
# Fallback: check dwm.exe last-write time as a secondary signal
$dwmFile = Get-Item $dwmPath
$dwmLastWrite = $dwmFile.LastWriteTime
if ($dwmLastWrite -ge $patchCutoff) {
Write-Output "PATCHED - dwm.exe was updated on $($dwmLastWrite.ToString('yyyy-MM-dd')), indicating a post-January-2026 patch. Verify with Get-HotFix for certainty."
exit 0
}
# No evidence of patching found
Write-Output "VULNERABLE - No cumulative update from January 2026 or later detected. Build $fullBuild with dwm.exe dated $($dwmLastWrite.ToString('yyyy-MM-dd')). Apply the latest cumulative update immediately."
exit 1