
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
Script PowerShell de assessment que verifica se um sistema Windows está vulnerável ao CVE-2025-47981 — heap-based buffer overflow no mecanismo SPNEGO Extended Negotiation (NEGOEX) que permite RCE sem autenticação. Não executa exploit — apenas avalia exposição e estado de patch.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2025-47981 é um heap-based buffer overflow no protocolo NEGOEX — a camada de extensão interna do mecanismo de autenticação SPNEGO do Windows. A vulnerabilidade permite que atacantes não autenticados executem código remoto arbitrário, potencialmente obtendo controle total do sistema.
Analistas já descreveram a CVE como tendo "as características infelizes de se tornar um problema significativo", com potencial wormable — capaz de se propagar automaticamente entre sistemas vulneráveis sem interação do usuário.
A vulnerabilidade afeta Windows 10 (versão 1607 em diante) e todos os Windows Server de 2008 R2 até Server 2025, incluindo variantes Server Core — mais de 33 configurações distintas de Windows e Server confirmadas vulneráveis em arquiteturas x64, x86 e ARM64.
$ cat ./technical_background.txtSPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) é a camada de handshake de autenticação que o Windows usa antes de cada sessão autenticada. Aplicações frequentemente precisam de autenticação sem fixar um protocolo — o Windows pode usar Kerberos em um ambiente, NTLM em outro, ou um mecanismo de autenticação estendido em um modelo de confiança diferente. SPNEGO é o mecanismo de negociação que decide qual protocolo de autenticação usar.
Cliente Servidor
│ │
│──── SPNEGO Negotiation ────────►│
│ MechTypeList: │
│ [Kerberos, NTLM, NEGOEX] │
│ │
│◄─── Selected Mechanism ─────────│
│ │
│──── Auth Exchange ─────────────►│ ← overflow aqui no NEGOEX
NEGOEX é o mecanismo de extensão dentro do SPNEGO — permite que autenticações PKU2U (peer-to-peer) e outros mecanismos customizados sejam negociados. A vulnerabilidade está na função ntoskrnl!SpnegoHandleExtended, que processa estruturas SPNEGO_TOKEN oversized enviadas em múltiplos fragmentos, causando overflow no heap do kernel.
O risco é elevado em sistemas onde a Group Policy "Network security: Allow PKU2U authentication requests to this computer to use online identities" está habilitada. Essa configuração, habilitada por padrão em muitos deployments do Windows, amplia a superfície de ataque do NEGOEX ao permitir autenticação peer-to-peer que ativa o código path vulnerável do NEGOEX em endpoints que de outra forma não o exporiam.
$ cat ./architecture.txt┌─────────────────────────────────────────────────────────────────────────┐
│ CVE-2025-47981 ASSESSMENT SCRIPT — FLOW │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 1: Windows Version │ │
│ │ Get-CimInstance Win32_OperatingSystem → .Version │ │
│ │ Contexto: identifica o build exato para correlação com patch │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 2: ntoskrnl.exe Version │ │
│ │ Get-Item C:\Windows\System32\ntoskrnl.exe │ │
│ │ Compare: installed < 10.0.14393.8246 → VULNERÁVEL │ │
│ │ Compare: installed ≥ 10.0.14393.8246 → KB5062560 aplicado │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 3: PKU2U Registry Key │ │
│ │ HKLM:\SYSTEM\...\Lsa\pku2u\AllowOnlineID │ │
│ │ 1 → PKU2U habilitado → superfície de ataque ampliada │ │
│ │ 0 → PKU2U desabilitado → vetor PKU2U mitigado │ │
│ │ Não existe → configuração padrão (avaliar via GPO) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ CHECK 4: Portas SPNEGO Expostas │ │
│ │ Get-NetTCPConnection → 135, 445, 5985, 3389, 80, 443, 25 │ │
│ │ Cada porta aberta = um vetor de entrega do exploit │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ Format-Table -AutoSize │
│ (output legível para relatório 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) {
"Vulnerável - Patch ausente ($missingKB)"
}
Por que ntoskrnl.exe e não Get-HotFix?
Get-HotFix lista KBs instalados, mas tem limitações conhecidas:
DISM ou Windows Update em modo silenciosoVerificar a versão do ntoskrnl.exe diretamente é mais confiável — o arquivo só recebe a versão patchada quando o KB foi efetivamente aplicado e o sistema reiniciado. Um sistema com KB pendente de reboot ainda terá a versão antiga do kernel em memória.
[version] cast: PowerShell compara strings lexicograficamente por padrão — "10.0.14393.8246" -lt "10.0.14393.800" seria $false (errado). O cast para [version] garante comparação numérica correta por octeto.
[System.IO.Path]::Combine($env:SystemRoot, ...): usa SystemRoot em vez de C:\Windows hardcoded — portável para sistemas com Windows instalado em drives diferentes.
10.0.14393.824610.0.14393.xxxx → Windows 10 version 1607 / Windows Server 2016
│
└─ 8246 = build com KB5062560 aplicado
Por que esse build específico?
Windows Server 2016 (build base 14393) é um dos ambientes mais críticos para patch — amplamente usado em DCs, file servers e serviços internos corporativos. A versão 8246 corresponde à build do kernel após a aplicação do KB5062560 (Julho 2025).
Para outros sistemas operacionais, o número de build mínimo requerido é diferente — o script pode ser estendido com uma tabela de versões por OS.
AllowOnlineID$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\pku2u"
$regName = "AllowOnlineID"
O que essa chave controla?
A vulnerabilidade afeta principalmente sistemas onde a Group Policy "Allow PKU2U authentication requests to this computer to use online identities" está habilitada por padrão, o que é o caso para Windows 10 versão 1607 em diante.
A chave AllowOnlineID é a representação em registry dessa Group Policy. Quando habilitada (= 1), o sistema aceita autenticações PKU2U — ativando o code path do NEGOEX que contém o overflow.
| Valor | Estado | Risco |
|---|---|---|
1 | PKU2U habilitado | ALTO — vetor de NEGOEX ativado |
0 | PKU2U desabilitado | BAIXO — vetor mitigado (patch ainda necessário) |
| Não existe | Padrão do sistema | Depende da GPO — verificar via gpresult /r |
-ErrorAction SilentlyContinue: a chave pode não existir em todos os sistemas — o script trata graciosamente a ausência sem gerar erro.
$ports = @(135, 445, 5985, 3389, 80, 443, 25)
Atacantes podem explorar a falha remotamente sem autenticação enviando pacotes maliciosos para serviços vulneráveis como SMB (porta 445/TCP), RDP (porta 3389/TCP), HTTP/S (portas 80, 443/TCP) e SMTP (porta 25/TCP) que utilizam autenticação SPNEGO.
| Porta | Protocolo | SPNEGO usado para |
|---|---|---|
135 | RPC Endpoint Mapper | Negociação de autenticação RPC |
445 | SMB | Autenticação de file shares, named pipes |
5985 | WinRM (HTTP) | PowerShell remoting, management |
3389 | RDP | Remote Desktop authentication |
80 | HTTP | IIS Windows Authentication (Negotiate) |
443 | HTTPS | IIS Windows Authentication via TLS |
25 | SMTP | Exchange Extended Protection |
Get-NetTCPConnection -LocalPort $port verifica se a porta está em LISTEN no sistema local — cada porta aberta representa um vetor de entrega independente para o exploit.
$ cat ./mitre_mapping.yml# Perspectiva do ATACANTE (o que o script detecta/previne)
tactic: Initial Access
- T1190 # Exploit Public-Facing Application
# RCE via SPNEGO heap overflow sem autenticação
# Vetor: qualquer porta com Negotiate auth (445, 5985, 3389...)
tactic: Execution
- T1203 # Exploitation for Client Execution
# Heap overflow em ntoskrnl!SpnegoHandleExtended
# Controle de RIP/EIP via kernel heap corruption
tactic: Lateral Movement
- T1210 # Exploitation of Remote Services
# Wormable: explora outros hosts via SMB/RPC sem credenciais
- T1550.002 # Pass-the-Hash
# Pós-RCE: acesso SYSTEM permite extração de hashes LSASS
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# Buffer overflow em contexto do kernel → ring 0 imediato
# Perspectiva do DEFENSOR (o que o script assessment executa)
tactic: Discovery (Blue Team)
- T1082 # System Information Discovery
# Coleta versão do OS e ntoskrnl.exe para avaliação de patch
- T1012 # Query Registry
# Verifica HKLM:\...\pku2u\AllowOnlineID
- T1049 # System Network Connections Discovery
# Get-NetTCPConnection para mapear portas SPNEGO expostas
$ cat ./detection_opportunities.md# Anomalia de autenticação NEGOEX — pacotes SPNEGO oversized
# Fonte: Windows Security Event Log / ETW
EventID: 4625 (Logon Failure) com SubStatus 0xC000006D
+ Origem: hosts externos
+ Frequência: alta (scan/exploit tentatives)
+ TargetUserName: ANONYMOUS LOGON OU vazio
# Alternativa: Sysmon Event 3 (Network Connection)
EventID: 3
Condição:
DestinationPort: 445 OU 5985 OU 135
Initiated: false (conexão inbound)
Image: System OU lsass.exe
# Crash do kernel pós-exploit malsucedido
# Fonte: Windows Event Log → System
EventID: 1001 (BugCheck)
BugCheckCode: 0x00000050 (PAGE_FAULT_IN_NONPAGED_AREA)
OU
BugCheckCode: 0x0000007E (SYSTEM_THREAD_EXCEPTION_NOT_HANDLED)
Context: Crash em ntoskrnl.exe → possível exploit attempt
# Snort/Suricata — SPNEGO token oversized (conceitual)
alert tcp any any -> $HOME_NET [445,5985,3389] (
msg:"CVE-2025-47981 SPNEGO NEGOEX oversized token";
content:"|60|"; # SPNEGO OID marker
content:"|a0|"; # MechTypeList marker
dsize:>4096; # tokens legítimos raramente excedem 4KB
threshold:type both, track by_src, count 3, seconds 10;
sid:2025479810;
)
$ cat ./remediation.mdPRIORIDADE: CRÍTICA — Patch imediato (CVSS 9.8, wormable)
1. PATCH (ação principal):
Windows Update → KB5062560 (Julho 2025 Patch Tuesday)
WSUS: aprovar KB5062560 para todos os sistemas Windows 10 1607+
REINICIAR após o patch — ntoskrnl.exe só é substituído após reboot
2. VERIFICAÇÃO PÓS-PATCH:
Executar este script novamente
Resultado esperado:
ntoskrnl.exe Installed Version: 10.0.14393.8246 (ou maior)
Vulnerability Result: Seguro - Patch aplicado
3. MITIGAÇÃO TEMPORÁRIA (se patch imediato for inviável):
Desabilitar PKU2U via Group Policy:
Computer Configuration → Windows Settings → Security Settings →
Local Policies → Security Options →
"Network security: Allow PKU2U authentication requests..." → DISABLED
OU via registry:
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\pku2u"
-Name AllowOnlineID -Value 0
4. BLOQUEIO DE REDE (defense-in-depth):
Firewall: restringir inbound 135, 445, 5985 a hosts autorizados
Segmentar DCs e servidores críticos em VLANs com ACLs rígidas
5. PRIORIDADE ESPECIAL — Domain Controllers:
DCs expõem todas as portas listadas (RPC, SMB, LDAP)
Wormable + DC comprometido = comprometimento completo do domínio AD
Patch DCs na primeira janela disponível
$ cat ./usage.sh# Executar o script de assessment (não requer privilégios de admin para leitura básica,
# mas alguns checks de registry podem precisar de elevação)
powershell.exe -ExecutionPolicy Bypass -File cve_2025_47981_check.ps1
# Output esperado em sistema VULNERÁVEL:
Name Value
---- -----
ntoskrnl.exe Installed Version 10.0.14393.7906
ntoskrnl.exe Required Version 10.0.14393.8246
PKU2U AllowOnlineID 1
Portas SPNEGO abertas {135, 445, 5985, 3389}
Vulnerability Result Vulnerável - Patch ausente (KB5062560)
Windows Version 10.0.14393.7906
# Output esperado em sistema PATCHADO:
Vulnerability Result Seguro - Patch aplicado
PKU2U AllowOnlineID 0
$ cat ./affected_versions.txtAFETADOS (33+ configurações):
Windows 10: 1607, 1809, 21H2, 22H2
Windows 11: 22H2, 23H2, 24H2
Windows Server: 2008 R2, 2012, 2012 R2, 2016, 2019, 2022, 2025
Arquiteturas: x64, x86, ARM64
Server Core: Sim (todas as versões acima)
FATOR DE RISCO ELEVADO:
PKU2U GPO habilitada (padrão em Win10 1607+)
Portas 135/445/5985 acessíveis de redes externas ou não confiáveis
PATCH:
KB5062560 → July 2025 Patch Tuesday
ntoskrnl.exe mínimo → 10.0.14393.8246 (Windows Server 2016)
Verificar builds específicos por versão em: msrc.microsoft.com
$ cat ./lessons_learned.txt[+] Comparar [version] em vez de string evita falsos negativos em comparações de build
[+] ntoskrnl.exe é fonte primária de verdade para estado de patch — mais confiável que Get-HotFix
[+] PKU2U AllowOnlineID é o amplificador do risco — sistemas sem ele têm superfície reduzida
[+] Get-NetTCPConnection mapeia rapidamente a superfície de ataque exposta localmente
[+] Format-Table -AutoSize gera output pronto para copiar em relatório de pentest
[-] Script verifica apenas Windows Server 2016 (14393) — estender para outros builds é necessário
[-] Não verifica estado da GPO via gpresult — registry pode divergir da política efetiva
[-] Não testa conectividade remota — apenas verifica se as portas estão abertas localmente
[-] Sem output em JSON/CSV — difícil integrar em pipelines de compliance automatizados
[→] Melhorias: tabela de versões por OS, output em JSON, verificação remota via Invoke-Command,
integração com Qualys/Tenable para correlação de vulnerabilidade
CVE Assessment · CVSS 9.8 · Wormable · July 2025 Patch Tuesday · Detection only · No exploit