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
CVE-2026-19490 — NetScaler ADC/Gateway bypass dell'asserzione SAML non firmata tramite binding HTTP-Redirect (CTX696939) - analisi della causa principale + PoC | Kitploit
Strumenti/GitHubGitHub/tarpeg007/cve-2026-19490
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingAnalisi di BinariAutenticazioneRed Teaming
GitHubtarpeg007/cve-2026-19490

CVE-2026-19490

NetScaler ADC/Gateway bypass dell'asserzione SAML non firmata tramite binding HTTP-Redirect (CTX696939) - analisi della causa principale + PoC

Vedi Repository
19h 3m 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 →
Condividi

CVE-2026-19490 — Bypass dell'autenticazione SAML in NetScaler ADC/Gateway

Falsificazione di sessione non autenticata su Citrix NetScaler ADC / NetScaler Gateway tramite il gestore del binding HTTP-Redirect SAML su GET /cgi/samlauth. CVSS 4.0 9.3, CWE-288. Bollettino CTX696939 (2026-08-19), nessuna soluzione alternativa. Il merito del report originale va a Samarth Vashisht (team di pen-test di JPMorgan Chase); l'analisi della causa principale e il codice in questo repository sono opera mia.

Versioni interessate: 14.1 precedenti alla 14.1-73.32, 13.1 precedenti alla 13.1-63.21. Corrette in queste due build.

causa principale

Due cose vanno male insieme in nsppe, il motore dei pacchetti.

1. il binding di redirect analizza le assertion con il flag strict disattivato.

Tutti i punti di chiamata del parser delle risposte SAML (sub_b40a50) impostano un argomento "strict" prima della chiamata. Il percorso del binding POST (quello che i browser usano realmente per le risposte SAML) lo passa impostato. Il percorso del binding HTTP-Redirect non lo fa:

root@kitploit:~
$ objdump -d -M intel --start-address=0xb7f532 --stop-address=0xb7f558 nsppe-14.1-73.30
  b7f532: 41 b8 00 00 00 00     mov    r8d,0x0          <-- strict OFF
  b7f538: 48 8d 8d d8 fe ff ff  lea    rcx,[rbp-0x128]
  b7f53f: 48 8b 95 b8 fe ff ff  mov    rdx,[rbp-0x148]
  b7f546: 8b b5 cc fe ff ff     mov    esi,[rbp-0x134]
  b7f54c: 48 8b 3d f5 9f 6f 02  mov    rdi,[rip+0x26f9ff5]
  b7f553: e8 f8 14 fc ff        call   b40a50            <-- il parser

Questo è il percorso alternativo nel senso della CWE-288. Stessa superficie di richiesta, invocazione del parser più debole, raggiungibile da chiunque possa inviare una GET con un parametro di query SAMLResponse.

2. il gate per le assertion non firmate tratta la configurazione predefinita come ALLOW.

All'interno del gestore di redirect, quando la richiesta non trasporta SigAlg/Signature, la parola di configurazione per rejectUnsignedAssertion viene confrontata e diramata così:

root@kitploit:~
$ objdump -d -M intel --start-address=0xb7ee3b --stop-address=0xb7ee41 nsppe-14.1-73.30
  b7ee3b: 83 78 08 02           cmp    DWORD PTR [rax+0x8],0x2
  b7ee3f: 74 5d                 je     b7ee9e            <-- salta al percorso ACCEPT

I valori della parola sono: 2 = rejectUnsignedAssertion ON (il predefinito), 3 = STRICT. Il je invia 2 ad accept. Solo STRICT raggiunge la riga di log di deny:

root@kitploit:~
$ strings -t x nsppe-14.1-73.30 | grep 'denying as per action'
  2020998 SAMLIDP: Redirect Binding: Unsigned Assertion seen, denying as per action %s

Quindi su un sistema con configurazione predefinita, un'assertion non firmata consegnata al binding di redirect viene analizzata (strict off), accettata oltre il gate per le non firmate (ON interpretato erroneamente come allow), e poi esegue i normali passaggi post-analisi: controlli di issuer/audience/subject rispetto alla configurazione dell'azione SAML, quindi costruzione della sessione da campi forniti dall'attaccante. Nessun digest, nessuna verifica RSA, in nessun punto di quella rotta. Il binding POST non è influenzato allo stesso modo — passa strict al parser e rifiuta correttamente l'input non firmato.

Prerequisiti secondo il bollettino, confermati contro il binario: le build dalla 14.1-43.56 / 13.1-61.28 in poi richiedono un'azione SAML associata a un vserver Gateway o AAA (la normale configurazione SAML SSO, quindi la maggior parte delle implementazioni SAML è idonea). Le build precedenti registrano la rotta con il solo vserver.

forma dell'exploit

Una GET. Costruisci una risposta SAML senza alcun <ds:Signature>, applica DEFLATE + base64 e invia:

root@kitploit:~
GET /cgi/samlauth?SAMLResponse=<b64(raw-deflate(xml))>&RelayState=<ctx> HTTP/1.1
Host: <gateway>

I valori che devono corrispondere alla configurazione dell'azione SAML del target: Issuer dell'assertion = l'ID entità IdP, Audience = l'ID entità SP, Recipient/Destination = l'URL ACS, e su configurazioni transazionali un InResponseTo da una AuthnRequest attiva. --mint esamina il redirect di login pre-autenticazione del gateway stesso per catturarli (la SAMLRequest nell'header Location li trasporta tutti). Un 302 verso /vpn/ più un cookie NSC_AAAC / NSC_TASS reale (non i marcatori di eliminazione xyz) è una sessione falsificata come qualsiasi NameID tu inserisca.

utilizzo

root@kitploit:~
pip install requests

# l'endpoint è presente e il binding GET elabora SAMLResponse?
python3 poc.py https://vpn.target.com --check-only

# sonda di configurazione non intrusiva: assertion non firmata con un issuer volutamente SBAGLIATO.
#   'Malformed Assertion' (0xe0005)  -> STRICT, non vulnerabile a questo vettore
#   errore issuer/policy (0xe0012)   -> configurazione predefinita, vulnerabile; nessuna sessione creata
python3 poc.py https://vpn.target.com --safe-oracle

# catena completa (solo target autorizzati): crea la catena SP, falsifica, verifica una volta
python3 poc.py https://vpn.target.com --mint --name-id [email protected]

--safe-oracle esiste perché le due configurazioni restituiscono pagine di errore diverse prima che accada qualsiasi cosa simile a una sessione, il che è anche il modo in cui i difensori possono auto-verificarsi senza toccare un IdP reale. Eseguilo contro la tua attrezzatura.

demo

demo/demo.gif (anche demo.mp4, e demo/demo.cast se vuoi riprodurlo con asciinema play): build interessata dall'immagine docker, la configurazione predefinita word-2, i due rami binari disassemblati dal nsppe fornito, e il controllo dell'endpoint del PoC. L'ultimo miglio, l'emissione della sessione, richiede un VPX con licenza — CPX Express rifiuta le sessioni AAA a livello di licenza — che è ciò che lab/record-demo.sh cattura quando ne hai uno.

laboratorio

lab/setup-cpx.sh avvia l'esatta build interessata in docker:

root@kitploit:~
docker run -dt --privileged --name cpx19490 -e EULA=YES \
    quay.io/netscaler/netscaler-cpx:14.1-73.30
bash lab/setup-cpx.sh

e configura un'azione SAML con rejectUnsignedAssertion ON, una policy e un vserver Gateway. Due avvertenze imparate a proprie spese:

  • CPX Express non include una licenza utente SSLVPN/AAA. Il vserver serve /cgi/samlauth ma ogni richiesta finisce su 480 Login exceeds maximum allowed users. Abbastanza buono per riprodurre configurazione + endpoint + stato binario, non il cookie di sessione finale.
  • Per l'esecuzione completa dell'emissione di sessione ti serve un VPX con la licenza gratuita Developer Edition (My Citrix → download → NetScaler VPX, poi CTX587663 per il flusso di licenza). Stessa CLI dello script di setup, poi lab/record-demo.sh registra l'intera sequenza asciinema: versione, configurazione, safe-oracle, sessione falsificata, controllo negativo STRICT.

Gli offset del binario fornito sopra provengono direttamente da quell'immagine:

root@kitploit:~
docker cp cpx19490:/var/netscaler/bins/nsppe ./nsppe-14.1-73.30
objdump -d -M intel --start-address=0xb7ee3b --stop-address=0xb7ee41 ./nsppe-14.1-73.30

rilevamento / mitigazione

  • Aggiorna a 14.1-73.32+ / 13.1-63.21+. Non esiste una soluzione alternativa supportata.
  • set samlAction <name> -samlRejectUnsignedAssertion STRICT blocca il vettore di redirect sul percorso vulnerabile (fa diventare word==3). Tieni presente che STRICT cambia anche ciò che il sistema si aspetta dal tuo IdP (requisiti di firma di Response + Assertion), che è presumibilmente il motivo per cui Citrix fornisce ON come predefinito e perché "basta impostare STRICT" non è una soluzione alternativa pulita per tutti.
  • Rilevamento: richieste a /cgi/samlauth che trasportano SAMLResponse su GET (le risposte del binding di redirect sono rare in natura — i browser fanno POST), payload non firmati e il differenziale delle pagine di errore sopra descritto.

legale

Solo per test di sicurezza autorizzati: il tuo laboratorio, o target esplicitamente in scope per un programma su cui sei autorizzato. L'autore non è affiliato a Citrix né al team di segnalazione originale.

cronologia

  • 2026-08-19 — bollettino Citrix CTX696939, correzioni distribuite
  • 2026-09 — questo writeup sulla causa principale e il PoC

Licenza MIT, vedi LICENSE.

Scarica lo strumento