Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-19490-check — Detecte com segurança o bypass de autenticação SAML do Citrix NetScaler CVE-2026-19490 | Kitploit
Ferramentas/GitHubGitHub/bishopfox/cve-2026-19490-check
Ferramentas DefensivasScanners de VulnerabilidadesScanners de Vulnerabilidades WebAnálise de VulnerabilidadesColeta de InformaçõesSegurança WebSegurança de RedeTestes de PenetraçãoAutenticação
GitHubbishopfox/cve-2026-19490-check

CVE-2026-19490-check

Detecte com segurança o bypass de autenticação SAML do Citrix NetScaler CVE-2026-19490

há 11h 55mAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Ver Repositório
Compartilhar

Citrix NetScaler SAML nFactor Context Authentication Bypass — Script de Detecção de Vulnerabilidade

Uma verificação de vulnerabilidade segura e não autenticada para CVE-2026-19490, o bypass de autenticação pré-autenticação no caminho do provedor de serviços SAML do Citrix NetScaler ADC / NetScaler Gateway (CTX696939, publicado em 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). Reportado por Samarth Vashisht da equipe de testes de intrusão do JPMorgan Chase.

O appliance decodifica em base64 o parâmetro RelayState de uma resposta SAML e, quando o texto simples começa com ctx=, entrega o restante ao desserializador de contexto nFactor. Em uma build não corrigida, uma falha de desserialização propaga o comprimento do RelayState decodificado como o código de disposição interno da requisição em vez de um erro, de modo que um atacante não autenticado escolhe qual ramo interno o appliance segue em seguida simplesmente escolhendo o comprimento do RelayState. Alguns ramos geram uma sessão real do Gateway; outros derrubam o packet engine e reiniciam o appliance. Este script não faz nenhum dos dois — ele envia o único comprimento validado para não criar sessão e deixar o packet engine em paz, e responde a uma única pergunta por alvo: Um resultado diferente de .

este appliance é vulnerável?
VULNERABLE
não é por si só um atestado de saúde

Uso

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+, apenas biblioteca padrão — sem pacotes de terceiros.

Aponte a ferramenta para o Gateway ou virtual server AAA, não para a interface de gerenciamento. A exposição é por virtual server, então um appliance com vários VIPs precisa que cada um seja testado. A sonda carrega um envelope de segurança rígido — um comprimento de RelayState validado, nunca varrido — que É Seguro Executar? detalha.

Opções

FlagDescrição
TARGETUm ou mais alvos [https://]HOST[:PORT]; o esquema padrão é https://
-f, --targets-file FILELê alvos de um arquivo (um por linha; comentários com #)
--timeout SECSTimeout por requisição (padrão: 15)
--workers NAlvos concorrentes (padrão: 16); a saída permanece na ordem de entrada
-b, --briefUma linha alinhada por alvo — ideal para escanear muitos hosts
--jsonEmite JSON estruturado, incluindo cada requisição enviada por alvo
--no-colorDesativa saída colorida (também respeita NO_COLOR e não-TTY)

Exemplos

Um appliance vulnerável (a saída padrão de duas linhas). O marcador [!] e VULNERABLE são renderizados em vermelho em um 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

Um appliance corrigido:

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)

A proteção contra falsos positivos disparando. A sonda e o controle de mesmo comprimento retornaram o sinal não corrigido, então a resposta não depende do que foi enviado e a resposta aparentemente decisiva é retirada:

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

Varrendo um parque (--brief). As duas linhas gateway.example.com são os virtual servers SP e somente IdP no mesmo appliance — ambos respondem, o que uma verificação de pré-condição de configuração não conseguiria:

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

Saída legível por máquina (--json). Cada requisição é incluída, então um achado pode ser re-derivado a partir da evidência em vez de ser confiado. O controle é registrado por sua relação com a sonda em vez de como um veredito próprio, porque um controle que se lê como uma build corrigida é o resultado esperado em toda 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"
      }
    ]
  }
]

É Seguro Executar?

