CrowdStrike宕机由21对20字段数不匹配引发。Kestrel在设备重启前通过代码严格验证。
CrowdStrike端点安全IT 韧性

CrowdStrike崩溃根源于字段计数:内核预期20个却来了21个。没有任何独立层在把关。

Ashutosh SinghalAshutosh Singhal2026年7月20日11 min

2024年7月19日,单次供应商更新在不到90分钟内导致数百万台Windows设备崩溃,而罪魁祸首仅仅是一个数字。CrowdStrike的一个“Rapid Response Content”通道文件声明了21个字段,而部署的内核解释器预期的却是20个。这个多出来的字段引发了越界读取(out-of-bounds read),导致瞬间蓝屏。又因为崩溃发生在启动的最早期阶段,崩溃的代理程序根本无法重新启动以接收回滚指令。恢复意味着必须亲自走到每一台机器面前,在安全模式(Safe Mode)下手动作出修复。

在真正想通困扰我的根源之前,我把CrowdStrike在当年8月发布的根本原因分析(RCA)读了不止一遍。这不是黑客攻击。也不是有缺陷的模型。这是一个确凿无疑的可判定算术事实——21对20,深藏在一个从未经过任何独立层验证就直接进入生产环境的有效载荷中。供应商的验证器批准了它。那些陷入瘫痪的企业并未拥有那个验证器。它们拥有的只有随之而来的严重后果。

我把最近的一段时间用来围绕这个缺口构建一个演示系统:一个我命名为Kestrel的控制台,它坐落在软件供应商与生产集群之间,通过代码裁定供应商被允许发布什么内容。您可以在以下地址查看其工作原理:veriprajna.com/demos/software-update-integrity。在构建过程中让我感到惊讶的是解决方案最终所在的位置。我一开始深信自己需要一个更聪明的模型,然而最先捕获崩溃的却是几行朴素的Python代码。

我重构了崩溃场景,然后让代码做出裁定

我将7月19日的故障特征重构成一个测试夹具(fixture),并将我自己的系统对准它,心里甚至做好了在自己的重放中大失所望的准备。该软件包是C-00000291,来自我虚构的名为SentinelEdge的供应商的Rapid Response Content通道文件,被推送到我命名为Acme Financial的合成8500个端点的集群中。这些都不是真实的公司。但故障特征完全是真实的:声明的模式字段从20个暴增到21个,并在没有金丝雀计划的情况下以单一波次推送到100%的集群。

门控同时触发四项检查,每一项都是纯粹的算术或直接查表,绝非主观判断。模式差异检测器发现解释器预期20个字段而实际提供了21个,并标记越界读取。模拟沙箱是一个确定性的各配置文件结果模型,而非真实的Windows虚拟机集群,它使集群6个配置文件中的5个在重启周期中陷入循环重启。它是从独立于模式检查的驱动程序兼容性信号中推导出这一点的,因此两项结论是相互印证而非简单重复。死亡代理检测器将回滚循环标记为true,因为崩溃的代理本身就是接收回滚指令的主体,而它在启动完成前就已经死亡。爆炸半径相对于5%的金丝雀策略达到了100%。裁定:BLOCK。屏幕上显示:在任何生产端点重启之前已拦截。

Kestrel控制台显示针对供应商SentinelEdge的C-00000291的Block Rollout面板,包含四个确定性证明、一个8500端点的集群以及估计5,000,000美元的避免停机损失。
C-00000291,7月19日特征重放。门控触发全部四项检查:模式字段计数不匹配(预期20,提供21)、5/6配置文件的沙箱循环重启、死亡代理回滚循环以及相对于5%金丝雀策略的100%爆炸半径。裁定BLOCK,估计避免停机损失5,000,000美元。

仅这一次更新估计避免的停机损失就显示为5,000,000美元,我想明确说明这个数字到底是什么。它是演示系统自身的内建模型:受影响比例乘以每小时500万美元的输入参数,再乘以一小时的最低恢复基准时间,公式直接打印在屏幕上。这不是客户实际节省下来的资金。7月19日的真实恢复耗时数天而非一小时,因此该基准是刻意保持保守的。

绿色通行案例比红色拦截案例更让我警惕

相比红色拦截案例,我对绿色通行案例更加感到紧张,因为一个既拦截危险更新同时也扼杀安全更新的治理层,不过是你为自己提前安排的一次服务中断。同一家虚构供应商推送了RRC-7741,这是一个良性的检测特征更新,声明模式为20对20,并附带分阶段的1.2%金丝雀计划。代理团队运行,模式匹配,6个配置文件中有5个顺利通过重启周期,死亡代理循环为false,爆炸半径处于策略允许范围内。裁定:APPROVE ROLLOUT,发布给102个端点的金丝雀环。绿色、迅速、平稳无波澜。

Kestrel控制台显示针对发布至1.2%金丝雀环的RRC-7741的绿色Approve Rollout面板,附带7/7评估追踪和证据记录。
同一家供应商的良性更新RRC-7741。模式匹配,5/6配置文件通过重启周期,死亡代理循环为false,爆炸半径1.2%符合策略。裁定APPROVE ROLLOUT,发布给102端点金丝雀环,证据记录sha256:798431b4c96612a9。

在该集合中的六次良性更新中,门控产生了零次错误拦截。我之所以把分母完整列出,是因为六个就是六个,我绝不允许将它夸大为您整个集群的万能保证。ALLOW案例的价值比单纯的百分比更加具体且更加重要。一个门控唯有在日常流量中保持无形,而在可能摧毁您集群的唯一关头坚如磐石,它才是值得信赖的。

为什么我将裁定权从模型中剥离

在构建之初,我假定最困难的部分是逻辑推理,并且认为更敏锐的模型或更聪明的批评者会是捕获错误更新的关键。我错了,而且我花了一段时间才坦然承认这一点。Kestrel内部确实有一组LLM团队:一个规范化器、一个沙箱解释器以及两个针锋相对的批评者,一个主张更新可以安全发布,另一个则力陈其会导致崩溃。这对对抗性组合之所以有其立足之地,是因为它在做出任何决定之前从正反两个方向对裁定进行红队检验。但是,这些代理中没有一个能够敲定最终裁定。

最终裁定由两个纯Python文件做出:verifier.pygate.py,它们完全位于智能体框架之外。运行团队基于Pydantic AI构建,默认模型为claude-opus-4-8,整个系统还可通过确定性建议回退机制在无API密钥的情况下离线运行。在所有这些模式下,门控都是完全相同的,并且返回完全相同的决定,因为这项决定是算术计算,而不是概率推理。代理提供建议,代码做出裁决。一个倾向于“允许”的建议代理无法抹去一项严重的确定性检测发现,这绝非个人喜好问题。

一个旨在审查供应商的防护层,绝不能在安全性上轻信供应商的一面之词。它同样不能轻信自身模型的一面之词。

这句话正是该架构呈现当前形态的根本原因。对于一个唯一职责就是治理供应商交付物的系统而言,对其信任绝不能通过任何可能被说服从而妥协说“是”的组件来维系。

我准备呈交给审计员的材料

在构建证据记录的同时,我始终在第二台显示器上打开着欧盟《网络弹性法案》(CRA),因为那份记录才是我真正需要捍卫的合规成果。每一次裁决都会导出一个不可变的HTML文件和一个包含SHA-256内容哈希的已签名JSON文件,其中记录了裁定结果、确定性证明、各配置文件沙箱结果、带有模型ID的建议代理裁定、触发的策略规则,以及记录了每一步延迟的逐步骤评估追踪。

针对被拦截的C-00000291的Kestrel裁决视图,显示带有sha256:0f4f71b2bd7d1753的证据记录,以及打开HTML记录和已签名JSON的按钮。
针对被拦截更新导出的证据记录。包含SHA-256内容哈希、可打开的HTML记录和已签名JSON文件,直接在裁决产生时生成。

追踪记录是我在点击查看具体步骤之前一直低估的部分。其中一个事件记录道:“规范化已签名的供应商清单,用时184毫秒完成”,并与裁决结果一同保留以供审计核查。每一个步骤都是可重新推导的。监管机构无需盲目信任我的仪表盘。他们可以重新运行算术验证并得出完全相同的结论。

Kestrel评估追踪步骤弹窗,显示“规范化已签名的供应商清单,用时184毫秒完成”,并注明该事件已被保留以供审计核查。
评估追踪的一个展开步骤:规范化已签名的供应商清单,用时184毫秒完成,与裁决输出一同保存供审计复核。

