Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-19490-check — 安全检测 Citrix NetScaler SAML 认证绕过漏洞 CVE-2026-19490 | Kitploit
工具/GitHubGitHub/bishopfox/cve-2026-19490-check
防御工具漏洞扫描器Web漏洞扫描器漏洞分析信息收集Web安全网络安全渗透测试身份验证
GitHubbishopfox/cve-2026-19490-check

CVE-2026-19490-check

安全检测 Citrix NetScaler SAML 认证绕过漏洞 CVE-2026-19490

116小时34分前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库

Citrix NetScaler SAML nFactor 上下文认证绕过 — 漏洞检测脚本

针对 CVE-2026-19490 的安全、未认证漏洞检查,该漏洞是 Citrix NetScaler ADC / NetScaler Gateway SAML 服务提供者路径中的预认证认证绕过(CTX696939,发布于 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)。由 JPMorgan Chase 渗透测试团队的 Samarth Vashisht 报告。

该设备对 SAML 响应的 RelayState 参数进行 base64 解码,当明文以 ctx= 开头时,将剩余部分交给 nFactor 上下文反序列化器处理。在未修补的版本上,反序列化失败会将解码后的 RelayState 长度作为请求的内部处置代码传播,而不是返回错误,因此未认证的攻击者仅通过选择 RelayState 的长度就能决定设备接下来走哪条内部分支。某些分支会生成真实的 Gateway 会话;其他分支会使数据包引擎崩溃并重启设备。本脚本两者都不做——它发送经过验证的、不会创建会话且不会影响数据包引擎的单一长度,并对每个目标回答一个问题:该设备是否存在漏洞? 除 VULNERABLE 之外的结果本身并不代表安全。

用法

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+,仅使用标准库——无第三方包。

将工具指向 Gateway 或 AAA 虚拟服务器,而不是管理接口。暴露是按虚拟服务器计算的,因此具有多个 VIP 的设备需要逐一测试。探测带有硬性安全边界——一个经过验证的 RelayState 长度,绝不扫描——运行是否安全?对此进行了说明。

选项

示例

存在漏洞的设备(默认两行输出)。在 TTY 上 [!] 标记和 VULNERABLE 显示为红色:

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

已修补的设备:

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)

误报防护触发。 探测和同长度对照都返回了未修补信号,因此回复不取决于发送的内容,看似决定性的答案被撤回:

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

扫描整个环境(--brief)。两行 gateway.example.com 是同一设备上的 SP 和仅 IdP 虚拟服务器——两者都有响应,这是配置前置条件检查无法做到的:

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

机器可读输出(--json)。包含每个请求,因此可以从证据重新推导发现,而不是仅凭信任。对照按其与探测的关系记录,而不是作为其自身的判定,因为一个读起来像已修补版本的对照在每个版本上都是预期结果:

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

运行是否安全?

是的。它专为生产环境和评估使用而设计:

  • 一个固定长度,绝不扫描。 探测的 RelayState 解码后恰好为 20 字节,工具在任何标志下都不会发送其他长度。在未修补的设备上,解码后的长度就是分支选择器,而分支包括创建会话的分支和使数据包引擎发生 SIGSEGV 的分支——后者会重启整个 NetScaler 并中断流量约 45 秒。20 字节落在干净的内部错误分支上,不会创建会话,并且载荷构建器拒绝构造任何其他长度,因此其他地方的编辑无法悄悄扩大探测范围。
  • 通过测量验证。 20 字节探测针对未修补的 13.1-63.18 连续运行了 10 次,零核心转储生成,无数据包引擎重启。此后该检查已针对两个维护分支、修复的两侧,以及服务提供者和仅 IdP 虚拟服务器运行,均无数据包引擎重启。
  • 无认证、无凭据材料、无状态更改。 此检查中不呈现任何断言、签名、时间戳、会话或客户端证书。SAMLResponse 参数必须存在才能到达 RelayState 分支,但其内容无关紧要,因此它是四个字节的垃圾数据。该分支不发放 cookie,也不写入配置。
  • 误报防护。 VULNERABLE 绝不会仅凭单个响应报告——参见对照。

如果你修改探测,不要更改解码后的 RelayState 长度,也不要扫描长度。 20 字节是关键,更短并不更安全。其他长度最好情况是未测试,最坏情况是设备中断。

请求和日志足迹

每个目标三个 HTTP 请求,仅当设备返回未修补信号时才有第四个:

不跟随重定向,也从不回传 cookie——NetScaler 会提供一个过期的 NSC_DLGE,重放的客户端会将其带入请求 4,将 POST 翻转为登录页面。

nsppe 将 SAML POST 以信息级别记录到 /var/log/ns.log,无需调试开关,作为 nFactor 上下文反序列化失败,包括行 nFactor: ctx deserialize aaa_info, base64 decode failed。在此长度下没有会话创建或登录行,这正是扫描与尝试绕过之间的区别。

工作原理

修复只是一条指令。在上下文反序列化失败时,存在漏洞的版本将解码后的 RelayState 长度作为请求状态向前传递;修复后的版本传递常量错误 0xe0005,呈现为 Malformed Assertion。因此一个 POST 就能区分它们:

对探测的响应版本判定
500 Internal Server Error 43524未修补VULNERABLE
200 Malformed Assertion sent to Netscaler已修补PATCHED

已修补的版本在每个长度都回答 Malformed Assertion,这正是使未修补答案成为预言而非巧合的原因。

对照使 500 具有意义

VULNERABLE 依赖于单个区分性响应,因此工具验证响应确实取决于发送的内容。在未修补信号之后,它用相同 20 字节解码长度的对照 RelayState 重复请求,仅在 ctx= 之后的 16 字节上不同。该内容会被反序列化器之前的守卫拒绝,因此所有测试的版本——已修补和未修补——都回答 200 Malformed Assertion。只有当两个答案不同时判定才成立。如果它们匹配,则某些东西无论输入如何都返回 500/43524,结果是标记为 flat-response 的 INCONCLUSIVE,而不是错误的 VULNERABLE。将对照保持在同一解码长度使其处于验证过的安全边界内,并将内容隔离为唯一变量。

该守卫是单向的。 它无法验证 PATCHED 判定,因为真正已修补的设备对探测和对照的回答完全相同——这就是此处已修补的含义。参见局限性。

它也能在仅 IdP 虚拟服务器上回答

RelayState 反序列化在 SAML 策略匹配之前运行,因此仅携带 samlIdPPolicy 的虚拟服务器也会回答探测,而不仅仅是绑定了服务提供者 samlAction 的虚拟服务器。这比配置前置条件检查能提供的覆盖范围更广。

不匹配绝不代表安全

存在漏洞的答案是唯一自我印证的:它带有特定标记,并且对照证明回复取决于发送的内容。PATCHED 也是正面证据——设备自身在探测所到达路径上的固定错误——但它仅限于此 CVE 和该路径。INCONCLUSIVE 和 ERROR 根本不是证据:探测从未到达反序列化器,因此补丁状态未知,这就是为什么 INCONCLUSIVE 是单独的判定而不是并入 PATCHED。将沉默报告为通过会在危险的方向上出错。在需要确定性的地方,请对照修复中的版本用 show ns version 确认。

判定

每个判定都带有一个简短的 reason 标签。--brief 将其打印为第三列,--json 将其作为 reason 携带。

所有四个 INCONCLUSIVE 原因对决策而言含义相同——未知,未修补。 标签指明了重新运行前需要修复的条件。

退出代码

代码含义
0没有目标为 VULNERABLE
1至少一个目标为 VULNERABLE
2用法错误(参数错误 / 目标文件不可读)

退出 0 不是健康证明。 PATCHED、UNAFFECTED 和所有四个 INCONCLUSIVE 原因都归入其中,而其中只有一个是正面结果。需要区分“已修补”和“无法分类”的包装器必须读取判定——--brief 的第一列,或 --json 的 verdict 字段——而不是退出代码。

局限性

  • WAF 或负载均衡器可能使 PATCHED 判定失真。 Malformed Assertion 是设备在探测未能到达上下文反序列化器时返回的内容,而已修补只是发生这种情况的原因之一。因此,剥离、篡改或短路 RelayState 参数的中间设备会在存在漏洞的设备上产生 PATCHED,而工具能发送的任何额外请求都无法区分两者。在可能有东西位于设备前方的地方,请用 show ns version 确认。
  • UNAFFECTED 仅限于当前版本。 在 14.1-43.55 / 13.1-61.27 及更早版本上,公告指出暴露根本不需要 SAML 操作——任何 Gateway 或 AAA 虚拟服务器都受影响——因此在此类版本上 404 并不能使设备脱离范围。该分支取自公告而非测量。
  • 这检查一个 CVE,而非设备的补丁级别。 PATCHED 对任何其他 NetScaler 漏洞一无所知,包括同一公告中的 CVE-2026-19489。
  • 不是利用检查,也不是入侵检查。 VULNERABLE 确定修复在探测所到达的路径上缺失。它不衡量攻击者在你的配置上能将绕过推进多远,也不会告诉你是否已经有人利用了——请单独在 /var/log/ns.log 中搜寻。
  • 它无法告诉你拒绝服务分支是否可达。 工具发送一个经过验证的长度,按设计绝不探索其他长度。

修复

升级到 13.1-63.21 或更高版本,或 14.1-73.32 或更高版本(FIPS 和 NDcPP:13.1-FIPS 和 13.1-NDcPP 为 13.1-37.277,14.1-FIPS 为 14.1-73.32 FIPS),依据 CTX696939。12.1 或 13.0 上的设备没有修复,也不会获得修复——这些分支已终止支持,应迁移到受支持的分支。

另外三点说明:

  • 修补 HA 对的两个节点。 未修补的辅助节点在接管的那一刻就是完全暴露的设备。
  • 如果今天无法修补,请检查限制影响的一个全局开关。 此漏洞在 Gateway 虚拟服务器上生成的会话跳过会话策略评估,因此它不会采用绑定到 vserver 的任何 vpn sessionAction 的 defaultAuthorizationAction——它会回退到全局 set vpn parameter -defaultAuthorizationAction。出厂默认为 DENY;ALLOW 在现场很常见,因为管理员会用它来代替编写每用户授权策略,而 ALLOW 正是让未认证会话到达内部资源的原因。它是全局的,不是按 vserver 的。这限制了影响;它不是修复。
  • 按 SAML 配置而非虚拟服务器类型来界定清单范围。 检查运行配置中的 add authentication samlAction 和 add authentication samlIdPProfile 以及 add authentication vserver 和 add vpn vserver——受上述旧版本注意事项约束。

CTX696939 还修复了 CVE-2026-19489,并且此表面与上一公告中的 CVE-2026-8452 大量重叠:在 14.1-43.56 / 13.1-61.28 及之后的版本上,两个问题都以配置的 SAML 操作为前提,因此一次配置审计就能界定两者。

许可证

此代码在 MIT 许可证下分发。

法律免责声明

未经事先相互同意,使用此工具攻击目标是非法的。最终用户有责任遵守所有适用的地方、州和联邦法律。开发者不承担任何责任,也不对由此程序造成的任何误用或损害负责。

另见

  • Citrix CTX696939 — NetScaler 安全公告
  • NVD — CVE-2026-19490
  • NVD — CVE-2026-19489
  • NVD — CVE-2026-8452
下载工具
标志描述
TARGET一个或多个 [https://]HOST[:PORT] 目标;协议默认 https://
-f, --targets-file FILE从文件读取目标(每行一个;# 注释)
--timeout SECS每请求超时(默认:15)
--workers N并发目标数(默认:16);输出保持输入顺序
-b, --brief每个目标一行对齐输出——非常适合扫描大量主机
--json输出结构化 JSON,包括每个目标发送的每个请求
--no-color禁用彩色输出(也遵循 NO_COLOR 和非 TTY)
#请求用途
1GET /logon/LogonPoint/tmindex.htmlNetScaler 识别(Content-Security-Policy 令牌)
2GET /vpn/js/rdx/core/rdx.jsNetScaler 识别
3POST /cgi/samlauth探测
4POST /cgi/samlauth对照,仅在未修补信号后发送
判定原因标签含义
VULNERABLEinternal-error-43524设备将解码后的 RelayState 长度作为其内部错误传播,并且同长度对照证明回复取决于发送的内容。CTX696939 修复缺失——请修补。
PATCHEDfixed-error-returned设备在探测所到达的路径上返回了固定错误。仅限于此 CVE,关于中间设备参见局限性。
UNAFFECTEDno-saml-endpoint/cgi/samlauth 返回 404,因此此处不提供 SAML 断言消费者。按 vserver 而非按设备,参见局限性中的旧版本注意事项。
INCONCLUSIVEflat-response探测和同长度对照回答相同,因此回复不取决于发送的内容。误报防护触发。
INCONCLUSIVEgeneric-internal-error端点返回 43549,其通用内部错误,已修补和未修补版本都会返回。不是区分标志——并且注意它是无关的 CVE-2026-8452 的未修补标记,所以它看起来像命中但并非命中。
INCONCLUSIVEunrecognized-reply端点回答了识别集合之外的内容。
INCONCLUSIVEno-probe-response主机回答了识别但未回答探测——超时、重置或中间盒丢弃了 POST。请重试。
ERRORnot-identified未被识别为 NetScaler,或不可达。
  • 可达性。 结果反映设备向你运行它的网络位置暴露的内容。