Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/bishopfox/cve-2026-19490-check
Strumenti DifensiviScanner di VulnerabilitàScanner di Vulnerabilità WebAnalisi delle VulnerabilitàRaccolta InformazioniSicurezza WebSicurezza di RetePenetration TestingAutenticazione
GitHubbishopfox/cve-2026-19490-check

CVE-2026-19490-check

Rileva in modo sicuro il bypass di autenticazione SAML di Citrix NetScaler CVE-2026-19490

118h 16m faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Vedi Repository
Condividi

Citrix NetScaler SAML nFactor Context Authentication Bypass — Script di Rilevamento della Vulnerabilità

Un controllo di vulnerabilità sicuro e non autenticato per CVE-2026-19490, il bypass di autenticazione pre-autenticazione nel percorso del service provider SAML di Citrix NetScaler ADC / NetScaler Gateway (CTX696939, pubblicato il 2026-08-19). CWE-288, CVSS v4.0 9.3 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L). Segnalato da Samarth Vashisht del team di penetration testing di JPMorgan Chase.

L'appliance decodifica in base64 il parametro RelayState di una risposta SAML e, quando il testo in chiaro inizia con ctx=, passa il resto al deserializzatore del contesto nFactor. Su una build non patchata un fallimento di deserializzazione propaga la lunghezza del RelayState decodificato come codice di disposizione interno della richiesta invece di un errore, così un attaccante non autenticato sceglie quale ramo interno l'appliance prende successivamente semplicemente scegliendo quanto è lungo il RelayState. Alcuni rami generano una vera sessione Gateway; altri mandano in crash il packet engine e riavviano l'appliance. Questo script non fa né l'una né l'altra cosa — invia l'unica lunghezza validata per non creare alcuna sessione e non toccare il packet engine, e risponde a una sola domanda per target: Un risultato diverso da .

questa appliance è vulnerabile?
VULNERABLE
non è di per sé un certificato di buona salute

Utilizzo

root@kitploit:~
# single target
./cve_2026_19490_check.py https://gateway.example.com

# a specific Gateway or AAA virtual server
./cve_2026_19490_check.py https://gateway.example.com:9443

# several targets; the scheme defaults to https://
./cve_2026_19490_check.py gw-a.example.com gw-b.example.com:9443

# scan a list, one target per line ('#' comments allowed), compact output
./cve_2026_19490_check.py -f targets.txt --brief

# machine-readable output for pipelines
./cve_2026_19490_check.py -f targets.txt --json > results.json

Python 3.8+, solo libreria standard — nessun pacchetto di terze parti.

Punta lo strumento al Gateway o al virtual server AAA, non all'interfaccia di gestione. L'esposizione è per virtual server, quindi un'appliance con diversi VIP richiede che ciascuno venga testato. La sonda porta con sé un rigido involucro di sicurezza — un'unica lunghezza RelayState validata, mai scansionata a tappeto — che È Sicuro Eseguirlo? illustra.

Opzioni

