Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-19490-check — Citrix NetScaler SAML-Authentifizierungs-Bypass CVE-2026-19490 sicher erkennen | Kitploit
Tools/GitHubGitHub/bishopfox/cve-2026-19490-check
DefensivwerkzeugeSchwachstellenscannerWeb-SchwachstellenscannerSchwachstellenanalyseInformationsbeschaffungWebsicherheitNetzwerksicherheitPenetrationstestsAuthentifizierung
GitHubbishopfox/cve-2026-19490-check

CVE-2026-19490-check

Citrix NetScaler SAML-Authentifizierungs-Bypass CVE-2026-19490 sicher erkennen

1vor 18h 16mNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Repository anzeigen
Teilen

Citrix NetScaler SAML nFactor Context Authentication Bypass — Skript zur Erkennung der Schwachstelle

Ein sicherer, unauthentifizierter Schwachstellen-Check für CVE-2026-19490, die Pre-Authentication- Authentication-Bypass in dem SAML-Service-Provider-Pfad von Citrix NetScaler ADC / NetScaler Gateway (CTX696939, veröffentlicht am 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). Gemeldet von Samarth Vashisht vom Penetrationstest-Team von JPMorgan Chase.

Die Appliance base64-dekodiert den RelayState-Parameter einer SAML-Antwort und übergibt, wenn der Klartext mit ctx= beginnt, den Rest an den nFactor-Context-Deserializer. Bei einem ungepatchten Build propagiert ein Deserialisierungsfehler die dekodierte RelayState-Länge als internen Disposition-Code der Anfrage statt eines Fehlers, sodass ein unauthentifizierter Angreifer allein dadurch, dass er die Länge des RelayState wählt, bestimmt, welchen internen Zweig die Appliance als Nächstes nimmt. Einige Zweige erzeugen eine echte Gateway-Session; andere bringen die Packet Engine zum Absturz und starten die Appliance neu. Dieses Skript tut weder das eine noch das andere — es sendet die eine validierte Länge, die nachweislich keine Session erzeugt und die Packet Engine unberührt lässt, und beantwortet pro Ziel eine einzige Frage: Ein anderes Ergebnis als ist .

ist diese Appliance verwundbar?
VULNERABLE
für sich genommen kein Unbedenklichkeitsbescheinigung

Verwendung

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+, nur Standardbibliothek — keine Drittanbieter-Pakete.

Richten Sie das Tool auf den Gateway- oder AAA-Virtual-Server, nicht auf die Management-Schnittstelle. Die Exposition gilt pro Virtual Server, daher muss bei einer Appliance mit mehreren VIPs jeder einzelne getestet werden. Die Sonde trägt eine harte Sicherheitshülle — eine validierte RelayState-Länge, niemals gesweept — die Ist es sicher auszuführen? darlegt.

Optionen

FlagBeschreibung
TARGETEin oder mehrere [https://]HOST[:PORT]-Ziele; das Schema ist standardmäßig https://
-f, --targets-file FILEZiele aus einer Datei lesen (eine pro Zeile; #-Kommentare)
--timeout SECSTimeout pro Anfrage (Standard: 15)
--workers NGleichzeitige Ziele (Standard: 16); die Ausgabe bleibt in Eingabereihenfolge
-b, --briefEine ausgerichtete Zeile pro Ziel — ideal zum Scannen vieler Hosts
--jsonStrukturiertes JSON ausgeben, einschließlich jeder pro Ziel gesendeten Anfrage
--no-colorFarbige Ausgabe deaktivieren (berücksichtigt auch NO_COLOR und Nicht-TTY)

Beispiele

Eine verwundbare Appliance (die standardmäßige zweizeilige Ausgabe). Der [!]-Marker und VULNERABLE werden auf einem TTY rot dargestellt:

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

Eine gepatchte Appliance:

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)

Der False-Positive-Guard greift. Die Sonde und die gleich lange Kontrolle lieferten beide das ungepatchte Signal zurück, sodass die Antwort nicht davon abhängt, was gesendet wurde, und die entscheidend wirkende Antwort zurückgezogen wird:

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

Sweeping eines Bestands (--brief). Die beiden gateway.example.com-Zeilen sind die SP- und die IdP-only-Virtual-Server auf derselben Appliance — beide antworten, was ein Konfigurations-Vorbedingungs-Check nicht schaffen würde:

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

Maschinenlesbare Ausgabe (--json). Jede Anfrage ist enthalten, sodass ein Befund aus den Belegen rekonstruiert werden kann, statt ihm zu vertrauen. Die Kontrolle wird über ihre Beziehung zur Sonde erfasst und nicht als eigenes Urteil, weil eine Kontrolle, die wie ein gepatchter Build aussieht, auf jedem Build das erwartete Ergebnis ist:

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"
      }
    ]
  }
]

Ist es sicher auszuführen?

Ja. Es ist für den Produktiv- und Assessment-Einsatz konzipiert:

  • Eine feste Länge, niemals ein Sweep. Der RelayState der Sonde dekodiert zu genau 20 Bytes, und das Tool sendet unter keinem Flag eine andere Länge. Bei einer ungepatchten Appliance ist die dekodierte Länge der Zweigselektor, und die Zweige umfassen solche, die eine Session erzeugen, und solche, die die Packet Engine per SIGSEGV zum Absturz bringen — was den gesamten NetScaler neu startet und den Datenverkehr für etwa 45 Sekunden unterbricht. Zwanzig Bytes landen auf einem sauberen Internal-Error-Zweig, der keine Session erzeugt, und der Payload-Builder weigert sich, eine andere Länge zu konstruieren, sodass eine Änderung an anderer Stelle die Sonde nicht stillschweigend erweitern kann.
  • Durch Messung validiert. Die 20-Byte-Sonde wurde 10 Mal hintereinander gegen ein ungepatchtes 13.1-63.18 ausgeführt, wobei null Cores erzeugt und kein Packet-Engine-Neustart ausgelöst wurde. Der Check selbst wurde seither gegen beide Maintenance-Branches, auf beiden Seiten des Fixes und sowohl gegen Service-Provider- als auch gegen IdP-only-Virtual-Server ausgeführt, ohne Packet-Engine-Neustart bei irgendeinem davon.
  • Keine Authentifizierung, kein Credential-Material, keine Zustandsänderung. Es wird nirgends in diesem Check eine Assertion, Signatur, ein Zeitstempel, eine Session oder ein Client-Zertifikat präsentiert. Der SAMLResponse-Parameter muss vorhanden sein, damit der RelayState-Zweig erreicht wird, aber sein Inhalt ist irrelevant, daher sind es vier Bytes Müll. Der Zweig setzt kein Cookie und schreibt keine Konfiguration.
  • False-Positive-Guard. VULNERABLE wird niemals aufgrund einer einzelnen Antwort gemeldet — siehe die Kontrolle.

Wenn Sie die Sonde ändern, ändern Sie nicht die dekodierte RelayState-Länge und sweepen Sie keine Längen. Zwanzig Bytes sind tragend, und kürzer ist nicht sicherer. Andere Längen sind bestenfalls ungetestet und schlimmstenfalls ein Ausfall der Appliance.

Anfrage- und Log-Footprint

Drei HTTP-Anfragen pro Ziel und eine vierte nur dann, wenn die Appliance das ungepatchte Signal zurückgibt:

#AnfrageZweck
1GET /logon/LogonPoint/tmindex.htmlNetScaler-Identifikation (Content-Security-Policy-Token)
2GET /vpn/js/rdx/core/rdx.jsNetScaler-Identifikation
3POST /cgi/samlauthdie Sonde
4POST /cgi/samlauthdie Kontrolle, nur nach einem ungepatchten Signal gesendet

Weiterleitungen werden nicht verfolgt und es wird niemals ein Cookie zurückgesendet — NetScaler liefert ein abgelaufenes NSC_DLGE, das ein wiederspielender Client in Anfrage 4 tragen würde, wodurch der POST auf eine Logon-Seite umgeleitet würde.

nsppe protokolliert den SAML-POST in /var/log/ns.log auf Informationslevel, ohne dass ein Debug-Schalter erforderlich ist, als nFactor-Context-Deserialisierungsfehler einschließlich der Zeile nFactor: ctx deserialize aaa_info, base64 decode failed. Bei dieser Länge gibt es keine Session-Erzeugungs- oder Login-Zeilen, was einen Scan von einem Versuch des Bypasses unterscheidet.

Wie es funktioniert

Der Fix ist eine einzige Instruktion. Bei einer fehlschlagenden Context-Deserialisierung trägt der verwundbare Build die dekodierte RelayState-Länge als Status der Anfrage weiter; der gefixte Build trägt den konstanten Fehler 0xe0005 weiter, dargestellt als Malformed Assertion. Ein POST trennt sie also:

Antwort auf die SondeBuildUrteil
500 Internal Server Error 43524ungepatchtVULNERABLE
200 Malformed Assertion sent to NetscalergepatchtPATCHED

Der gepatchte Build antwortet bei jeder Länge mit Malformed Assertion, was die ungepatchte Antwort zu einem Orakel statt zu einem Zufall macht.

Die Kontrolle ist es, was einem 500 eine Bedeutung gibt

VULNERABLE stützt sich auf eine einzige unterscheidende Antwort, daher verifiziert das Tool, dass die Antwort tatsächlich davon abhängt, was gesendet wurde. Nach dem ungepatchten Signal wiederholt es die Anfrage mit einer Kontroll-RelayState von derselben dekodierten Länge von 20 Bytes, die sich nur in den 16 Bytes nach ctx= unterscheidet. Dieser Inhalt wird von einem Guard vor dem Deserializer zurückgewiesen, sodass jeder getestete Build — gepatcht und ungepatcht — darauf mit 200 Malformed Assertion antwortet. Das Urteil bleibt nur bestehen, wenn die beiden Antworten voneinander abweichen. Wenn sie übereinstimmen, gibt etwas unabhängig von der Eingabe 500/43524 zurück, und das Ergebnis ist INCONCLUSIVE mit dem Tag flat-response statt eines falschen VULNERABLE. Die Kontrolle auf derselben dekodierten Länge zu halten, bewahrt sie innerhalb der validierten Sicherheitshülle und isoliert den Inhalt als einzige Variable.

Der Guard ist einseitig. Er kann kein PATCHED-Urteil validieren, weil eine tatsächlich gepatchte Appliance auf Sonde und Kontrolle identisch antwortet — genau das bedeutet hier gepatcht zu sein. Siehe Einschränkungen.

Es antwortet auch auf IdP-only-Virtual-Servern

Die RelayState-Deserialisierung läuft vor dem SAML-Policy-Matching, sodass ein Virtual Server, der nur eine samlIdPPolicy trägt, auf die Sonde antwortet, nicht nur einer mit einer gebundenen Service-Provider-samlAction. Das ist eine breitere Abdeckung, als ein Konfigurations-Vorbedingungs-Check bieten kann.

Ein Nicht-Treffer ist niemals eine Aussage über Sicherheit

Die verwundbare Antwort ist die einzige, die sich selbst bestätigt: Sie trägt einen spezifischen Marker, und die Kontrolle beweist, dass die Antwort davon abhängt, was gesendet wurde. PATCHED ist ebenfalls ein positiver Beleg — der eigene gefixte Fehler der Appliance auf dem Pfad, den die Sonde erreicht hat — aber er ist auf diese CVE und auf diesen Pfad beschränkt. INCONCLUSIVE und ERROR sind überhaupt keine Belege: Die Sonde hat den Deserializer nie erreicht, der Patch-Status ist also unbekannt, und deshalb ist INCONCLUSIVE ein separates Urteil statt in PATCHED eingefaltet. Stille als Bestehen zu melden, liegt in der gefährlichen Richtung falsch. Wo Sie Gewissheit benötigen, bestätigen Sie mit show ns version gegen die Builds in Behebung.

Urteile

Jedes Urteil trägt ein kurzes reason-Tag. --brief gibt es als dritte Spalte aus und --json trägt es als reason.

