
Detector comportamental de estado de patch para Citrix NetScaler CVE-2026-8452. Envia solicitações SAML elaboradas para determinar se a verificação de tamanho do PrefixList está presente, sem explorar ou corromper memória.
Uma verificação segura e não destrutiva do estado do patch para CVE-2026-8452, o heap overflow de pré-autenticação
no canonicalizador de assinatura SAML do Citrix NetScaler ADC / NetScaler Gateway
(CTX696604,
CVSS 8.8). Um PrefixList superdimensionado de canonicalização exclusiva estoura um buffer de tamanho fixo durante
a canonicalização, que o NetScaler executa antes de validar a assinatura que o transporta — portanto, todo o
caminho é acessível sem credenciais, sem sessão e sem assinatura válida. Relatado por Michael
Tucker da equipe XOR do JPMorgan Chase; análise de causa raiz e de exploração creditada a
watchTowr Labs.
Este script não explora a vulnerabilidade e não corrompe a memória. Ele responde a uma pergunta por alvo: a correção está presente neste appliance? — determinado comportamentalmente, observando o patch em vez de adivinhar a versão.
Sim. Ele foi projetado para uso em produção e em avaliações:
PrefixList de 512 bytes e rejeitam 513 ou mais. Esse limite foi localizado byte a byte,
é idêntico nos dois ramos suportados e não muda com a configuração do appliance nem
com a forma da mensagem SAML ao redor — confirmado ao testar ambas as rotas, que envolvem o
valor em quantidades substancialmente diferentes de XML, e ao verificar que elas mudam de comportamento no mesmo
byte. 575 supera o limite em 63 bytes, portanto o veredito não depende de como um alvo acontece de
estar configurado.PrefixList. Inflar outros campos além dele — URLs de assertion consumer service,
nomes de issuer, identificadores de algoritmo, valores de digest e assinatura — não muda nada em uma versão corrigida, portanto
aplicar a correção não deve fazer uma configuração SAML funcional começar a falhar.Se você modificar a sonda, não altere
PROBE_PREFIXESe não varra comprimentos. 575 bytes é essencial. Outros comprimentos dePrefixListpodem desestabilizar um appliance, em pelo menos um caso em uma versão que contém esta correção; portanto, uma varredura de comprimentos não é uma forma segura de explorar este bug, e mais curto não é mais seguro.
Versões corrigidas rejeitam um PrefixList superdimensionado de forma limpa, com uma mensagem distintiva. Versões não corrigidas
passam pelo parser e retornam um erro interno genérico. Uma solicitação idêntica, duas respostas
diferentes:
PrefixList de 575 bytes | Resposta |
|---|---|
| Não corrigido | 500 Internal Server Error 43549 |
| Corrigido | 200 Malformed Assertion sent to Netscaler |
Duas rotas são testadas, IdP primeiro, parando assim que uma der uma resposta. Qualquer uma é suficiente sozinha, e juntas elas cobrem os dois papéis SAML:
| Rota | Solicitação | Exige |
|---|---|---|
| 1 (primeira) | POST /saml/login — AuthnRequest assinado, PrefixList em ds:SignedInfo | uma política de IdP SAML vinculada ao vserver alvo |
| 2 (fallback) | POST /cgi/samlauth — SAMLResponse, PrefixList na assinatura da asserção | um serviço de consumidor de asserção de SP SAML no vserver alvo |
A rota IdP vem primeiro porque é a mais robusta das duas. Ela é insensível ao valor de Issuer,
à AssertionConsumerServiceURL e ao skew de relógio — um IssueInstant bem fora da
tolerância de skew do appliance ainda discrimina corretamente, porque a canonicalização precede a verificação
de tempo, assim como a verificação de assinatura.
O
AuthnRequestda rota 1 deve ser assinado. Um não assinado retorna200 Malformed Assertion sent to Netscalerem versões corrigidas e não corrigidas, o que é byte-idêntico ao sinal de corrigido; portanto, uma sonda que omite o bloco de assinatura relata todos os appliances como corrigidos. A assinatura não precisa ser válida, e a desta ferramenta não é; ela só precisa estar presente, porque é o seuSignedInfoque carrega oPrefixListpara o canonicalizador.
Ambos os ramos suportados mudam de comportamento exatamente na versão corrigida, em ambas as rotas:
| Versão | Veredito | |
|---|---|---|
13.1-63.16 | última 13.1 vulnerável | VULNERABLE |
13.1-63.18 | primeira 13.1 corrigida | PATCHED |
14.1-66.59 | 14.1 vulnerável | VULNERABLE |
14.1-72.61 | primeira 14.1 corrigida | PATCHED |
13.1-63.16 e 63.18 são versões consecutivas, portanto a mudança é atribuível ao próprio patch,
em vez de alterações entre versões intermediárias.
Essas são as versões em que esta correção apareceu pela primeira vez, e a sonda detecta exatamente essa transição.
Elas não são mais as versões para as quais atualizar: boletins posteriores as substituíram, então 13.1-63.18 e
14.1-72.61 respondem PATCHED aqui, mas permanecem expostos a problemas mais novos. Veja
Remediação para as versões corrigidas atuais.
Porque é impossível que funcione para esta vulnerabilidade, nem em princípio. 13.1-63.16 e 13.1-63.18, as versões
imediatamente em ambos os lados da correção, servem byte-idênticos tmindex.html, base.css e
resources.js — a correção não toca nenhum ativo web. Hashes de ativos estáticos também colidem entre ramos, portanto,
uma abordagem baseada em hash pode mapear um appliance vulnerável para uma versão corrigida e reportá-lo como limpo,
que é o pior modo de falha que uma ferramenta de detecção pode ter. Portanto, o fingerprinting de versão é deliberadamente
não implementado. O estado do patch vem da sonda, ou do comando show ns version quando você tem
credenciais.
./cve_2026_8452_check.py https://gateway.example.com
./cve_2026_8452_check.py https://gateway.example.com:9443
./cve_2026_8452_check.py -f targets.txt --brief
./cve_2026_8452_check.py -f targets.txt --json > results.json
Aponte a ferramenta para o **servidor virtual Gateway ou AAA**, não para a interface de gerenciamento. A
pré-condição é por servidor virtual, portanto um appliance com vários VIPs precisa que cada um seja testado.
### Opções