Sim. Ele foi projetado para uso em produção e em avaliações:

  • Um comprimento fixo, nunca uma varredura. O RelayState da sonda decodifica para exatamente 20 bytes e a ferramenta não envia nenhum outro comprimento sob nenhuma flag. Em um appliance não corrigido, o comprimento decodificado é o seletor de ramo, e os ramos incluem alguns que criam uma sessão e alguns que causam SIGSEGV no packet engine — reiniciando todo o NetScaler e derrubando o tráfego por cerca de 45 segundos. Vinte bytes caem em um ramo limpo de erro interno que não cria sessão, e o construtor de payload se recusa a construir qualquer outro comprimento, então uma edição em outro lugar não pode silenciosamente ampliar a sonda.
  • Validado por medição. A sonda de 20 bytes foi executada 10 vezes consecutivas contra um 13.1-63.18 não corrigido com zero cores gerados e nenhum reinício do packet engine. A verificação em si já foi executada contra ambos os ramos de manutenção, em ambos os lados da correção, e contra virtual servers de provedor de serviços e somente IdP igualmente, sem reinício do packet engine em nenhum deles.
  • Sem autenticação, sem material de credencial, sem mudança de estado. Nenhuma assertion, assinatura, timestamp, sessão ou certificado de cliente é apresentado em qualquer lugar nesta verificação. O parâmetro SAMLResponse precisa estar presente para que o ramo RelayState seja alcançado, mas seu conteúdo é irrelevante, então são quatro bytes de lixo. O ramo não emite cookie e não escreve configuração.
  • Proteção contra falsos positivos. VULNERABLE nunca é reportado com base em uma única resposta — veja o controle.

Se você modificar a sonda, não altere o comprimento decodificado do RelayState e não varra comprimentos. Vinte bytes é essencial, e mais curto não é mais seguro. Outros comprimentos não são testados no melhor caso e uma indisponibilidade do appliance no pior caso.

Pegada de requisições e logs

Três requisições HTTP por alvo, e uma quarta apenas quando o appliance retorna o sinal não corrigido:

#RequisiçãoPropósito
1GET /logon/LogonPoint/tmindex.htmlIdentificação do NetScaler (tokens de Content-Security-Policy)
2GET /vpn/js/rdx/core/rdx.jsIdentificação do NetScaler
3POST /cgi/samlautha sonda
4POST /cgi/samlautho controle, enviado apenas após um sinal não corrigido

Redirecionamentos não são seguidos e nenhum cookie é jamais enviado de volta — o NetScaler serve um NSC_DLGE expirado que um cliente que o reproduzisse carregaria para a requisição 4, transformando o POST em uma página de logon.

O nsppe registra o POST SAML em /var/log/ns.log no nível informativo, sem necessidade de nenhum botão de debug, como uma falha de desserialização de contexto nFactor incluindo a linha nFactor: ctx deserialize aaa_info, base64 decode failed. Não há linhas de criação de sessão ou login neste comprimento, o que distingue uma varredura de uma tentativa de bypass.

Como Funciona

A correção é uma instrução. Em uma desserialização de contexto com falha, a build vulnerável carrega o comprimento decodificado do RelayState adiante como o status da requisição; a build corrigida carrega o erro constante 0xe0005, renderizado como Malformed Assertion. Então um único POST os separa:

Resposta à sondaBuildVeredito
500 Internal Server Error 43524não corrigidaVULNERABLE
200 Malformed Assertion sent to NetscalercorrigidaPATCHED

A build corrigida responde Malformed Assertion em todos os comprimentos, o que faz da resposta não corrigida um oráculo em vez de uma coincidência.

O controle é o que faz um 500 significar algo

VULNERABLE baseia-se em uma única resposta distintiva, então a ferramenta verifica se a resposta realmente depende do que foi enviado. Após o sinal não corrigido, ela repete a requisição com um RelayState de controle com o mesmo comprimento decodificado de 20 bytes, diferindo apenas nos 16 bytes após ctx=. Esse conteúdo é rejeitado por uma proteção antes do desserializador, então toda build testada — corrigida e não corrigida — responde a ele 200 Malformed Assertion. O veredito se mantém apenas se as duas respostas diferirem. Se elas coincidirem, algo está retornando 500/43524 independentemente da entrada, e o resultado é INCONCLUSIVE marcado como flat-response em vez de um falso VULNERABLE. Manter o controle no mesmo comprimento decodificado o mantém dentro do envelope de segurança validado e isola o conteúdo como a única variável.

A proteção é unidirecional. Ela não pode validar um veredito PATCHED, porque um appliance genuinamente corrigido responde à sonda e ao controle de forma idêntica — é isso que significa estar corrigido aqui. Veja Limitações.

Ele responde em virtual servers somente IdP também

A desserialização do RelayState é executada antes da correspondência de política SAML, então um virtual server que carrega apenas uma samlIdPPolicy responde à sonda, não apenas um com um samlAction de provedor de serviços vinculado. Isso é uma cobertura mais ampla do que uma verificação de pré-condição de configuração pode oferecer.

Uma não correspondência nunca é uma afirmação de segurança

A resposta vulnerável é a única autocorroborante: ela carrega um marcador específico, e o controle prova que a resposta depende do que foi enviado. PATCHED também é evidência positiva — o erro corrigido do próprio appliance no caminho que a sonda alcançou — mas está limitado a este CVE e a esse caminho. INCONCLUSIVE e ERROR não são evidência alguma: a sonda nunca alcançou o desserializador, então o estado da correção é desconhecido, e é por isso que INCONCLUSIVE é um veredito separado em vez de ser agrupado em PATCHED. Reportar silêncio como aprovação erra na direção perigosa. Onde você precisa de certeza, confirme com show ns version contra as builds em Remediação.

Vereditos

Todo veredito carrega uma tag curta de reason. --brief a imprime como a terceira coluna e --json a carrega como reason.

VereditoTag de reasonSignificado
VULNERABLEinternal-error-43524O appliance propagou o comprimento decodificado do RelayState como seu erro interno, e um controle de mesmo comprimento provou que a resposta depende do que foi enviado. A correção do CTX696939 está ausente — corrija.
PATCHEDfixed-error-returnedO appliance retornou o erro corrigido no caminho que a sonda alcançou. Limitado a este CVE, e veja Limitações sobre dispositivos interpostos.
UNAFFECTEDno-saml-endpoint/cgi/samlauth retornou 404, então o consumidor de assertion SAML não é servido aqui. Por vserver, não por appliance, e veja a ressalva de builds mais antigas em Limitações.
INCONCLUSIVEflat-responseSonda e controle de mesmo comprimento responderam de forma idêntica, então a resposta não depende do que foi enviado. A proteção contra falsos positivos disparando.
INCONCLUSIVEgeneric-internal-errorO endpoint retornou 43549, seu erro interno genérico, que tanto builds corrigidas quanto não corrigidas retornam. Não é o discriminador — e observe que é o marcador não corrigido para o CVE-2026-8452 não relacionado, então parece um acerto e não é.
INCONCLUSIVEunrecognized-replyO endpoint respondeu com algo fora do conjunto reconhecido.
INCONCLUSIVEno-probe-responseO host respondeu à identificação mas não à sonda — um timeout, um reset, ou um middlebox descartando o POST. Tente novamente.
ERRORnot-identifiedNão identificado como um NetScaler, ou inacessível.

Todas as quatro razões de INCONCLUSIVE significam a mesma coisa para a tomada de decisão — desconhecido, não corrigido. A tag nomeia qual condição corrigir antes de reexecutar.

Códigos de saída

CódigoSignificado
0Nenhum alvo era VULNERABLE
1Pelo menos um alvo é VULNERABLE
2Erro de uso (argumentos inválidos / arquivo de alvos ilegível)

Saída 0 não é um atestado de saúde. PATCHED, UNAFFECTED e todas as quatro razões de INCONCLUSIVE colapsam nela, e apenas uma delas é um resultado positivo. Um wrapper que precisa distinguir "corrigido" de "não foi possível classificar" deve ler o veredito — primeira coluna de --brief, ou o campo verdict de --json — não o código de saída.

Limitações

  • Um WAF ou load balancer pode distorcer um veredito PATCHED. Malformed Assertion é o que o appliance retorna sempre que a sonda não consegue alcançar o desserializador de contexto, e estar corrigido é apenas uma razão para isso acontecer. Um dispositivo interposto que remove, corrompe ou curto-circuita o parâmetro RelayState portanto produz PATCHED em um appliance vulnerável, e nenhuma requisição adicional que a ferramenta pudesse enviar separaria os dois. Onde algo pode estar na frente do appliance, confirme com show ns version.
  • UNAFFECTED está limitado a builds atuais. Em 14.1-43.55 / 13.1-61.27 e anteriores o aviso afirma que a exposição não requer uma ação SAML alguma — qualquer virtual server Gateway ou AAA é afetado — então um 404 em tal build não coloca o appliance fora de escopo. Esse trecho é retirado do aviso em vez de medido.
  • Isto verifica um CVE, não o nível de correção do appliance. PATCHED não diz nada sobre qualquer outra vulnerabilidade do NetScaler, incluindo CVE-2026-19489 no mesmo boletim.
  • Não é uma verificação de exploração, e não é uma verificação de comprometimento. VULNERABLE estabelece que a correção está ausente no caminho que a sonda alcançou. Ele não mede até onde um atacante poderia levar o bypass na sua configuração, e não lhe dirá se alguém já o fez — procure isso em /var/log/ns.log separadamente.
  • Ele não pode lhe dizer se os ramos de negação de serviço são alcançáveis. A ferramenta envia um comprimento validado e nunca explora os outros, por design.
  • Alcançabilidade. Um resultado reflete o que o appliance expõe à posição de rede a partir da qual você o executa.

Remediação

Atualize para 13.1-63.21 ou posterior, ou 14.1-73.32 ou posterior (FIPS e NDcPP: 13.1-37.277 para 13.1-FIPS e 13.1-NDcPP, 14.1-73.32 FIPS para 14.1-FIPS), conforme CTX696939. Appliances em 12.1 ou 13.0 não têm correção e não receberão uma — esses ramos estão em fim de vida e devem ser migrados para um ramo suportado.

Três notas adicionais:

  • Corrija ambos os nós de um par HA. Um secundário não corrigido é um appliance totalmente exposto no momento em que assume o controle.
  • Se você não pode corrigir hoje, verifique o único botão global que limita o impacto. A sessão que este bug gera em um virtual server Gateway ignora a avaliação de política de sessão, então ela não capta o defaultAuthorizationAction de qualquer vpn sessionAction vinculado ao vserver — ela recorre ao set vpn parameter -defaultAuthorizationAction global. O padrão de fábrica é DENY; ALLOW é comum no campo porque é o que os administradores usam em vez de escrever políticas de autorização por usuário, e ALLOW é o que permite que a sessão não autenticada alcance recursos internos. É global, não por vserver. Isso limita o impacto; não é uma correção.
  • Delimite seu inventário pela configuração SAML, não pelo tipo de virtual server. Verifique a configuração em execução para add authentication samlAction e add authentication samlIdPProfile juntamente com add authentication vserver e add vpn vserver — sujeito à ressalva de builds mais antigas acima.

O CTX696939 também corrige CVE-2026-19489, e esta superfície se sobrepõe fortemente com CVE-2026-8452 do boletim anterior: em builds a partir de 14.1-43.56 / 13.1-61.28 em diante, ambos os problemas são condicionados a uma ação SAML configurada, então uma auditoria de configuração delimita ambos.

Licença

Este código é distribuído sob uma licença MIT.

Aviso Legal

O uso desta ferramenta para atacar alvos sem consentimento mútuo prévio é ilegal. É responsabilidade do usuário final obedecer a todas as leis locais, estaduais e federais aplicáveis. Os desenvolvedores não assumem nenhuma responsabilidade e não são responsáveis por qualquer uso indevido ou dano causado por este programa.

Veja Também

  • Citrix CTX696939 — Boletim de segurança do NetScaler
  • NVD — CVE-2026-19490
  • NVD — CVE-2026-19489
  • NVD — CVE-2026-8452
Baixar ferramenta