UrteilReason-TagBedeutung
VULNERABLEinternal-error-43524Die Appliance propagierte die dekodierte RelayState-Länge als ihren internen Fehler, und eine gleich lange Kontrolle bewies, dass die Antwort davon abhängt, was gesendet wurde. Der CTX696939-Fix fehlt — patchen Sie.
PATCHEDfixed-error-returnedDie Appliance gab den gefixten Fehler auf dem Pfad zurück, den die Sonde erreicht hat. Beschränkt auf diese CVE, und siehe Einschränkungen zu zwischengeschalteten Geräten.
UNAFFECTEDno-saml-endpoint/cgi/samlauth gab 404 zurück, der SAML-Assertion-Consumer wird hier also nicht bedient. Pro Vserver, nicht pro Appliance, und siehe den Vorbehalt zu älteren Builds in Einschränkungen.
INCONCLUSIVEflat-responseSonde und gleich lange Kontrolle antworteten identisch, die Antwort hängt also nicht davon ab, was gesendet wurde. Der False-Positive-Guard greift.
INCONCLUSIVEgeneric-internal-errorDer Endpunkt gab 43549 zurück, seinen generischen internen Fehler, den sowohl gepatchte als auch ungepatchte Builds zurückgeben. Nicht der Diskriminator — und beachten Sie, dass er der ungepatchte Marker für die unabhängige CVE-2026-8452 ist, sodass er wie ein Treffer aussieht und keiner ist.
INCONCLUSIVEunrecognized-replyDer Endpunkt antwortete mit etwas außerhalb der erkannten Menge.
INCONCLUSIVEno-probe-responseDer Host antwortete auf die Identifikation, aber nicht auf die Sonde — ein Timeout, ein Reset oder eine Middlebox, die den POST verwirft. Erneut versuchen.
ERRORnot-identifiedNicht als NetScaler identifiziert oder nicht erreichbar.

Alle vier INCONCLUSIVE-Gründe bedeuten für die Entscheidungsfindung dasselbe — unbekannt, nicht gepatcht. Das Tag benennt, welche Bedingung vor dem erneuten Ausführen zu beheben ist.

Exit-Codes

CodeBedeutung
0Kein Ziel war VULNERABLE
1Mindestens ein Ziel ist VULNERABLE
2Verwendungsfehler (ungültige Argumente / nicht lesbare Zieldatei)

Exit 0 ist keine Unbedenklichkeitsbescheinigung. PATCHED, UNAFFECTED und alle vier INCONCLUSIVE-Gründe fallen darunter zusammen, und nur eines davon ist ein positives Ergebnis. Ein Wrapper, der „gepatcht" von „konnte nicht klassifiziert werden" unterscheiden muss, muss das Urteil lesen — erste Spalte von --brief oder das verdict-Feld von --json — nicht den Exit-Code.

Einschränkungen

  • Eine WAF oder ein Load Balancer kann ein PATCHED-Urteil verzerren. Malformed Assertion ist das, was die Appliance zurückgibt, wann immer die Sonde den Context-Deserializer nicht erreicht, und gepatcht zu sein ist nur einer der Gründe dafür. Ein zwischengeschaltetes Gerät, das den RelayState-Parameter entfernt, verunstaltet oder kurzschließt, erzeugt daher PATCHED auf einer verwundbaren Appliance, und keine zusätzliche Anfrage, die das Tool senden könnte, würde die beiden trennen. Wo etwas vor der Appliance sitzen könnte, bestätigen Sie mit show ns version.
  • UNAFFECTED ist auf aktuelle Builds beschränkt. Bei 14.1-43.55 / 13.1-61.27 und früher besagt das Advisory, dass die Exposition überhaupt keine SAML-Action erfordert — jeder Gateway- oder AAA-Virtual-Server ist betroffen —, sodass ein 404 auf einem solchen Build die Appliance nicht aus dem Geltungsbereich nimmt. Dieser Teil ist dem Advisory entnommen und nicht gemessen.
  • Dies prüft eine CVE, nicht den Patch-Stand der Appliance. PATCHED sagt nichts über irgendeine andere NetScaler-Schwachstelle aus, einschließlich CVE-2026-19489 im selben Bulletin.
  • Kein Exploitation-Check und kein Kompromittierungs-Check. VULNERABLE belegt, dass der Fix auf dem Pfad fehlt, den die Sonde erreicht hat. Es misst nicht, wie weit ein Angreifer den Bypass bei Ihrer Konfiguration treiben könnte, und es sagt Ihnen nicht, ob jemand dies bereits getan hat — das suchen Sie separat in /var/log/ns.log.
  • Es kann Ihnen nicht sagen, ob die Denial-of-Service-Zweige erreichbar sind. Das Tool sendet eine validierte Länge und erkundet die anderen konstruktionsbedingt nie.
  • Erreichbarkeit. Ein Ergebnis spiegelt wider, was die Appliance gegenüber der Netzwerkposition exponiert, von der aus Sie es ausführen.

