首页
社区
课程
招聘
[原创]UEFI Bootkit源码分析
发表于: 2025-3-1 22:14 3462

[原创]UEFI Bootkit源码分析

2025-3-1 22:14
3462

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编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 3915
活跃值: (4182)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
感谢分享。
2025-3-5 09:32
0
游客
登录 | 注册 方可回帖
返回