我对什么是签名、什么不是签名保持着严谨的态度。它是本地的SHA-256哈希,而不是企业级PKI体系。供应商更新源及其背后的ITSM工单是测试桩,而不是实时连接器。这份记录旨在契合申报合规需求:CRA的短周期事件通报机制、SEC关于重大网络安全事件4个工作日内披露的要求,以及2025年富尔顿县Delta诉CrowdStrike一案中引发的供应商法律责任问题。仅仅是“旨在契合”,它不为任何人背书,也不构成法律建议,任何向您兜售声称能让您合规的审计日志的人,都只不过是在向您推销商品。

还有一个令我引以为傲的决定,那就是一次“拒绝”。测试夹具XX-0000是一个门控无法解析的加密专有内容二进制块(blob),因此门控绝不妄加猜测。它返回ABSTAIN(弃权)并转交人工处理,因为一个给它读不懂的内容放行的门控,比完全没有门控还要危险。沙箱无法建模的遗留主机都会被标记并排除在外,绝不预设其为安全。词汇表仅有四个词:ALLOW、HOLD、BLOCK、ABSTAIN,而最后一个正是我会竭力捍卫的词汇。

12个中的12个真正允许代表的意义

在这个节点上我必须放慢语速,因为这正是创始人们最容易开始顺水推舟四舍五入夸大成效的地方。而我把公司命名为Veriprajna——意为真正的智慧,因此夸大其词是绝不允许的。在包含十二项更新的固定标注测试集中,门控在全部十二项上都做出了正确的决定。其中六项是良性的,门控没有拦截其中任何一项。有一项是坦诚的ABSTAIN。计分板上清晰地写着:12/12项经过验证的决定,0/6项错误拦截,整个集合避免的潜在停机损失估计达1330万美元,其中500万美元来自单一的CrowdStrike级别拦截。

Kestrel基准测试面板显示在标注发布测试集上的12/12项已验证决定、0/6项误报拦截和1330万美元的规避风险暴露额。
标注测试集上的价值计分板:12/12项验证决定,良性更新上0/6项误报,整个集合估计避免1330万美元停机损失。特意明确标注较小分母。

现在来到我坚决拒绝简化的部分。这些只是十二个标注项目上的测试结果,绝非对进入您集群的下一次更新的保证承诺。六个良性项目就是六个。这并不意味着“拦截100%的不良更新”,过去不是,将来也永远不会是。如果您抓到我写下这样的话,您就应当停止阅读我的文章。我所坚持保证的数字是另一种性质:相同的输入,相同的决定,每次运行皆然,因为裁决过程不包含任何模型温度。明天再次运行测试集,它将返回逐字节完全相同的结果。这正是让确定性防御层能够以概率层无法实现的方式接受严格审计的核心所在。

留给我的深思之问

在这次开发历程中始终萦绕在我心头的是,那次故障是何等的寻常普通。预期20个字段的地方出现了21个。只要在供应商和集群之间存在一个独立的验证者,任何独立的验证机制都本可以在任何一台设备重启前通过算术计算将其拦截。但是当时没有。而在今天,绝大多数情况下依然没有。

每家企业都在运行着8到12个来自其无法控制的供应商的内核特权代理,每个代理都能把文件直接写入ring 0内核层。SBOM工具监控开源依赖项。身份系统监控访问权限。却没有任何人在供应商专有更新进门时对其进行读取并证明其安全性。Kestrel不是EDR,也绝不触碰内核。它坐落在这些代理之上,统领管辖它们被允许交付的内容。这正是我试图构建的防御层,完整解析请访问:veriprajna.com/demos/software-update-integrity

如果您宁愿亲眼目睹其实际运行也不愿只读我的文字描述,这里有整个系统端到端完整运行的全貌。

因此,这就是我如今对所见到的每一个生产集群提出的质问:当下一次供应商更新到来时,在那份文件与生产环境之间究竟矗立着什么,它能否出示令人信服的工作证据?如果答案是一个盲目信任供应商的变更咨询委员会(CAB),那么那套击垮数百万台机器的算术错误就依然在毫无约束地潜伏运行。它不会预先通知。在重启的那一刻到来之前,它看起来将与此前到来的每一次正常更新完全一模一样。

相关研究

同步发布于

满怀信心地构建您的 AI。

与一支在打造新一代企业级 AI 方面拥有深厚经验的团队携手合作。让我们助您设计、构建并部署一套值得信赖的 AI 战略。

Veriprajna 深度科技咨询公司 专注于为医疗健康、金融和监管等领域构建安全攸关的 AI 系统。我们的架构均依据成熟的规范进行验证,并配有完善的合规文档。