A haunted-house creak from 2012 that scanners keep flagging but attackers stopped trying to weaponize a decade ago
MS12-020 bundles two RDP flaws, headlined by CVE-2012-0002, a use-after-free in the way RDPWD.SYS handles the maxChannelIDs field of a T.125 ConnectMCSPDU packet during the pre-authentication phase of RDP session setup. On paper it's a pre-auth remote code execution against Windows XP SP2/SP3, Server 2003 SP2, Vista SP2, Server 2008/2008 R2, and Windows 7 GA/SP1 — every RDP listener on the planet in early 2012. If Network Level Authentication (NLA) is enabled the attacker must first authenticate, collapsing the bug to post-auth; if NLA is off, it's wire-reachable.
Microsoft rated this Critical and Tenable inherited it as HIGH. That was defensible in March 2012, when Windows XP and 2003 dominated fleets and NLA was rare. In 2026 the calculus is different: every affected OS is end-of-life, NLA has been the default since Windows 8/2012, and despite 14 years of researcher attention the only public weapon is the Metasploit *DoS* module (ms12_020_maxchannelids) plus Chinese-forum BSOD PoCs — no reliable public RCE ever materialized. The vendor label overstates the practical risk on any modern fleet; it's still real on the XP/2003 ghosts sitting in OT closets.
4 steps from start to impact.
Reach TCP/3389 on an affected host
port:3389 os:"Windows XP"; internal exposure is common on flat OT/legacy segments.- TCP/3389 reachable
- target running unpatched pre-Win8 Windows
- RDP service enabled
- Every affected OS is EOL — modern fleets don't have them
- Perimeter firewalls almost never expose 3389 externally in 2026
- Internal segmentation and jump-host patterns limit east-west 3389
Confirm NLA is disabled
- NLA off on target
- or valid domain credentials for post-auth reach
- NLA has been widely deployed since ~2013
- CIS/DISA STIGs mandate NLA
- Even legacy 2008 R2 hosts commonly have NLA forced by GPO
rdp-enum-encryption NSE script, Nessus plugin 58453 (Terminal Services NLA check).Send crafted T.125 ConnectMCSPDU with malformed maxChannelIDs
rdpclient.py, or Metasploit auxiliary/dos/windows/rdp/ms12_020_maxchannelids — to send a specially crafted ConnectMCSPDU packet that triggers a use-after-free in RDPWD.SYS. This reliably produces a BSOD 0x9F / BUGCODE_USB_DRIVER-style crash. Achieving code execution requires controlling the freed-object reuse under kernel non-paged pool pressure.- Working PoC/tool
- packet path to 3389
- target under attacker-influenced memory pressure for RCE
- Public tooling is DoS-only
- Kernel pool grooming on XP/2003/7 is fragile across hotfix levels
- No commodity weaponization exists after 14 years of researcher attention
SID 2014384/2014385 fire on the malformed packet pattern; kernel crash telemetry from EDR.Achieve kernel RCE (theoretical) or settle for DoS
- Reliable exploit primitive
- No public reliable RCE
- Modern EDR (where deployed on legacy hosts) catches post-exploitation quickly
The supporting signals.
| In the wild | No confirmed RCE campaigns. Widespread opportunistic DoS scanning throughout 2012–2015. Never added to CISA KEV. |
|---|---|
| Public PoC | Metasploit auxiliary/dos/windows/rdp/ms12_020_maxchannelids (DoS), Luigi Auriemma's original packet capture, numerous Python rdpclient.py derivatives on GitHub — all DoS-only |
| EPSS | ~0.94 (very high percentile) — reflects age and scanner noise, not observed RCE |
| KEV status | Not listed. CISA has never added CVE-2012-0002 to the Known Exploited Vulnerabilities catalog |
| CVSS v2 | AV:N/AC:M/Au:N/C:C/I:C/A:C = 9.3 — the pre-NLA-default era rating |
| Affected | Windows XP SP2/SP3, Server 2003 SP2, Vista SP2, Server 2008 SP2, Server 2008 R2 (SP0/SP1), Windows 7 GA/SP1 — all EOL |
| Fixed in | KB2621440 (Windows), KB2667402 (Terminal Server), released 2012-03-13 |
| Exposure | Shodan shows <50k public 3389 listeners identifying as XP/2003/Vista globally in 2026, most in residential/APAC ranges; enterprise external exposure is negligible |
| Disclosed | 2012-03-13 (Patch Tuesday) |
| Reporter | Luigi Auriemma via ZDI (ZDI-12-044) |
noisgate verdict.
MEDIUM because every affected operating system is end-of-life and no reliable public RCE has emerged in 14 years — the decisive factor is the absence of a working weapon combined with a near-zero modern installed base. The flag on your scanner report is almost always a legacy Windows 7 / 2008 R2 host that needs decommissioning, not an active RCE hazard.
Why this verdict
- No weaponized RCE in 14 years: despite Metasploit, ZDI attention, and Luigi Auriemma's original research, every public artifact is a DoS. Kernel UAF exploitation on XP/2003/7 non-paged pool never became commodity.
- NLA neutralizes the pre-auth path: Network Level Authentication has been default since Windows 8/2012 and is universally enforced by CIS/DISA baselines. On any NLA-enforced host the bug collapses to post-auth.
- Installed base collapse: Windows XP, Server 2003, Vista, Server 2008, and Windows 7 are all past end-of-support. A 2026 enterprise finding this plugin fire is almost certainly looking at an isolated legacy appliance, not a production Windows fleet.
- Not KEV-listed: CISA has never added CVE-2012-0002, reflecting the absence of confirmed exploitation-in-the-wild evidence over 14 years.
- Role multiplier — legacy DC / OT HMI: if the flagged host is a Windows 2008 R2 domain controller still in production or an XP-embedded SCADA HMI, a DoS bugcheck causes real operational impact and the host itself is a fleet-wide risk regardless of this CVE. Fix the deployment role, not just this bug.
Why not higher?
HIGH would require either active KEV listing, a working public RCE, or meaningful modern-OS exposure — none exist. The bug is real but 14 years of researcher pressure produced only denial-of-service, and CVSS v2's 9.3 was calibrated against a pre-NLA-default world that no longer exists.
Why not lower?
LOW/IGNORE would ignore that this scanner finding is a reliable canary for an unpatched, end-of-life Windows host on your network — which is itself a serious hygiene failure and a target for dozens of *other* unpatched CVEs (MS17-010, BlueKeep, PrintNightmare). The host needs remediation; the CVE just points at it.
What to do — in priority order.
- Enable Network Level Authentication on every RDP-capable host — GPO:
Computer Configuration → Admin Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Security → Require user authentication for remote connections by using Network Level Authentication = Enabled. This collapses the pre-auth attack surface. Deploy in the standard MEDIUM 365-day remediation window; no mitigation SLA required. - Block TCP/3389 at the perimeter and enforce jump-host-only RDP internally — External 3389 exposure has no legitimate enterprise use case in 2026. Use ZTNA / Entra Private Access / RDGateway for remote admin. Roll out as part of standing edge hygiene.
- Inventory and decommission every affected OS — Windows XP, 2003, Vista, 2008, 2008 R2, and 7 are all EOL. If Nessus 58435 fires, that host is carrying dozens of other unpatched CVEs. Prioritize the host, not the CVE — 365-day decommission plan is the noisgate remediation SLA baseline for MEDIUM.
- Deploy KB2621440 / KB2667402 on any legacy host that cannot be retired — The patch is 14 years old and stable. There is no reason a host still running these OSes shouldn't already have it — its absence signals a broken patch pipeline that needs fixing.
- RDP account lockout policies — the vulnerable code executes before credential validation when NLA is off, so lockouts are never triggered.
- Strong RDP passwords — irrelevant to a pre-auth code path.
- TLS-wrapped RDP (SSL cert on 3389) — the bug is in the MCS channel setup that runs inside the encrypted session; wrapping does not remove the vulnerable code.
Crowdsourced verification payload.
Run on the target Windows host as Administrator to check for the KB2621440 hotfix and NLA state. Invoke: powershell -ExecutionPolicy Bypass -File Check-MS12-020.ps1. Outputs VULNERABLE, PATCHED, or UNKNOWN and exits with codes 1/0/2 respectively.
#requires -RunAsAdministrator
# Check-MS12-020.ps1 — noisgate verification for CVE-2012-0002 / MS12-020
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
$ErrorActionPreference = 'Stop'
# 1. OS applicability
$os = (Get-CimInstance Win32_OperatingSystem).Version
$major = [int]$os.Split('.')[0]
$minor = [int]$os.Split('.')[1]
# Vulnerable: 5.1 (XP), 5.2 (2003), 6.0 (Vista/2008), 6.1 (7/2008R2)
$vulnerableFamily = ($major -eq 5) -or ($major -eq 6 -and $minor -le 1)
if (-not $vulnerableFamily) {
Write-Output 'PATCHED (OS family not affected by MS12-020)'
exit 0
}
# 2. Hotfix check — KB2621440 (Windows) or KB2667402 (Terminal Server)
try {
$hotfixes = Get-HotFix -ErrorAction Stop | Select-Object -ExpandProperty HotFixID
} catch {
Write-Output 'UNKNOWN (could not enumerate hotfixes)'
exit 2
}
$patched = ($hotfixes -contains 'KB2621440') -or ($hotfixes -contains 'KB2667402')
# 3. NLA state (mitigating factor, not a fix)
$nla = 'unknown'
try {
$ts = Get-CimInstance -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'" -ErrorAction Stop
$nla = if ($ts.UserAuthenticationRequired -eq 1) { 'enabled' } else { 'disabled' }
} catch { $nla = 'unknown' }
if ($patched) {
Write-Output "PATCHED (KB2621440/2667402 present; NLA=$nla)"
exit 0
} else {
Write-Output "VULNERABLE (KB2621440/2667402 missing; NLA=$nla; OS=$os)"
exit 1
}
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.