分析背景
本案例的固件恶意模块是卡巴斯基从用户处收集的,属于卡巴斯基的客户数据,无法公开传播。作为安全研究人员的我们也没法获取到攻击样本,因此只能根据公开材料与相关的历史经验来进行推导感染过程与细节实现。与公开的UEFI Bootkit案例类似,该案例Bootkit也会通过设置多个hook,在整个启动阶段都能控制执行流,不至于引导过程切换时终止执行上下文而失去控制。通过对CosmicStrand UEFI Bootkit实现Bootkit植入与感染细节的分析与回顾,可以发现这与2013年QuarksLab的Sébastien Kaczmarek公开的Dreamboot Bootkit POC部分启动引导流程实现逻辑是一致的,本例通过对特定的固件镜像内嵌的CSMCORE模块进行补丁植入恶意代码并在后续启动引导过程中的借助层层劫持来实现Bootkit的感染植入。
在固件执行引导阶段时,第一次hook实现的原理大致为当被补丁的恶意模块CSMCORE通过执行位于重定位表节区的恶意代码时将在内存中通过索引对EFI_SYSTEM_TABLE的地址进行判断是否有效,接着定位到EFI_BOOT_SERVICES,再然后根据结构体偏移量0x98定位到HandleProtocol函数地址,在内存中对其进行修改实现hook,最终该函数的地址将位于攻击者提供的恶意代码地址。
通过对材料中指明的H81芯片组附带的固件的CSMCORE模块本地分析表明确实会使用HandleProtocol函数来调用EFI镜像加载协议,因此恶意代码会根据当前HandleProtocol函数被调用时的参数协议来判断当前Windows引导管理器(bootmgfw.efi)是否已经被加载进内存,如下可与卡巴斯基提供的部分截图信息进行比较。
当定位到Windows引导管理器(bootmgfw.efi)已经被加载进内存后,恶意代码会对bootmgfw.efi其中的Archpx64TransferTo64BitApplicationAsm函数植入hook,Archpx64TransferTo64BitApplicationAsm实质是一个关键函数,这在之前分析过的Bootkit中也涉及到会被植入hook来获取控制权。实现的具体细节为在被补丁后的Windows启动管理器二进制文件(bootmgfw.efi)被UEFI固件加载执行后找到已安装的操作系统并将执行转移到其操作系统引导加载程序winload.efi的过程中,Archpx64TransferTo64BitApplicationAsm函数会被winload.efi调用,因此控制流继续转移到winload.efi的执行流程。Archpx64TransferTo64BitApplicationAsm函数被植入的hook被触发执行过程中会通过搜索特定的字节数据在Windows内核加载程序ntoskrnl.exe中查找并定位OslArchTransferToKernel函数,在该函数的最后会植入第二个hook(添加68 00 E0 08 00 C3数据(指令为push 0x8E000 ret)),一旦调用OslArchTransferToKernel函数就会将执行流转移到hook的地址并执行,这与之前分析过的Bootkit控制流转移利用技巧是类似的。OslArchTransferToKernel函数在控制从操作系统引导加载器(winload.efi)转移到Windows内核加载程序ntoskrnl.exe时被调用,因此当操作系统内核镜像被映射到系统地址空间时,就会触发该hook来获取执行流控制权。
该处hook的逻辑是可以在内存中对Windows内核进行补丁,一旦Windows内核加载程序ntoskrnl.exe被操作系统引导加载程序winload.efi加载但被执行之前,CosmicStrand会利用之前植入的第二个hook将恶意代码复制到Windows内核加载程序ntoskrnl.exe的内存镜像区域的.text节区空闲区域,接着对内核函数ZwCreateSection起始部分植入补丁来跳转执行恶意代码再次获取执行流控制权。
植入的hook实现了禁止Windows提供的PatchGuard安全机制,具体细节为通过定位到Windows内核加载程序ntkrnlmp.exe的KiFilterFiberContext函数(可定位到受影响的版本为低于Windows 10内部版本14393,发布时间为2016年7月,在Windows10 1607之后,除了PatchGuard安全机制,微软再次推出HyperGuard安全机制,其利用CPU虚拟化支持并配合PatchGuard对内核层实施防护。由于硬件支持,HyperGuard并不需要像PG一样进行轮询检测。在攻击者补丁内核的一瞬间,HyperGuard就能感知到并且Crash系统。),这里补丁的作用是对其KeExpandKernelStackAndCallout函数内部执行过程中直接使rax为1达到完成调用后成功通过验证来禁用PatchGuard的目的。
结合特定版本的Windows内核加载程序ntkrnlmp.exe来得到具体实现细节如下:
hook植入完成后,等待Windows内核启动并执行ZwCreateSection函数会触发设置的hook,此时CosmicStrand再次获得执行流控制权,并在运行更多恶意代码之前恢复之前被植入hook的原始代码。最终ZwCreateSection函数植入的hook将实现获取内核提供的API函数的地址,并为下一个组件创建一个导入表,使用已解析的函数在内核的地址空间中分配一个缓冲区映射shellcode并最终调用,处于内核内存区域的shellcode会最终实现与C2的交互。
取证检测
在整个感染过程中,虽然对ZwCreateSection函数的hook在后续阶段进行了恢复,但是禁止PatchGuard安全机制时设置的hook并未恢复(因为PatchGuard将会周期性的检查系统),因此可以对Windows内核加载程序ntkrnlmp.exe检测内核钩子,针对之前将shellcode代码复制到.text节区空闲区域的操作,也可以进行相同版本环境下内存模块数据比对来找到可疑注入痕迹。本次UEFI Bootkit植入与感染并未涉及恶意驱动的内存加载执行,因此传统的Rootkit检测手段无法检测到恶意驱动,即使如MoonBounce UEFI Bootkit感染植入也无法去通过传统的检测手段发现恶意驱动程序,因此检测的重点应当放置在内存与流量中,最后才是针对固件镜像进行取证检测校验完整性。
参考链接
https://securelist.com/cosmicstrand-uefi-firmware-rootkit/106973/