Behebung

Aktualisieren Sie auf 13.1-63.21 oder später bzw. 14.1-73.32 oder später (FIPS und NDcPP: 13.1-37.277 für 13.1-FIPS und 13.1-NDcPP, 14.1-73.32 FIPS für 14.1-FIPS), gemäß CTX696939. Appliances auf 12.1 oder 13.0 haben keinen Fix und werden keinen erhalten — diese Branches sind End of Life und sollten auf einen unterstützten Branch migriert werden.

Drei weitere Hinweise:

  • Patchen Sie beide Knoten eines HA-Paars. Ein ungepatchter Secondary ist in dem Moment, in dem er übernimmt, eine vollständig exponierte Appliance.
  • Wenn Sie heute nicht patchen können, prüfen Sie den einen globalen Schalter, der die Auswirkung begrenzt. Die Session, die dieser Bug auf einem Gateway-Virtual-Server erzeugt, überspringt die Session-Policy-Auswertung, sodass sie nicht die defaultAuthorizationAction irgendeiner an den Vserver gebundenen vpn sessionAction aufgreift — sie fällt auf die globale set vpn parameter -defaultAuthorizationAction zurück. Der ausgelieferte Standard ist DENY; ALLOW ist in der Praxis verbreitet, weil Administratoren danach greifen, statt benutzerspezifische Autorisierungsrichtlinien zu schreiben, und ALLOW ist es, was die unauthentifizierte Session auf interne Ressourcen zugreifen lässt. Sie ist global, nicht pro Vserver. Dies begrenzt die Auswirkung; es ist kein Fix.
  • Grenzen Sie Ihr Inventar nach SAML-Konfiguration ab, nicht nach Virtual-Server-Typ. Prüfen Sie die laufende Konfiguration auf add authentication samlAction und add authentication samlIdPProfile neben add authentication vserver und add vpn vserver — vorbehaltlich des obigen Vorbehalts zu älteren Builds.

CTX696939 behebt auch CVE-2026-19489, und diese Angriffsfläche überschneidet sich stark mit CVE-2026-8452 aus dem vorherigen Bulletin: Bei Builds ab 14.1-43.56 / 13.1-61.28 sind beide Probleme an eine konfigurierte SAML-Action geknüpft, sodass ein Konfigurationsaudit beide abgrenzt.

Lizenz

Dieser Code wird unter einer MIT-Lizenz vertrieben.

Rechtlicher Haftungsausschluss

Die Verwendung dieses Tools zum Angriff auf Ziele ohne vorherige gegenseitige Zustimmung ist illegal. Es liegt in der Verantwortung des Endnutzers, alle geltenden lokalen, staatlichen und bundesstaatlichen Gesetze zu befolgen. Die Entwickler übernehmen keine Haftung und sind nicht verantwortlich für Missbrauch oder Schäden, die durch dieses Programm verursacht werden.

Siehe auch

  • Citrix CTX696939 — NetScaler-Sicherheitsbulletin
  • NVD — CVE-2026-19490
  • NVD — CVE-2026-19489
  • NVD — CVE-2026-8452
Tool herunterladen