0.介绍
Vector-EDK作为UEFI Bootkit的经典案例,在此对其进行分析。
源码在Github上可找到。
1.架构与感染过程分析
1.主架构:
NTFS 解析器(Ntfs.efi):一个DXE驱动程序,包含一个完整的NTFS解析器,用于读写操作。
Rootkit加载器(rkloader.efi):一个DXE驱动程序,它注册一个回调来拦截EFI_EVENT_ GROUP_READY_TO_BOOT事件(表示平台已经准备好执行操作系统引导加载程序),并在启动操作系统引导程序之前加载UEFI应用程序fsbg.efi。
Bootkit辅助程序(fsbg.efi):在UEFI将控制权传递给操作系统引导加载程序之前运行的 UEFI应用程序。它使用用Ntfs.efi解析主要Bootkit函数,并注入恶意软件。
2.感染过程分析
一个以Vector-edk为范本制作的感染概述图

在现在,绝大多数安全软件都只关注Ring0与Ring3,而对Ring-2很少关注,SPI读写漏洞一旦被利用,后果严重。
2.详细分析
1.Bootkit加载器:rkloader.efi
主函数_ModuleEntryPoint()
1
2
3
4
5
6
7
8
9
10
11
12
|
EFI_STATUS EFIAPI
_ModuleEntryPoint(FI_HANDLE ImageHandle,EFI_SYSTEM_TABLE * SystemTable)
{
EFI_EVENT Event;
DEBUG((EFI_D_INFO, "Running RK loader.\n" ));
InitializeLib(ImageHandle,SystemTable);
gReceived = FALSE; / / 重置
/ / 等待EFI_EVENT_ GROUP_READY_TO_BOOT事件
/ / 准备启动
gBootServices - >CreateEventEx( 0x200 , 0x10 ,&CallbackSMI,NULL,&SMBIOS_TABLE_GUID, &Event );
return EFI_SUCCESS;
|
在这之中,gBootServices为UEFI全局变量,该函数采用CreateEventEx函数创建回调,在收到EFI_EVENT_ GROUP_READY_TO_BOOT后执行CallbackSMI函数。
此事件发生在BIOS DXE阶段结束时,操作系统引导加载程序收到控制信号之前,允许fsbg.efi在操作系统之前接管执行。
在下面给出UEFI的原型函数的解释:
1
2
3
4
5
6
7
8
9
10
|
EFI_STATUS
EFIAPI
CreateEventEx (
IN UINT32 Type , / / 事件类型
IN EFI_TPL NotifyTpl, / / 回调的任务优先级(TPL)
IN EFI_EVENT_NOTIFY NotifyFunction, / / 回调函数指针
IN CONST VOID * NotifyContext, / / 传递给回调的上下文
IN CONST EFI_GUID * EventGroup, / / 事件组 GUID(可选)
OUT EFI_EVENT * Event / / 返回的事件句柄
);
|
NotifyTpl:0x10 对应 TPL_NOTIFY,属于高优先级。
重要的CallbackSMI()函数
这个函数很长,只截取部分分析
1
2
3
4
5
6
7
8
9
10
11
12
|
VOID EFIAPI
CallbackSMI (EFI_EVENT Event,VOID * Context){
/ / 略去部分
EFI_LOADED_IMAGE_PROTOCOL * LoadedImage;
EFI_FIRMWARE_VOLUME_PROTOCOL * FirmwareProtocol;
EFI_DEVICE_PATH_PROTOCOL * DevicePathProtocol,
* NewDevicePathProtocol,
* NewFilePathProtocol,
* NewDevicePathEnd;
return ;
}
|
首先,我们看到多个UEFI协议初始化,例如:
EFI_LOADED_IMAGE_PROTOCOL提供已加载UEFI程序的信息(映像基地址、映像大小和映像在UEFI固件中的位置)。
EFI_FIRMWARE_VOLUME_PROTOCOL提供从固件卷读取和写入固件卷的接口。
EFI_DEVICE_PATH_PROTOCOL提供一个接口,用于构建到设备的路径。
何为UEFI Protocol
一个 Protocol 是一个结构体,包含一组函数指针和数据字段,定义了如何访问某种硬件、服务或功能。类似于WinAPI,但又有不同,UEFI Driver通过 Protocol 实现模块化和重用。每个 Protocol 通过一个 GUID(全局唯一标识符)来区分。
多个EFI_DEVICE_PATH_PROTOCOL初始化开始后,我们可以看到许多变量名都以New作为前缀,这通常表明它们是钩子。命名规范就是好(^_^)。因此,NewProtocol相当于一个UEFI Hook。
具体的使用:
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!
最后于 2025-3-2 14:02
被TurkeybraNC编辑
,原因: