
Rilevatore comportamentale dello stato di patch per Citrix NetScaler CVE-2026-8452. Invia richieste SAML appositamente predisposte per determinare se il controllo della dimensione di PrefixList è presente, senza sfruttare o corrompere la memoria.
Un controllo sicuro e non distruttivo dello stato di patch per CVE-2026-8452, l'heap overflow pre-autenticazione nel canonicalizzatore della firma SAML di Citrix NetScaler ADC / NetScaler Gateway (CTX696604, CVSS 8.8). Un PrefixList di canonicalizzazione esclusiva di dimensioni eccessive supera un buffer a dimensione fissa durante la canonicalizzazione, che NetScaler esegue prima di validare la firma che lo trasporta — quindi l'intero percorso è raggiungibile senza credenziali, senza sessione e senza firma valida. Segnalato da Michael Tucker del team XOR di JPMorgan Chase; l'analisi della causa principale e dello sfruttamento è attribuita a watchTowr Labs.
Questo script non sfrutta la vulnerabilità e non corrompe la memoria. Risponde a una sola domanda per ogni target: la correzione è presente su questo appliance? — determinata in base al comportamento, osservando la patch piuttosto che indovinando la build.
Sì. È progettato per l'uso in produzione e durante le valutazioni:
PrefixList di 512 byte e rifiutano 513 o più. Questo limite è stato individuato al byte, è identico su entrambi i rami supportati e non cambia con la configurazione dell'appliance né con la forma del messaggio SAML circostante — confermato sondando entrambe le route, che avvolgono il valore in quantità di XML sostanzialmente diverse, e riscontrando che cambiano comportamento allo stesso byte. 575 supera il limite di 63 byte, quindi il verdetto non dipende da come è configurato un determinato target.PrefixList. Gonfiare altri campi oltre tale limite — URL del servizio di consumo assertion, nomi dell'emittente, identificatori di algoritmo, valori di digest e firma — non cambia nulla su una build corretta, quindi applicare la correzione non dovrebbe far fallire una configurazione SAML funzionante.Se modifichi la sonda, non cambiare
PROBE_PREFIXESe non eseguire scansioni su più lunghezze. 575 byte sono un elemento portante. Altre lunghezze diPrefixListpossono destabilizzare un appliance, in almeno un caso su una build che include questa correzione, quindi una scansione di lunghezze non è un modo sicuro per esplorare questa vulnerabilità e più corto non significa più sicuro.
Le build patchate rifiutano un PrefixList di dimensioni eccessive in modo pulito, con un messaggio distintivo. Le build non patchate superano il parser e restituiscono un errore interno generico. Una richiesta identica, due risposte diverse:
PrefixList da 575 byte | Risposta |
|---|---|
| Non patchata | 500 Internal Server Error 43549 |
| Patchata | 200 Malformed Assertion sent to Netscaler |
Vengono provate due route, prima la IdP, fermandosi appena una fornisce una risposta. Una sola è sufficiente, e insieme coprono entrambi i ruoli SAML:
| Route | Richiesta | Richiede |
|---|---|---|
| 1 (prima) | POST /saml/login — AuthnRequest firmata, PrefixList in ds:SignedInfo | una policy SAML IdP associata al vserver di destinazione |
| 2 (fallback) | POST /cgi/samlauth — SAMLResponse, PrefixList nella firma dell'assertion | un servizio di consumo assertion SAML SP sul vserver di destinazione |
La route IdP viene per prima perché è la più robusta delle due. È insensibile al valore di Issuer, a AssertionConsumerServiceURL e alla deriva dell'orologio — un IssueInstant ben al di fuori della tolleranza di deriva dell'appliance discrimina comunque correttamente, perché la canonicalizzazione precede sia il controllo temporale sia il controllo della firma.
La
AuthnRequestdella route-1 deve essere firmata. Una non firmata restituisce200 Malformed Assertion sent to Netscalersia sulle build patchate che su quelle non patchate, un segnale byte-identico a quello delle build patchate, quindi una sonda che omette il blocco della firma segnala ogni appliance come patchato. La firma non deve essere valida, e quella di questo strumento non lo è; deve solo essere presente, perché è il suoSignedInfoa trasportare ilPrefixListnel canonicalizzatore.
Entrambi i rami supportati cambiano comportamento esattamente in corrispondenza della build di correzione, su entrambe le route:
| Build | Verdetto | |
|---|---|---|
13.1-63.16 | ultima 13.1 vulnerabile | VULNERABLE |
13.1-63.18 | prima 13.1 corretta | PATCHED |
14.1-66.59 | 14.1 vulnerabile | VULNERABLE |
14.1-72.61 | prima 14.1 corretta | PATCHED |
13.1-63.16 e 63.18 sono release consecutive, quindi il cambiamento è attribuibile alla patch stessa piuttosto che a derive tra build intermedie.
Queste sono le build in cui è apparsa per la prima volta questa correzione, e la sonda rileva esattamente quella transizione. Non sono più le build a cui aggiornare: bollettini successivi le hanno superate, quindi sia 13.1-63.18 che 14.1-72.61 rispondono PATCHED qui pur rimanendo esposte a problemi più recenti. Vedi Remediation per le build corrette attuali.
Perché non può funzionare su questa vulnerabilità, nemmeno in linea di principio. 13.1-63.16 e 13.1-63.18, le build immediatamente a cavallo della correzione, servono tmindex.html, base.css e resources.js byte-identici — la correzione non tocca alcuna risorsa web. Anche gli hash delle risorse statiche collidono tra i rami, quindi un approccio basato su hash può risolvere un appliance vulnerabile in una build patchata e segnalarlo come pulito, che è la modalità di errore peggiore per uno strumento di rilevamento. Il fingerprinting della build è quindi deliberatamente non implementato. Lo stato della patch deriva dalla sonda, o da show ns version dove si dispone delle credenziali.
./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