上周,在2024年7月19日世界协调时0409分,著名的防病毒制造商CrowdStrike发布了其广泛使用的Falcon平台的更新,导致全球的Microsoft Windows机器发生崩溃。
影响范围极为广泛。供应链公司Interos估计,大约有674,620个CrowdStrike和Microsoft的直接企业客户关系受到影响。据Microsoft表示,有850万台Windows机器失败。这次事件除了造成大量的IT补救时间外,还引发了全球航班和航运的延误,这是由于广泛的Windows系统故障所造成的。
CrowdStrike至今透露的原因是:“一个逻辑错误导致受影响系统出现系统崩溃和蓝屏(BSOD)”。
此次崩溃源于可能被篡改的数据,这些数据不知何故进入了名为Channel File的Falcon配置文件中,该文件控制着CrowdStrike安全软件的工作方式。
Channel Files会随着时间由CrowdStrike更新,并推送到运行其软件的系统上。反过来,这些机器上的Falcon使用文件中的信息来检测和应对威胁。这是Falcon基于行为的机制的一部分,该机制识别、突出显示并阻止计算机上的恶意软件和其他不受欢迎的活动。
在这个案例中,数百万台运行Falcon的Windows电脑接收了一个配置文件,这个文件使安全软件如此困惑,以至于整个系统崩溃。当重启受影响的机器时,它几乎会立即启动Falcon,然后再次崩溃。
根据CrowdStrike的说法,Windows机器上的Channel Files存储在以下目录中:
C:\Windows\System32\drivers\CrowdStrike\
这些文件的命名规则以”C-“开头,后面跟着一个唯一的标识号。出问题的文件名以”C-00000291-“开头,后面跟着其他数字,并以.sys扩展名结尾。但CrowdStrike指出,这些并不是内核驱动程序;事实上,它们是供Falcon使用的数据文件,Falcon确实在驱动级别运行。
也就是说,损坏的配置文件不是驱动可执行文件,但它是由CrowdStrike高度信任的代码处理的,该代码被允许在操作系统上下文中运行,当坏文件导致这段代码出错时,它带下了整个周围的操作系统——在这个故事中就是Microsoft Windows。
“Channel File 291控制Falcon在Windows系统上评估命名管道执行的方式。命名管道用于Windows中的正常、进程间或系统间的通信。”CrowdStrike在其周末发布的技术摘要中解释道。
配置更新触发了一个逻辑错误,导致操作系统崩溃 “在04:09 UTC发生的更新旨在针对新观察到的、在网路攻击中由常见C2框架使用的恶意命名管道。配置更新触发了一个逻辑错误,导致操作系统崩溃。”
换言之,CrowdStrike发现恶意软件滥用Windows的一个名为命名管道的功能,以与该恶意软件的指挥和控制(C2)服务器进行通信,这些服务器通常指示恶意软件执行各种不良行为。CrowdStrike推送了一个配置文件更新以检测并阻止这种管道的滥用,但配置文件却弄巧成拙,破坏了Falcon。
尽管有人猜测错误是由于Channel File中包含空字节所致,但CrowdStrike坚称情况并非如此。
“这与Channel File 291或其他任何Channel File中包含的空字节无关。”这家网络安全公司表示,并承诺进行进一步的根本原因分析以确定逻辑缺陷是如何发生的。
具体导致错误的根本原因尚未正式披露——CrowdStrike的CEO乔治·科茨(George Kurtz)刚刚被要求就此事向国会作证——不过像Google Project Zero的泰维斯·奥曼迪(Tavis Ormandy)和Objective-See创始人帕特里克·沃德尔(Patrick Wardle)这样的安全专家令人信服地争辩说,冒犯性的Channel File以某种方式导致Falcon访问了不存在的信息,触发了崩溃。
看起来Falcon从内存中的一个表读取条目,并在循环中使用这些条目作为进一步工作的内存指针。当至少有一个条目因为配置文件而不正确或不存在,而是包含垃圾值时,内核级别的代码将这个垃圾视为有效值,从而尝试访问未映射的内存。
处理器和操作系统捕获了这个错误的访问,并引发蓝屏死机,因为在那个点上操作系统知道在非常低的层面发生了意外的事情。在这种情况下崩溃可能是更好的选择,而不是尝试继续运行并覆盖数据,造成更多的损害。
沃德尔告诉The Register,崩溃转储和反汇编清楚地表明崩溃起因于试图使用未初始化的数据作为指针——一个野指针,但更具体的细节仍然未知。
“但我们仍然不知道确切的原因,为什么Channel File会触发这一点,”他说。
The Register与网络安全资深人士Omkhar Arasaratnam交谈,他是OpenSSF的总经理,关于事情是如何出错的。
Arasaratnam说,确切的原因仍然是推测性的,因为他没有接触到CrowdStrike的源代码或Windows内核。
CrowdStrike的Falcon Sensor有两个组件:一个是名为CSAgent.sys的经过数字签名、微软批准的驱动程序,另一个是用于用最新的安全信息更新软件的Channel Files。
“CrowdStrike所做的基本上是他们有一个经过签名的驱动程序,然后加载了大量的这些通道配置,”Arasaratnam说。“我们不知道Channel配置文件到底包含什么。这是文件中所含内容以及CSAgent.sys如何解释它的结合。”
根据一个堆栈跟踪,他解释说,CSAgent.sys因执行所谓的坏指针解除引用而被终止。它试图从地址0x000000000000009c访问内存,但这个地址并不存在。
“那是它不应该访问的内存区域,”Arasaratnam说。
“现在,当你有一个像这样的低级程序时,你就会陷入两难境地,因为总体上内核应该负责操作系统做许多低级的事情,包括分配内存,”Arasaratnam说。
“所以如果内核实质上是在尝试访问它不应该访问的内存,那么从操作系统理论的角度来看,正确的做法是假设分配的所有内存都不安全,因为如果连内核都不知道,那谁会知道呢?基本上停止系统运行。”
你是否了解崩溃是如何发生的更多信息?你可以直接联系我们这里或按照这里的说明匿名联系。
Arasaratnam解释说,情况的复杂性还在于Windows驱动架构的工作方式。
“工作方式是驱动程序可以设置一个叫做boot-start的标志,”他说。
“通常,如果你有一个表现有点buggy的驱动程序,导致像这样的故障,Windows可以通过简单地下次不加载该驱动程序来自动恢复。但如果它被标记为boot-start,这应该是为关键驱动程序保留的,比如你的硬盘驱动程序,Windows就不会将其从启动序列中删除,会一次又一次地持续失败,这就是我们在CrowdStrike故障中看到的情况。”
(我们认为微软建议人们最多重启受影响的Azure Windows虚拟机15次来解决问题的原因是每次重启都有小概率自动更新到非破损的配置文件,然后在CSAgent.sys驱动开始解析之前。经过多次重启,你最终会赢得这个竞争条件。)
Arasaratnam说,除此之外,我们不会知道那个告诉CSAgent.sys进行错误指针解除引用的Channel File更新是如何通过质量保证(QA)的。
“鉴于崩溃发生的频率,很明显有些东西逃过了QA,”他说。“即使是最微不足道的QA也应该能抓住这个。这不是那种千分之一机器的边缘案例,对吧?”
Arasaratnam说,有几个最佳实践应该被遵循。一是如果可能的话,不要在内核模式下运行软件。第二,是要确保QA更为彻底。第三,是效仿Google的做法,部署增量Canary版本。
他解释说,“Google采用的一种技术,也是我以前在那里时我们采用的,叫做Canary版本——渐进或缓慢推出——并观察发生的情况,而不是让微软估计的850万台机器崩溃。”