整体事件背景
北京时间2024年7月19日中午12:09时开始,全球多地用户开始反馈运行微软Windows操作系统的电脑出现蓝屏现象。据公开报道数据统计,截至目前,此次事件已导致全球范围内至少20多个国家的银行、航空、医疗等公司服务受到影响,全球超过21,000个航班延误,大量医院被迫推迟了手术,众多企业服务和公共服务都陷入瘫痪。从波及范围、受危害程度来看,此次事件带来的影响已远远超过了2007年赛门铁客导致的系统蓝屏事件,已成为近15年来,由安全产品自身导致的最大规模的灾难事件。
360能力中心在事件发生的第一时间就捕获到了蓝屏事故发生时所产生的Crash Dump文件,直接引发事故是“CSAgent.sys”驱动程序,该驱动程序属于美国网络安全公司CrowdStrike,是其Windows安全产品的核心内核驱动组件。
独家影响面分析
基于360部署于全球15亿终端的独家安全视野,我们对此次安全事件的影响面进行了统计分析。
从国内来看,受影响最大的城市为上海,其安装占比高达21.42%。受响应的城市具体如下:
从国外来看,欧洲、美洲相关国家为主要影响国,我们重点统计了在360终端视野下亚洲邻国的影响情况。具体如下:
技术细节还原
此次事件发生已过去了近2周,CrowdStrike公司、国内外其他安全厂商以及研究机构未给出详细的技术分析。360能力中心在事件发生后,利用全球的数据视野,获取了一手全面的信息,展开深入分析,还原整个事件细节。我们公开部分技术细节,为避免类似事故重演,促进国内安全产业发展,贡献微薄之力。
1.崩溃现场信息
在360安全大脑的全球视野下,我们观测到CrowdStrike探针的多个版本驱动程序均导致了崩溃。从监控到的崩溃数据来看,75% 的崩溃增量都集中CrowdStrike Windows 版探针7.15.18513.0 这个版本的偏移 0xe14ed 处。
但这次的崩溃在7.16.18605.0 甚至更新的版本都存在,可见并不是由于CSAgent.sys驱动文件本身升级造成的。
从 7.15.18513.0 相关的一份DUMP文件来看,崩溃的直接原因是在 CSAgent+0xe14ed 偏移处,产生了一个无效地址访问,可以看到此时 r8 寄存器指向的内存已经无效。
通过阅读CSAgent(7.15.18513.0)+0xe14ed 偏移处的反汇编代码,如下图所示。
可以看到,其上一条指令就是判断r8 指向的地址是否为空,这个蓝屏的直接原因其实是由于`mov r8 qword[rax+r11*8]` 造成的索引越界访问(OOB Read)。
2.CrowdStrike 目录介绍
CrowdStrike 的文件主要在 `C:\Program Files\CrowdStrike` 和 `C:\Windows\System32\drivers\CrowdStrike` 这两个目录下。其中 `C:\Program Files\CrowdStrike` 包含的是用户态组件、后台服务、扫描工具和托盘组件。
在 `\SystemRoot\Drivers\CrowdeStrike` 目录下,包含的是CrowdeStrike的内核驱动和规则文件。
3.核心组件分析
CSAgent.sys 是 CrowdStrike Windows 版探针的核心组件,本身是一个非常庞大的驱动,可以视为多个防护驱动的集合体。以 7.16.18605.0 版本为例,编译后的文件体积达到了 4.28 MB , IDAPro 自动识别出了10816 个函数,其功能复杂性可见一斑。其主要功能包括:
(1) 实现了基于自定义虚拟机的规则引擎;
(2) 基于kernel socket 的内核网络通信;
(3) 实现了常用 TLS 协议的加密算法;
(4) 在 2和3 的基础上,实现了完整的 HTTPS 协议通信;
(5) 实现了HTTP 代理协议;
(6) 实现了完整的 X509证书格式解析;
(7) 实现了联网查询证书吊销列表以检证书和CA有效性;
(8) 实现了基于 minifilter 的文件过滤,本次蓝屏的 291规则就是为了处理命名管道的事件;
(9) 实现了基于 WFP 的网络事件过滤 , DNS 重定向和 RPC 拦截;
(10) 在内核中,创建了 15 个基于 iocp 的队列,来实现事件的异步处理;
(11) 实现了基于 ETW 、WMI 、Clfs的3套trace 机制,并支持 HTTPS传输遥测日志;
(12) 实现了基于CPU性能计数器的性能监控。
4.内核动态加载驱动
`CSAgent.sys` 调用了 `nt!ZwSetSystemInformation` 来实现内核加载、卸载驱动的能力。
值得说明的是,在`CSAgent.sys`中对` nt!ZwSetSystemInformation` 的使用一共有两处。虽然都是加载到了内核,但目的有所不同。
在 ` csagent+0x5a468` 中是为了动态加载新的功能模块,加载之后直接调用被加载模块的`DriverEntry`。而对于`Osfm-00000001.bin` 等文件,虽然也是加载到内核,但并不调用其入口点,而是把入口处的内容当作规则数据来解析,在后文中有详细解释其格式。
5.固件检查
Osfm 表示 operating system firmware ,以 `Osfm-%08U.bin` 的格式作为文件名 ,其中 Osfm 表示 operating system firmware 。描述了需要检查的关键文件 (也就是 CrowdStrike 所说的固件 )的路径。
虽然该文件看似是数据配置文件,但使用二进制编辑器打开之后可以看出是一个 PE 文件。
通过后续分析,发现驱动入口点的内容又是规则数据。CrowdStrike 的开发者的作法很有意思:看似是驱动,实际上是规则,比如 `C-00000001-00000000-00000025.sys`;看似是数据文件,实际上是驱动,比如 `Osfm-00000001.bin`。其格式如下:
Osfm 文件的主体是一个标准的PE 文件,只是 OEP指向的地方并不是代码而是规则数据。
(1) 规则头中 `string_count` 表示附属的字符串表中字符串的个数;
(2) 规则体中的 `string_array` 表示字符串表的位置。注意这里的 `string_array` 在文件中的值并不是文件偏移,而是虚拟地址。
在加载到内存中之后,由于重定位表的存在,会被Image Loader自动修正成实际地址。在文件中解析时,只需要按 RVA2FOA 计算其实际的文件偏移即可。字符串表中的每一个元素也是虚拟地址,计算实际的文件偏移可以读取得到实际的字符串。每一个字符串都是需要检查的关键文件的路径。
`CSAgent.sys` 会自动查找CrowdStrike 目录下最新的 ` Osfm-*.bin` 文件,并按 ` OSFM-%08u.bin` 格式读取其版本信息,加载最新的那一份,并自动删除上次修改时间为1天前的老文件。
6.重点文件分析(C-%08U-%08U-%08U.sys 文件格式)
以 `C-00000001-00000000-00000025.sys` 命名的文件,虽然有 `.sys` 扩展名,但其实并不是内核驱动文件,而是 `CSAgent.sys` 用到规则文件 。如图所示,并没有可执行文件所需的 MZ 和 PE 头。
其文件格式分为 三层,第一层是固定的文件头,格式如下。
其中 `magic` 固定是 `0xAAAAAAA` , `channel` , `part2` , `part3` 就是 `C-00000291-00000000-00000009` 中的3个数字,表示应用的频道和版本,`kind` 是规则的子类型。
第二层的格式就是文件跳过第一层文件头的剩余部分。规则的第二层格式是分块的,每个块头占 8 字节。文件格式和内存格式,共享同一个数据结构。
在文件中时,块头的`next_block_data_offset` 表示下一个块的偏移,`block_size` 是当前块的总大小 , 如果 ` block_size ` 是 0 ,表示这是最后一个块。当前块的数据区域包含的大小需要是 ` nBlockSize` 减去 8 字节,也就是块头的大小。在加载到内存中之后,块头的8字节会被修改成直接指向下一个块数据区的指针,刚好组成一个单向链表。第3层的格式就建立在这个逻辑上连续的单链表之上。
第三层的格式,根据第一层文件头中规则子类型的不同而不同,包含的是实际的规则数据。
除了从文件加载规则以外,`CSAgent.sys`也会从注册表读写规则数据。比如在 `CSAgent.sys` 下载得到新的设备管控规则文件,并读取解析之后,会把去除第一层规则头之后的规则数据重新写入注册表,然后再次从注册表里读取出,进行剩余的解析。这里为什么要写一次注册表,目测是为了系统重启时,能被设备管控`CSDeviceControl.sys` 用到。
我们重新审视了蓝屏的原因,`CSAgent.sys` 实现了自定义的虚拟机引擎,类似Linux内核的ebpf , 其入口为 `CSAgent+0xbfd48` 。在各个渠道加载得到的规则的第三层的规则数据,除了必要的头,主体就是要执行的虚拟 bytecode。
在分析完规则格式和虚拟机指令之后,就能理解蓝屏点 `CSAgent+0xe3b58` 到底是在做什么了。蓝屏时的处理,其实就是在解释执行`C-00000291-00000000-00000009.sys` 中包含的错误 opcode。
重新审视蓝屏原因
值得一提的,最近国外网站上流传着一种分析论调,认为此次事件只是一个零地址访问造成的拒绝服务。该分析收到了数十万的关注与评论,但这种说法实际上是不对的。
通过360团队分析,造成蓝屏的直接原因实际上是 opcode 校验时的 OOB Read ,虽然看起来这里并不能直接控制内存,但是 `CSAgent.sys` 的这个虚拟机引擎,实际上是图灵完全的,是可以像 Dequ 病毒利用 atmfd.dll 里的字体虚拟机一样,配合特定的利用技巧,实现完全控制外部(即操作系统内核)的内存,进而获得代码执行权限。所以,我们深入分析之后,发现这里其实是满足了LPE 或者 RCE 漏洞的条件。
(1)其输入内容来源是 `C-00000291-00000000-00000009.sys` 文件,且没有签名机制;
(2)`CrowdStrike` 缺乏自我保护机制,可以任意读写 `C-00000291-00000000-00000009.sys` 文件;
(3)`C-00000291-00000000-00000009.sys` 本身又是直接由 `CSAgent.sys` 直接从网络下载的;
(4)`CSAgent.sys` 支持从 IE AutoProxy 读取代理出网。
所以如果有网关权限,或者修改了IE 的代理设置,劫持了 `C-00000291-00000000-00000009.sys` 的分发,是可以拿到主机内核权限的,进而造成更深入的危害。