
# Script de evaluación de PowerShell que comprueba sistemas Windows para CVE-2025-47981 (desbordamiento de montón SPNEGO NEGOEX) verificando la versión del kernel, la clave de registro PKU2U y los puertos SPNEGO expuestos. Proporciona pasos de remediación y orientación de detección.
Tipo: Evaluación de Vulnerabilidad — Detección / Verificación de Cumplimiento CVE: CVE-2025-47981 CVSS: 9.8 Crítico (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) CWE: CWE-122 — Desbordamiento de Búfer Basado en Heap Alias: "SPNEGO Nightmare" / "RCE Wormable de Autenticación de Windows" Parche: KB5062560 | Patch Tuesday de Julio 2025
Script PowerShell de evaluación que verifica si un sistema Windows es vulnerable al CVE-2025-47981 — desbordamiento de búfer basado en heap en el mecanismo SPNEGO Extended Negotiation (NEGOEX) que permite RCE sin autenticación. No ejecuta exploits — solo evalúa exposición y estado del parche.
Desarrollado por: HKK$ cat ./vulnerability_summary.txtCVE-2025-47981 es un desbordamiento de búfer basado en heap en el protocolo NEGOEX — la capa de extensión interna del mecanismo de autenticación SPNEGO de Windows. La vulnerabilidad permite que atacantes no autenticados ejecuten código remoto arbitrario, obteniendo potencialmente control total del sistema.
Analistas ya han descrito el CVE como teniendo "las características desafortunadas de convertirse en un problema significativo", con potencial wormable — capaz de propagarse automáticamente entre sistemas vulnerables sin interacción del usuario.
La vulnerabilidad afecta a Windows 10 (versión 1607 en adelante) y a todos los Windows Server desde 2008 R2 hasta Server 2025, incluyendo variantes Server Core — más de 33 configuraciones distintas de Windows y Server confirmadas como vulnerables en arquitecturas x64, x86 y ARM64.
$ cat ./technical_background.txtSPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) es la capa de handshake de autenticación que Windows usa antes de cada sesión autenticada. Las aplicaciones frecuentemente necesitan autenticación sin fijar un protocolo — Windows puede usar Kerberos en un entorno, NTLM en otro, o un mecanismo de autenticación extendido en un modelo de confianza diferente. SPNEGO es el mecanismo de negociación que decide qué protocolo de autenticación usar.
Cliente Servidor
│ │
│──── SPNEGO Negotiation ────────►│
│ MechTypeList: │
│ [Kerberos, NTLM, NEGOEX] │
│ │
│◄─── Selected Mechanism ─────────│
│ │
│──── Auth Exchange ─────────────►│ ← overflow aquí en NEGOEX
NEGOEX es el mecanismo de extensión dentro de SPNEGO — permite que autenticaciones PKU2U (peer-to-peer) y otros mecanismos personalizados sean negociados. La vulnerabilidad está en la función ntoskrnl!SpnegoHandleExtended, que procesa estructuras SPNEGO_TOKEN de tamaño excesivo enviadas en múltiples fragmentos, causando desbordamiento en el heap del kernel.
El riesgo es elevado en sistemas donde la Group Policy "Network security: Allow PKU2U authentication requests to this computer to use online identities" está habilitada. Esta configuración, habilitada por defecto en muchos despliegues de Windows, amplifica la superficie de ataque de NEGOEX al permitir autenticación peer-to-peer que activa la ruta de código vulnerable de NEGOEX en endpoints que de otra forma no la expondrían.
$ cat ./architecture.txt┌─────────────────────────────────────────────────────────────────────────┐
│ CVE-2025-47981 ASSESSMENT SCRIPT — FLOW │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 1: Windows Version │ │
│ │ Get-CimInstance Win32_OperatingSystem → .Version │ │
│ │ Contexto: identifica el build exacto para correlación con patch│ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 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 aplicado │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 3: PKU2U Registry Key │ │
│ │ HKLM:\SYSTEM\...\Lsa\pku2u\AllowOnlineID │ │
│ │ 1 → PKU2U habilitado → superficie de ataque ampliada │ │
│ │ 0 → PKU2U deshabilitado → vector PKU2U mitigado │ │
│ │ No existe → configuración predeterminada (evaluar vía GPO) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 4: Puertos SPNEGO Expuestos │ │
│ │ Get-NetTCPConnection → 135, 445, 5985, 3389, 80, 443, 25 │ │
│ │ Cada puerto abierto = un vector de entrega del exploit │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ Format-Table -AutoSize │
│ (salida legible para informe de pentest) │
└─────────────────────────────────────────────────────────────────────────┘
$ 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 - Parche ausente ($missingKB)"
}
¿Por qué ntoskrnl.exe y no Get-HotFix?
Get-HotFix lista KBs instalados, pero tiene limitaciones conocidas:
DISM o Windows Update en modo silenciosoVerificar la versión de ntoskrnl.exe directamente es más confiable — el archivo solo recibe la versión parcheada cuando el KB ha sido efectivamente aplicado y el sistema reiniciado. Un sistema con KB pendiente de reinicio aún tendrá la versión antigua del kernel en memoria.
[version] cast: PowerShell compara strings lexicográficamente por defecto — "10.0.14393.8246" -lt "10.0.14393.800" sería $false (incorrecto). El cast a [version] garantiza comparación numérica correcta por octeto.
[System.IO.Path]::Combine($env:SystemRoot, ...): usa SystemRoot en lugar de C:\Windows hardcodeado — portable para sistemas con Windows instalado en unidades diferentes.
10.0.14393.824610.0.14393.xxxx → Windows 10 version 1607 / Windows Server 2016
│
└─ 8246 = build con KB5062560 aplicado
¿Por qué este build específico?
Windows Server 2016 (build base 14393) es uno de los entornos más críticos para parcheo — ampliamente usado en DCs, file servers y servicios internos corporativos. La versión 8246 corresponde al build del kernel después de la aplicación del KB5062560 (Julio 2025).
Para otros sistemas operativos, el número de build mínimo requerido es diferente — el script puede extenderse con una tabla de versiones por SO.
AllowOnlineID$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\pku2u"
$regName = "AllowOnlineID"
¿Qué controla esta clave?
La vulnerabilidad afecta principalmente a sistemas donde la Group Policy "Allow PKU2U authentication requests to this computer to use online identities" está habilitada por defecto, lo cual es el caso para Windows 10 versión 1607 en adelante.
La clave AllowOnlineID es la representación en registry de esa Group Policy. Cuando está habilitada (= 1), el sistema acepta autenticaciones PKU2U — activando la ruta de código de NEGOEX que contiene el desbordamiento.
| Valor | Estado | Riesgo |
|---|---|---|
1 | PKU2U habilitado | ALTO — vector de NEGOEX activado |
0 | PKU2U deshabilitado | BAJO — vector mitigado (parche aún necesario) |
| No existe | Predeterminado del sistema | Depende de la GPO — verificar vía gpresult /r |
-ErrorAction SilentlyContinue: la clave puede no existir en todos los sistemas — el script maneja graciosamente la ausencia sin generar error.
$ports = @(135, 445, 5985, 3389, 80, 443, 25)
Los atacantes pueden explotar la falla remotamente sin autenticación enviando paquetes maliciosos a servicios vulnerables como SMB (puerto 445/TCP), RDP (puerto 3389/TCP), HTTP/S (puertos 80, 443/TCP) y SMTP (puerto 25/TCP) que utilizan autenticación SPNEGO.
| Puerto | Protocolo | SPNEGO usado para |
|---|---|---|
135 | RPC Endpoint Mapper | Negociación de autenticación RPC |
445 | SMB | Autenticación de file shares, named pipes |
5985 | WinRM (HTTP) | PowerShell remoting, gestión |
3389 | RDP | Autenticación de Remote Desktop |
80 | HTTP | Autenticación de Windows de IIS (Negotiate) |
443 | HTTPS | Autenticación de Windows de IIS vía TLS |
25 | SMTP | Exchange Extended Protection |
Get-NetTCPConnection -LocalPort $port verifica si el puerto está en LISTEN en el sistema local — cada puerto abierto representa un vector de entrega independiente para el exploit.
$ cat ./mitre_mapping.yml# Perspectiva del ATACANTE (lo que el script detecta/previene)
tactic: Initial Access
- T1190 # Exploit Public-Facing Application
# RCE vía desbordamiento de heap SPNEGO sin autenticación
# Vector: cualquier puerto con auth Negotiate (445, 5985, 3389...)
tactic: Execution
- T1203 # Exploitation for Client Execution
# Desbordamiento de heap en ntoskrnl!SpnegoHandleExtended
# Control de RIP/EIP vía corrupción del heap del kernel
tactic: Lateral Movement
- T1210 # Exploitation of Remote Services
# Wormable: explota otros hosts vía SMB/RPC sin credenciales
- T1550.002 # Pass-the-Hash
# Post-RCE: acceso SYSTEM permite extracción de hashes LSASS
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# Desbordamiento de búfer en contexto del kernel → ring 0 inmediato
# Perspectiva del DEFENSOR (lo que el script de evaluación ejecuta)
tactic: Discovery (Blue Team)
- T1082 # System Information Discovery
# Recopila versión del SO y ntoskrnl.exe para evaluación de parche
- T1012 # Query Registry
# Verifica HKLM:\...\pku2u\AllowOnlineID
- T1049 # System Network Connections Discovery
# Get-NetTCPConnection para mapear puertos SPNEGO expuestos
$ cat ./detection_opportunities.md# Anomalía de autenticación NEGOEX — paquetes SPNEGO de tamaño excesivo
# Fuente: Windows Security Event Log / ETW
EventID: 4625 (Logon Failure) con SubStatus 0xC000006D
+ Origen: hosts externos
+ Frecuencia: alta (intentos de scan/exploit)
+ TargetUserName: ANONYMOUS LOGON O vacío
# Alternativa: Sysmon Event 3 (Network Connection)
EventID: 3
Condición:
DestinationPort: 445 O 5985 O 135
Initiated: false (conexión entrante)
Image: System O lsass.exe
# Crash del kernel post-exploit fallido
# Fuente: Windows Event Log → System
EventID: 1001 (BugCheck)
BugCheckCode: 0x00000050 (PAGE_FAULT_IN_NONPAGED_AREA)
O
BugCheckCode: 0x0000007E (SYSTEM_THREAD_EXCEPTION_NOT_HANDLED)
Contexto: Crash en ntoskrnl.exe → posible intento de exploit
# Snort/Suricata — token SPNEGO de tamaño excesivo (conceptual)
alert tcp any any -> $HOME_NET [445,5985,3389] (
msg:"CVE-2025-47981 SPNEGO NEGOEX oversized token";
content:"|60|"; # Marcador OID SPNEGO
content:"|a0|"; # Marcador MechTypeList
dsize:>4096; # los tokens legítimos raramente exceden 4KB
threshold:type both, track by_src, count 3, seconds 10;
sid:2025479810;
)
$ cat ./remediation.mdPRIORIDAD: CRÍTICA — Parche inmediato (CVSS 9.8, wormable)
1. PARCHE (acción principal):
Windows Update → KB5062560 (Patch Tuesday de Julio 2025)
WSUS: aprobar KB5062560 para todos los sistemas Windows 10 1607+
REINICIAR después del parche — ntoskrnl.exe solo se reemplaza tras reinicio
2. VERIFICACIÓN POST-PARCHE:
Ejecutar este script nuevamente
Resultado esperado:
ntoskrnl.exe Installed Version: 10.0.14393.8246 (o superior)
Vulnerability Result: Seguro - Parche aplicado
3. MITIGACIÓN TEMPORAL (si el parche inmediato no es viable):
Deshabilitar PKU2U vía Group Policy:
Computer Configuration → Windows Settings → Security Settings →
Local Policies → Security Options →
"Network security: Allow PKU2U authentication requests..." → DISABLED
O vía registry:
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\pku2u"
-Name AllowOnlineID -Value 0
4. BLOQUEO DE RED (defense-in-depth):
Firewall: restringir inbound 135, 445, 5985 a hosts autorizados
Segmentar DCs y servidores críticos en VLANs con ACLs estrictas
5. PRIORIDAD ESPECIAL — Domain Controllers:
Los DCs exponen todos los puertos listados (RPC, SMB, LDAP)
Wormable + DC comprometido = compromiso completo del dominio AD
Parchear DCs en la primera ventana disponible
$ cat ./usage.sh# Ejecutar el script de evaluación (no requiere privilegios de admin para lectura básica,
# pero algunos checks de registry pueden necesitar elevación)
powershell.exe -ExecutionPolicy Bypass -File cve_2025_47981_check.ps1
# Salida esperada en sistema VULNERABLE:
Name Value
---- -----
ntoskrnl.exe Installed Version 10.0.14393.7906
ntoskrnl.exe Required Version 10.0.14393.8246
PKU2U AllowOnlineID 1
Puertos SPNEGO abiertos {135, 445, 5985, 3389}
Vulnerability Result Vulnerable - Parche ausente (KB5062560)
Windows Version 10.0.14393.7906
# Salida esperada en sistema PARCHEADO:
Vulnerability Result Seguro - Parche aplicado
PKU2U AllowOnlineID 0
$ cat ./affected_versions.txtAFECTADOS (33+ configuraciones):
Windows 10: 1607, 1809, 21H2, 22H2
Windows 11: 22H2, 23H2, 24H2
Windows Server: 2008 R2, 2012, 2012 R2, 2016, 2019, 2022, 2025
Arquitecturas: x64, x86, ARM64
Server Core: Sí (todas las versiones anteriores)
FACTOR DE RIESGO ELEVADO:
GPO PKU2U habilitada (predeterminada en Win10 1607+)
Puertos 135/445/5985 accesibles desde redes externas o no confiables
PARCHE:
KB5062560 → Patch Tuesday de Julio 2025
ntoskrnl.exe mínimo → 10.0.14393.8246 (Windows Server 2016)
Verificar builds específicos por versión en: msrc.microsoft.com
$ cat ./lessons_learned.txt[+] Comparar [version] en lugar de string evita falsos negativos en comparaciones de build
[+] ntoskrnl.exe es fuente primaria de verdad para estado de parche — más confiable que Get-HotFix
[+] PKU2U AllowOnlineID es el amplificador del riesgo — sistemas sin él tienen superficie reducida
[+] Get-NetTCPConnection mapea rápidamente la superficie de ataque expuesta localmente
[+] Format-Table -AutoSize genera salida lista para copiar en informe de pentest
[-] El script verifica solo Windows Server 2016 (14393) — extender a otros builds es necesario
[-] No verifica estado de la GPO vía gpresult — el registry puede divergir de la política efectiva
[-] No prueba conectividad remota — solo verifica si los puertos están abiertos localmente
[-] Sin salida en JSON/CSV — difícil integrar en pipelines de cumplimiento automatizados
[→] Mejoras: tabla de versiones por SO, salida en JSON, verificación remota vía Invoke-Command,
integración con Qualys/Tenable para correlación de vulnerabilidad
Evaluación CVE · CVSS 9.8 · Wormable · Patch Tuesday de Julio 2025 · Solo detección · Sin exploit