FlagDescrizione
TARGETUno o più target [https://]HOST[:PORT]; lo schema predefinito è https://
-f, --targets-file FILELegge i target da un file (uno per riga; commenti #)
--timeout SECSTimeout per richiesta (predefinito: 15)
--workers NTarget concorrenti (predefinito: 16); l'output resta nell'ordine di input
-b, --briefUna singola riga allineata per target — ideale per scansionare molti host
--jsonEmette JSON strutturato, includendo ogni richiesta inviata per target
--no-colorDisabilita l'output colorato (rispetta anche NO_COLOR e non-TTY)

Esempi

Un'appliance vulnerabile (l'output predefinito su due righe). Il marcatore [!] e VULNERABLE vengono resi in rosso su un TTY:

root@kitploit:~
$ ./cve_2026_19490_check.py https://gateway.example.com:9443
[!] https://gateway.example.com:9443: VULNERABLE  [internal-error-43524]
      HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error, so the CTX696939 fix is absent

Un'appliance patchata:

root@kitploit:~
$ ./cve_2026_19490_check.py https://vpn.example.com
[+] https://vpn.example.com: PATCHED  [fixed-error-returned]
      HTTP 200 "Malformed Assertion": the fixed error was returned on the path this probe reached, so the CTX696939 fix is present (>= 13.1-63.21 / 14.1-73.32)

La guardia anti-falsi positivi che scatta. La sonda e il controllo della stessa lunghezza hanno entrambi restituito il segnale non patchato, quindi la risposta non dipende da ciò che è stato inviato e la risposta dall'aspetto decisivo viene ritirata:

root@kitploit:~
$ ./cve_2026_19490_check.py https://sp-strict.example.com
[?] https://sp-strict.example.com: INCONCLUSIVE  [flat-response]
      the probe and the same-length control both answered HTTP 500 / 43524, so the reply does not depend on what was sent and the fix was never exercised; unknown, not patched

Scansione di un parco macchine (--brief). Le due righe gateway.example.com sono i virtual server SP e solo-IdP sulla stessa appliance — entrambi rispondono, cosa che un controllo di precondizione di configurazione non riuscirebbe a fare:

root@kitploit:~
$ ./cve_2026_19490_check.py -f targets.txt --brief; echo "exit: $?"
VULNERABLE    https://gateway.example.com:9443         internal-error-43524
VULNERABLE    https://gateway.example.com:9444         internal-error-43524
PATCHED       https://vpn.example.com                  fixed-error-returned
INCONCLUSIVE  https://sp-strict.example.com            flat-response
UNAFFECTED    https://lb.example.com                   no-saml-endpoint
ERROR         https://www.example.com                  not-identified
exit: 1

Output leggibile dalla macchina (--json). Ogni richiesta è inclusa, così un risultato può essere ri-derivato dalle prove anziché essere preso per buono. Il controllo è registrato per la sua relazione con la sonda piuttosto che come un verdetto a sé stante, perché un controllo che si legge come una build patchata è il risultato atteso su ogni build:

root@kitploit:~
$ ./cve_2026_19490_check.py https://gateway.example.com:9443 --json
[
  {
    "target": "https://gateway.example.com:9443",
    "verdict": "VULNERABLE",
    "reason": "internal-error-43524",
    "detail": "HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error, so the CTX696939 fix is absent",
    "netscaler_indicators": [
      "CSP contains citrixng://",
      "CSP contains com.citrix.nsgclient://",
      "CSP contains nsgcepa://",
      "CSP report-uri /nscsp_violation/report_uri",
      "/vpn/js/rdx/ present (HTTP 404)"
    ],
    "attempts": [
      {
        "kind": "probe",
        "path": "/cgi/samlauth",
        "status": 500,
        "state": "unpatched",
        "detail": "HTTP 500 / 43524: the decoded RelayState length was propagated as the internal error"
      },
      {
        "kind": "control",
        "path": "/cgi/samlauth",
        "status": 200,
        "state": "differs-from-probe",
        "detail": "same-length control: HTTP 200 \"Malformed Assertion\": the fixed error was returned"
      }
    ]
  }
]

È Sicuro Eseguirlo?

Sì. È progettato per l'uso in produzione e in fase di assessment:

  • Una lunghezza fissa, mai una scansione a tappeto. Il RelayState della sonda si decodifica in esattamente 20 byte e lo strumento non invia nessun'altra lunghezza con nessun flag. Su un'appliance non patchata la lunghezza decodificata è il selettore di ramo, e i rami includono quelli che creano una sessione e quelli che mandano in SIGSEGV il packet engine — riavviando l'intero NetScaler e facendo cadere il traffico per circa 45 secondi. Venti byte atterrano su un ramo di errore interno pulito che non crea alcuna sessione, e il costruttore del payload rifiuta di costruire qualsiasi altra lunghezza, così una modifica altrove non può silenziosamente ampliare la sonda.
  • Validato tramite misurazione. La sonda da 20 byte è stata eseguita 10 volte consecutive contro una 13.1-63.18 non patchata con zero core generati e nessun riavvio del packet engine. Il controllo stesso è stato eseguito da allora contro entrambi i rami di manutenzione, su entrambi i lati della correzione, e contro virtual server service-provider e solo-IdP allo stesso modo, senza alcun riavvio del packet engine su nessuno di essi.
  • Nessuna autenticazione, nessun materiale di credenziali, nessun cambiamento di stato. Nessuna assertion, firma, timestamp, sessione o certificato client viene presentato in alcun punto di questo controllo. Il parametro SAMLResponse deve essere presente perché il ramo RelayState venga raggiunto, ma il suo contenuto è irrilevante, quindi sono quattro byte di spazzatura. Il ramo non emette alcun cookie e non scrive alcuna configurazione.
  • Guardia anti-falsi positivi. VULNERABLE non viene mai segnalato su una singola risposta — vedi il controllo.

Se modifichi la sonda, non cambiare la lunghezza del RelayState decodificato e non scansionare le lunghezze. Venti byte sono portanti, e più corto non è più sicuro. Altre lunghezze sono non testate nel migliore dei casi e un'interruzione dell'appliance nel peggiore.

Impronta di richieste e log

Tre richieste HTTP per target, e una quarta solo quando l'appliance restituisce il segnale non patchato:

#RichiestaScopo
1GET /logon/LogonPoint/tmindex.htmlIdentificazione NetScaler (token Content-Security-Policy)
2GET /vpn/js/rdx/core/rdx.jsIdentificazione NetScaler
3POST /cgi/samlauthla sonda
4POST /cgi/samlauthil controllo, inviato solo dopo un segnale non patchato

I redirect non vengono seguiti e nessun cookie viene mai rimandato indietro — NetScaler serve un NSC_DLGE scaduto che un client che lo riproduce porterebbe nella richiesta 4, trasformando il POST in una pagina di logon.

nsppe registra il POST SAML in /var/log/ns.log a livello informativo, senza necessità di alcun interruttore di debug, come un fallimento di deserializzazione del contesto nFactor che include la riga nFactor: ctx deserialize aaa_info, base64 decode failed. Non ci sono righe di creazione sessione o login a questa lunghezza, ed è ciò che distingue una scansione da un tentativo di bypass.

Come Funziona

La correzione è una singola istruzione. Su una deserializzazione del contesto fallita la build vulnerabile porta avanti la lunghezza del RelayState decodificato come stato della richiesta; la build corretta porta la costante di errore 0xe0005, resa come Malformed Assertion. Quindi un singolo POST le separa:

Risposta alla sondaBuildVerdetto
500 Internal Server Error 43524non patchataVULNERABLE
200 Malformed Assertion sent to NetscalerpatchataPATCHED

La build patchata risponde Malformed Assertion a ogni lunghezza, ed è ciò che rende la risposta non patchata un oracolo piuttosto che una coincidenza.

Il controllo è ciò che rende significativo un 500

VULNERABLE si basa su una singola risposta distintiva, quindi lo strumento verifica che la risposta dipenda effettivamente da ciò che è stato inviato. Dopo il segnale non patchato ripete la richiesta con un RelayState di controllo della stessa lunghezza decodificata di 20 byte, che differisce solo nei 16 byte dopo ctx=. Quel contenuto viene rifiutato da una guardia a monte del deserializzatore, quindi ogni build testata — patchata e non patchata — risponde 200 Malformed Assertion. Il verdetto regge solo se le due risposte differiscono. Se coincidono, qualcosa sta restituendo 500/43524 indipendentemente dall'input, e il risultato è INCONCLUSIVE etichettato flat-response anziché un falso VULNERABLE. Mantenere il controllo alla stessa lunghezza decodificata lo tiene dentro l'involucro di sicurezza validato e isola il contenuto come unica variabile.

La guardia è unidirezionale. Non può validare un verdetto PATCHED, perché un'appliance genuinamente patchata risponde in modo identico a sonda e controllo — è ciò che significa essere patchati qui. Vedi Limitazioni.

Risponde anche sui virtual server solo-IdP

La deserializzazione del RelayState avviene prima del matching della policy SAML, quindi un virtual server che porta solo una samlIdPPolicy risponde alla sonda, non solo uno con un samlAction service-provider associato. Questa è una copertura più ampia di quella che un controllo di precondizione di configurazione può offrire.

Un non-match non è mai una dichiarazione di sicurezza

La risposta vulnerabile è l'unica auto-corroborante: porta un marcatore specifico, e il controllo prova che la risposta dipende da ciò che è stato inviato. Anche PATCHED è una prova positiva — l'errore corretto dell'appliance stessa sul percorso che la sonda ha raggiunto — ma è limitato a questa CVE e a quel percorso. INCONCLUSIVE ed ERROR non sono affatto prove: la sonda non ha mai raggiunto il deserializzatore, quindi lo stato della patch è sconosciuto, ed è per questo che INCONCLUSIVE è un verdetto separato anziché essere accorpato a PATCHED. Riportare il silenzio come un superamento lo sbaglia nella direzione pericolosa. Dove serve certezza, conferma con show ns version rispetto alle build in Remediation.

Verdetti

Ogni verdetto porta un breve tag reason. --brief lo stampa come terza colonna e --json lo porta come reason.

VerdettoTag reasonSignificato
VULNERABLEinternal-error-43524L'appliance ha propagato la lunghezza del RelayState decodificato come suo errore interno, e un controllo della stessa lunghezza ha provato che la risposta dipende da ciò che è stato inviato. La correzione CTX696939 è assente — applica la patch.
PATCHEDfixed-error-returnedL'appliance ha restituito l'errore corretto sul percorso che la sonda ha raggiunto. Limitato a questa CVE, e vedi Limitazioni sui dispositivi interposti.
UNAFFECTEDno-saml-endpoint/cgi/samlauth ha restituito 404, quindi l'assertion consumer SAML non è servito qui. Per-vserver, non per-appliance, e vedi l'avvertenza sulle build più vecchie in Limitazioni.
INCONCLUSIVEflat-responseSonda e controllo della stessa lunghezza hanno risposto in modo identico, quindi la risposta non dipende da ciò che è stato inviato. La guardia anti-falsi positivi che scatta.
INCONCLUSIVEgeneric-internal-errorL'endpoint ha restituito 43549, il suo errore interno generico, che sia le build patchate che quelle non patchate restituiscono. Non è il discriminatore — e nota che è il marcatore non patchato per la CVE-2026-8452 non correlata, quindi sembra un riscontro e non lo è.
INCONCLUSIVEunrecognized-replyL'endpoint ha risposto con qualcosa al di fuori dell'insieme riconosciuto.
INCONCLUSIVEno-probe-responseL'host ha risposto all'identificazione ma non alla sonda — un timeout, un reset, o un middlebox che scarta il POST. Riprova.
ERRORnot-identifiedNon identificato come NetScaler, o irraggiungibile.

Tutte e quattro le ragioni INCONCLUSIVE significano la stessa cosa per il processo decisionale — sconosciuto, non patchato. Il tag nomina quale condizione correggere prima di rieseguire.

Codici di uscita

CodiceSignificato
0Nessun target era VULNERABLE
1Almeno un target è VULNERABLE
2Errore di utilizzo (argomenti errati / file dei target non leggibile)

L'uscita 0 non è un certificato di buona salute. PATCHED, UNAFFECTED e tutte e quattro le ragioni INCONCLUSIVE vi confluiscono, e solo una di queste è un risultato positivo. Un wrapper che deve distinguere "patchato" da "non classificabile" deve leggere il verdetto — prima colonna di --brief, o il campo verdict di --json — non il codice di uscita.

Limitazioni

  • Un WAF o un load balancer può falsare un verdetto PATCHED. Malformed Assertion è ciò che l'appliance restituisce ogni volta che la sonda non riesce a raggiungere il deserializzatore del contesto, e essere patchata è solo una delle ragioni per cui ciò accade. Un dispositivo interposto che rimuove, altera o cortocircuita il parametro RelayState produce quindi PATCHED su un'appliance vulnerabile, e nessuna richiesta aggiuntiva che lo strumento potrebbe inviare separerebbe le due. Dove qualcosa può trovarsi davanti all'appliance, conferma con show ns version.
  • UNAFFECTED è limitato alle build attuali. Su 14.1-43.55 / 13.1-61.27 e precedenti l' advisory afferma che l'esposizione non richiede affatto una SAML action — qualsiasi virtual server Gateway o AAA è interessato — quindi un 404 su una tale build non mette l'appliance fuori ambito. Quel ramo è tratto dall'advisory anziché misurato.
  • Questo controlla una CVE, non il livello di patch dell'appliance. PATCHED non dice nulla su qualsiasi altra vulnerabilità NetScaler, inclusa CVE-2026-19489 nello stesso bollettino.
  • Non è un controllo di sfruttamento, e non è un controllo di compromissione. VULNERABLE stabilisce che la correzione è assente sul percorso che la sonda ha raggiunto. Non misura fin dove un attaccante potrebbe spingere il bypass sulla tua configurazione, e non ti dirà se qualcuno lo ha già fatto — cerca quello in /var/log/ns.log separatamente.
  • Non può dirti se i rami di denial-of-service sono raggiungibili. Lo strumento invia una lunghezza validata e non esplora mai le altre, per design.
  • Raggiungibilità. Un risultato riflette ciò che l'appliance espone alla posizione di rete da cui lo esegui.

Remediation

Aggiorna a 13.1-63.21 o successiva, o 14.1-73.32 o successiva (FIPS e NDcPP: 13.1-37.277 per 13.1-FIPS e 13.1-NDcPP, 14.1-73.32 FIPS per 14.1-FIPS), secondo CTX696939. Le appliance su 12.1 o 13.0 non hanno correzione e non ne riceveranno una — quei rami sono a fine vita e dovrebbero essere migrati a un ramo supportato.

Tre ulteriori note:

  • Applica la patch a entrambi i nodi di una coppia HA. Un secondario non patchato è un'appliance completamente esposta nel momento in cui assume il controllo.
  • Se non puoi applicare la patch oggi, controlla l'unico interruttore globale che limita l'impatto. La sessione che questo bug genera su un virtual server Gateway salta la valutazione della session-policy, quindi non assume il defaultAuthorizationAction di alcuna vpn sessionAction associata al vserver — ricade sul set vpn parameter -defaultAuthorizationAction globale. Il valore predefinito fornito è DENY; ALLOW è comune sul campo perché è ciò a cui gli amministratori ricorrono invece di scrivere policy di autorizzazione per utente, e ALLOW è ciò che permette alla sessione non autenticata di raggiungere le risorse interne. È globale, non per-vserver. Questo limita l'impatto; non è una correzione.
  • Delimita il tuo inventario per configurazione SAML, non per tipo di virtual server. Controlla la configurazione in esecuzione per add authentication samlAction e add authentication samlIdPProfile insieme a add authentication vserver e add vpn vserver — fatta salva l'avvertenza sulle build più vecchie sopra.

CTX696939 corregge anche CVE-2026-19489, e questa superficie si sovrappone pesantemente a CVE-2026-8452 del bollettino precedente: sulle build da 14.1-43.56 / 13.1-61.28 in poi entrambi i problemi sono vincolati a una SAML action configurata, quindi un singolo audit di configurazione delimita entrambi.

Licenza

Questo codice è distribuito sotto una licenza MIT.

Disclaimer Legale

L'uso di questo strumento per attaccare target senza previo consenso reciproco è illegale. È responsabilità dell'utente finale rispettare tutte le leggi locali, statali e federali applicabili. Gli sviluppatori non si assumono alcuna responsabilità e non sono responsabili per qualsiasi uso improprio o danno causato da questo programma.

Vedi Anche

  • Citrix CTX696939 — Bollettino di sicurezza NetScaler
  • NVD — CVE-2026-19490
  • NVD — CVE-2026-19489
  • NVD — CVE-2026-8452
Scarica lo strumento