
PowerShell assessment script that checks Windows systems for CVE-2025-47981 (SPNEGO NEGOEX heap overflow) by verifying kernel version, PKU2U registry key, and exposed SPNEGO ports. Provides remediation steps and detection guidance.
Type: Vulnerability Assessment — Detection / Compliance Check CVE: CVE-2025-47981 CVSS: 9.8 Critical (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) CWE: CWE-122 — Heap-based Buffer Overflow Alias: "SPNEGO Nightmare" / "Windows Authentication Wormable RCE" Patch: KB5062560 | July 2025 Patch Tuesday
PowerShell assessment script that checks whether a Windows system is vulnerable to CVE-2025-47981 — heap-based buffer overflow in the SPNEGO Extended Negotiation (NEGOEX) mechanism that allows unauthenticated RCE. Does not execute an exploit — only assesses exposure and patch status.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2025-47981 is a heap-based buffer overflow in the NEGOEX protocol — the internal extension layer of the Windows SPNEGO authentication mechanism. The vulnerability allows unauthenticated attackers to execute arbitrary remote code, potentially gaining full control of the system.
Analysts have already described the CVE as having "the unfortunate characteristics of becoming a significant problem," with wormable potential — capable of automatically spreading between vulnerable systems without user interaction.
The vulnerability affects Windows 10 (version 1607 and later) and all Windows Server from 2008 R2 through Server 2025, including Server Core variants — more than 33 distinct Windows and Server configurations confirmed vulnerable on x64, x86, and ARM64 architectures.
$ cat ./technical_background.txtSPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) is the authentication handshake layer that Windows uses before every authenticated session. Applications often need authentication without committing to a protocol — Windows may use Kerberos in one environment, NTLM in another, or an extended authentication mechanism in a different trust model. SPNEGO is the negotiation mechanism that decides which authentication protocol to use.
Client Server
│ │
│──── SPNEGO Negotiation ────────►│
│ MechTypeList: │
│ [Kerberos, NTLM, NEGOEX] │
│ │
│◄─── Selected Mechanism ─────────│
│ │
│──── Auth Exchange ─────────────►│ ← overflow here in NEGOEX
NEGOEX is the extension mechanism within SPNEGO — it allows PKU2U (peer-to-peer) authentications and other custom mechanisms to be negotiated. The vulnerability is in the ntoskrnl!SpnegoHandleExtended function, which processes oversized SPNEGO_TOKEN structures sent in multiple fragments, causing a kernel heap overflow.
The risk is elevated on systems where the Group Policy "Network security: Allow PKU2U authentication requests to this computer to use online identities" is enabled. This setting, enabled by default in many Windows deployments, broadens the NEGOEX attack surface by allowing peer-to-peer authentication that activates the vulnerable NEGOEX code path on endpoints that would otherwise not expose it.
$ cat ./architecture.txt┌─────────────────────────────────────────────────────────────────────────┐
│ CVE-2025-47981 ASSESSMENT SCRIPT — FLOW │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 1: Windows Version │ │
│ │ Get-CimInstance Win32_OperatingSystem → .Version │ │
│ │ Context: identifies the exact build for patch correlation │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 2: ntoskrnl.exe Version │ │
│ │ Get-Item C:\Windows\System32\ntoskrnl.exe │ │
│ │ Compare: installed < 10.0.14393.8246 → VULNERABLE │ │
│ │ Compare: installed ≥ 10.0.14393.8246 → KB5062560 applied │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 3: PKU2U Registry Key │ │
│ │ HKLM:\SYSTEM\...\Lsa\pku2u\AllowOnlineID │ │
│ │ 1 → PKU2U enabled → expanded attack surface │ │
│ │ 0 → PKU2U disabled → PKU2U vector mitigated │ │
│ │ Does not exist → default configuration (assess via GPO) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 4: Exposed SPNEGO Ports │ │
│ │ Get-NetTCPConnection → 135, 445, 5985, 3389, 80, 443, 25 │ │
│ │ Each open port = an exploit delivery vector │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ Format-Table -AutoSize │
│ (output readable for pentest report) │
└─────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdntoskrnl.exe$kernelPath = [System.IO.Path]::Combine($env:SystemRoot, "System32\ntoskrnl.exe")
$requiredVersion = "10.0.14393.8246"
$installedVersion = (Get-Item $kernelPath).VersionInfo.FileVersion
if ([version]$installedVersion -lt [version]$requiredVersion) {
"Vulnerable - Patch missing ($missingKB)"
}
Why ntoskrnl.exe and not Get-HotFix?
Get-HotFix lists installed KBs, but has known limitations:
DISM or Windows Update in silent modeChecking the ntoskrnl.exe version directly is more reliable — the file only receives the patched version when the KB has been effectively applied and the system rebooted. A system with a KB pending reboot will still have the old kernel version in memory.
[version] cast: PowerShell compares strings lexicographically by default — "10.0.14393.8246" -lt "10.0.14393.800" would be $false (wrong). The cast to [version] ensures correct numeric comparison per octet.
[System.IO.Path]::Combine($env:SystemRoot, ...): uses SystemRoot instead of hardcoded C:\Windows — portable for systems with Windows installed on different drives.
10.0.14393.824610.0.14393.xxxx → Windows 10 version 1607 / Windows Server 2016
│
└─ 8246 = build with KB5062560 applied
Why this specific build?
Windows Server 2016 (base build 14393) is one of the most critical environments for patching — widely used in DCs, file servers, and corporate internal services. Version 8246 corresponds to the kernel build after applying KB5062560 (July 2025).
For other operating systems, the minimum required build number is different — the script can be extended with a version table per OS.
AllowOnlineID