CitrixBleed到无限远:CitrixNetScaler又爆内存越界读取(CVE-2026-8451)"

admin 2026-10-21 22:02:37 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

cover_image

CitrixBleed 到无限远:Citrix NetScaler 又爆内存越界读取(CVE-2026-8451)

幻泉之洲

2026年7月2日 09:32
北京

在小说阅读器读本章

去阅读

Citrix NetScaler 再次因为内存泄露漏洞被推到聚光灯下。watchTowr 实验室在分析 CVE-2026-3055 时意外撞上了这个全新的零日漏洞,编号 CVE-2026-8451。它的成因依然是 SAML IdP 模块中自制 XML 解析器的边界检查缺失,攻击者无需认证就能从设备内存中窃取数据,甚至轻松导致系统崩溃。本文拆解了漏洞的发现过程、解析器的诡异逻辑,以及漏洞利用的完整链条,看完你会对“安全设计承诺”这几个字有新的理解。

又双叒叕是你,CitrixBleed

每次看到“Citrix NetScaler”这个词,我的胃就开始条件反射地抽搐。不是因为它有多难用,而是围绕这坨设备的漏洞,我们已经写了太多篇文章,做了太多表情包,以至于那枚象征着“安全设计”的承诺戒指都快被我们玩坏了。

如果你是新加入这场集体治疗的朋友,先补几篇旧文感受一下氛围:

  • 我们还要流多少血?——Citrix NetScaler 内存泄露 (CitrixBleed 2 CVE-2025-5777)[1]
  • 这是 CitrixBleed4 吗?不是。那它好吗?也不好。(Citrix NetScaler 内存泄漏 & RXSS CVE-2025-12101)[2]
  • 续集从来都不好看,但我们依然痛苦 (Citrix NetScaler CVE-2026-3055 内存越界读取)[3]
  • 求求了,就一个周末让我们远离网络设备吧 (Citrix NetScaler CVE-2026-3055 内存越界读取 Part 2)[4]

今天我们又要添一篇了。Citric 在 2026 年 6 月 30 日公开了我们 3 月报告的一个零日内存泄露漏洞,编号 CVE-2026-8451。我们连编号都懒得再记了,干脆叫它“CitrixBleed To Infinity And Beyond(飞向无限远)”。

我们在之前的文章里反复说过:NetScaler 的内存管理脆弱得就像纸糊的一样,哪怕只是“不小心配错”几个参数,都能把内存里的东西漏出来。这就像一个高度敏感的枪被大家抛来抛去,不断伤及无辜——而它偏偏是无数企业网络的关键“安全设备”。

NetScaler 是什么,以及它为什么让你头疼

Citrix NetScaler(经历过改品牌名又改回来的经典企业级操作)是一系列应用交付控制器和 VPN 网关设备,几乎每个大型企业网络里都能看到它。它负责负载均衡、SSL 卸载、身份认证、远程接入,而 NetScaler Gateway 更是成千上万组织远程办公的“大门”。你可以把它理解成那种我们既喜欢研究、又每次都能挖出“自然灾害”级别漏洞的产品。

CVE-2026-8451 是什么

Citrix 官方的描述简洁得像在写推特:输入验证不足导致内存越界读取。CVSS 评分 8.8。要触发这个漏洞,NetScaler 必须配置为 SAML IDP——这和之前某些 CitrixBleed 变体的前置条件一样。受影响版本如下:

  • NetScaler ADC 和 NetScaler Gateway 14.1 低于 14.1-72.61
  • NetScaler ADC 和 NetScaler Gateway 13.1 低于 13.1-63.18
  • NetScaler ADC FIPS 低于 14.1-72.61 FIPS
  • NetScaler ADC FIPS 和 NDcPP 低于 13.1-37.272

漏洞狩猎:在 NetScaler 的草丛里抓稀有宝可梦

时间回到 2026 年 3 月,我们正埋头复现 CitrixBleed4(CVE-2026-3055),分析 NetScaler 作为 IdP 时的补丁变化。说实话,SAML 本身的攻击面并不大,就那几个认证端点。所以很自然地,我们从 /saml/login 开始下手。

熟悉 SAML 的人都知道,客户端会提交一段 base64 编码的 XML 文档,里面包含 AuthnRequest,描述着 Issuer、Destination、时间戳等一堆属性。我们决定就盯着这块解析逻辑看。

自己造轮子的 XML 解析器,一塌糊涂

但凡有点漏洞挖掘经验的人都明白,XML 解析器极难写对。哪怕是有经验的开发者,也宁可依赖久经考验的库,而不是自己折腾。但 Citrix 显然走了另一条路——他们坚持要“手搓”一个解析器,也许是为了体现对安全设计承诺的“忠诚”。

我们扒出来的解析代码长这样(负责处理像 foo=\"bar\" 这样的 XML 属性):

cursor =

whitespaceCharList = 0x100002600;

// 跳过前导空白
for ( lookahead = (v32 + 28); ; lookahead++ )
{
ch = \cursor;
if ( ch > '=' )
break;
if ( !\_bittest64(&whitespaceCharList, ch) )
{
if ( ch == '=' )
{
while ( 1 )
{
ch = \
lookahead;
if ( ch > 0x20 || !\_bittest64(&whitespaceCharList, ch) )
break;
++lookahead;
}
cursor = lookahead;
}
break;
}
++cursor;
}

// 确定值的引号类型,支持单引号、双引号或不加引号
if ( ch == '\'' || ch == '\"' )
{
terminator = ch;
first = \*++cursor;
}
else
{
terminator = ' ';
first = ch;
}
if ( first == terminator )
return 0xE0002; // 值为空

// 向前扫描直到找到终止符
scanPos = cursor;
while ( first != '\0' && first != '>' )
{
scanPos++;
first = \*scanPos;
if (first == terminator)
break
}

if ( scanPos == cursor )
return 0xE0002; // 值为空

out->value\_ptr = cursor;
out->value\_len = scanPos - cursor;

你看,_bittest64() 这个调用看起来有点怪,但它其实就是在查一个预定义的字符位图,匹配水平制表、换行、回车和空格。ASCII 值范围是 0-255,而位图只有 64 位宽,所以那个 > 0x20 的检查是为了防止越界。乍一看功能挺清晰:定位属性值并返回指针和长度。

但问题也很明显:没有任何显式的边界检查。如果输入格式错误,解析器完全可能读过输入缓冲区的末尾。比如,一个属性值永远没有终止符会怎样?更诡异的是,不加引号的属性值终止逻辑与加引号的不同——对于非引号值,空格不再是终止符,只有遇到 null 字节、闭合的 > 或者匹配的引号才停止。这个差异听起来不起眼,实际上要了老命。

用换行符戏弄解析器

我们先构造一个简单的 SAML AuthnRequest 作为基准,然后开始搞破坏。首先,把 AssertionConsumerServiceURL 后面的空格换成换行符:

watchtowr

base64 编码后发给 /saml/login,HTTP 响应没什么特别的,但日志直接出卖了它:属性值读到的内容已经超出了原本的边界,甚至把后续的 XML 数据都吞了进来。

再进一步,我们把 AssertionConsumerServiceURL 和 ID 都用换行终止,并且干脆让 AuthnRequest 的开始标签不闭合,就得到了这个请求:

id=
watchtowr

日志显示,解析器在找 ID 的属性值时,一直读到了 Issuer 标签里的 watchtowr。这已经明确是个越界读取了。

泄露的数据去了哪里?

答案藏在服务器返回的 NSC_TASS cookie 里。这个 cookie 会包含从 XML 中解析出来的 ID 和 AssertionConsumerServiceURL 值。我们用之前的请求一试,cookie 解码出来果然带着多余的字符串片段。

更致命的是,我们发现解析器对 XML 元素的嵌套顺序和标签闭合都异常宽容。即使把 Issuer 放到 AuthnRequest 外面,只要开始标签没正确闭合,解析器照样接受。这让构造利用请求变得非常灵活:我们可以在 AuthnRequest 标签里留下一个带引号的假属性(比如 id=\"11\"),然后真正的 AssertionConsumerServiceURL= 不带值且不闭合,迫使解析器一路读到缓冲区的尽头,把后面堆里的任意二进制数据都当成属性值的一部分。

我们试了一发,日志里直接出现了十六进制垃圾:OH HO HO。解码 cookie 后,除了预期的 XML 片段,还跟出了几个字节的堆数据——看起来像是某种指针。

不止是泄露,还能崩坏

漏洞的实际利用价值分两层。首先,信息泄露本身就很要命。我们通过调节请求长度,稳定地每次从服务器内存里捞出几个字节:

Leaked bytes:
00000000  f0 0d 90 de de de de de de de de de de de de de   |................|
00000010  de de de de de de de de de de de de de de de de   |................|
...
00000050  0c a1 35 00                                       |..5.|

里面出现了 0xf00d 和类似数据指针的东西。如果那个指针是有效的进程地址,那这个漏洞就从一个简单的信息泄露升级成了真正的内存读取原语。再搭配一个内存破坏漏洞,整个设备就可能被完全控制。

退一步讲,即使不搞什么利用链,单靠这种越界读取也很容易把服务器搞挂。说到底,一个企业级安全设备,居然连这种简单的畸形请求都扛不住。

漏洞时间线

日期 事件
2026年3月28日 watchTowr 发现漏洞,通知 Citrix 及受影响客户
2026年3月28日 Citrix 回复,看起来像自动应答
2026年4月30日 watchTowr 要求更新进展
2026年5月7日 watchTowr 再次要求更新
2026年5月7日 Citrix 告知补丁正在开发
2026年6月14日 Citrix 预计 6月29日发布
2026年6月25日 Citrix 称补丁可能延期几天;watchTowr 表示可以接受
2026年6月30日 Citrix 发布公告和补丁
2026年6月30日 watchTowr 发布研究报告和表情包

这次漏洞从发现到公开,前后拖了三个多月。虽然中间有沟通拉扯,但好在比某些厂商动辄半年的响应速度要强。当然,考虑到这已经是同类问题的第 N 次重演,所谓的“安全设计承诺”大概也只剩下一枚生锈的戒指了。

watchTowr 实验室的这项研究,背后是 watchTowr 平台[5]提供的能力——一个结合了外部攻击面管理和持续自动化红队演练的解决方案。与其等扫描器厂商的下一个“令人满意”的公告,不如主动看看攻击者究竟在利用什么。


参考资料

[1] https://labs.watchtowr.com/how-much-more-must-we-bleed-citrix-netscaler-memory-disclosure-citrixbleed-2-cve-2025-5777/

[2] https://labs.watchtowr.com/is-it-citrixbleed4-well-no-is-it-good-also-no-citrix-netscalers-memory-leak-rxss-cve-2025-12101/

[3] https://labs.watchtowr.com/please-we-beg-just-one-weekend-free-of-appliances-citrix-netscaler-cve-2026-3055-memory-overread-part-2/

[4] https://labs.watchtowr.com/the-sequels-are-never-as-good-but-were-still-in-pain-citrix-netscaler-cve-2026-3055-memory-overread/

[5] https://watchtowr.com/

[6] https://labs.watchtowr.com/citrixbleed-to-infinity-and-beyond-citrix-netscaler-pre-auth-memory-overread-cve-2026-8451/


安全快报|印度政府和水利发电部门遭网络间谍组织部署恶意软件窃取情报" 网络安全文章

安全快报|印度政府和水利发电部门遭网络间谍组织部署恶意软件窃取情报"

本周安全快报汇总了多起网络攻击事件,包括MustangPanda针对印度政府和水利部门的间谍活动、Gamaredon对乌克兰的持续钓鱼攻击、FBI警告的Signal账户钓鱼、GhostShell对乌克兰无人机领域的攻击、SharkLoader恶意软件针对多国政府组织的攻击、NoName057(16)对加拿大水利系统的入侵、针对酒店餐饮行业的钓鱼邮件以及美敦力数据泄露。这些事件凸显了APT组织利用恶意软件、钓鱼邮件和社会工程学手段窃取情报与数据的持续威胁。
评论:0   参与:  0