(一)模块组成
感染过Sinowal的电脑,Sinaowal在硬盘中的分布例如以下图:
; Sector Offset Size Name
; ----------------------------------------------------------------------------------------------------------------------
; 0 0000h 512 Bootloader
; 60 7800h 512 Ntldr Hook Code
; 61 7A00h 512 Kernel Code
; 62 7C00h 512 Original Bootloader
(二)Bootloader 分析
(a) Bootloader 的主要功能。
首先将sinowal的其它部分读入内存。然后Hook int 13h ,最后将原始的BootLoader 载如内存 0x7c00处。运行原始代码。
内存映像为:
| 0x9f400 - 0x9f600 | 0x9f600 -0x9f800 | 0x9f800 -0x9fa00 |
; ----------------------------------------------------------------------------------------------------------------------
|Bootloader | Ntldr Hook Code | NtosHookCode |
(b)int 13hook 函数的运行逻辑
在读入的数据流中搜索特征码 8B F0 85 F6 74 21 80 3D 这段特征码相应的代码例如以下:
.text:00422A6A call _BlLoadBootDrivers@12 ; .text:00422A6F mov esi, eax 。8bf0 .text:00422A71 test esi, esi ;85f6 .text:00422A73 jz short loc_422A96 ;7421 .text:00422A75 cmp _BlRebootSystem, 0 ;80 3D F8 AE 43 00 00
![](file:///C:/Users/QUANJU~1/AppData/Local/Temp/ksohtml/wps_clip_image-6875.png)
定位到特征码后,进行第一次Hook 将8B F0 85 F6 74 21 的6个字节替换为ff 15 fc f5 09 00 即 call dword ptr [0x9f5fc], Hook后的代码例如以下:
.text:00422A6A call _BlLoadBootDrivers@12 .text:00422A6F call dword ptr [0x9f5fc] 。注:[0x9f5fc]保存的地址是 0x9f600,为Ntldr Hook Code .text:00422A75 cmp _BlRebootSystem, 0;
(三)Ntldr Hook Code 分析
(a) 保存现场环境
mov esi,eax test eax,eax pushf jnz Hook_Handler add [esp+4],dword 21h Hook_Handler: pushad mov edi,[esp+24h] and edi,0FFF00000h
*** *** ***
(b)搜索全局变量 BlLoaderBlock
将函数函数的返回地址按4kb对齐,然后在Ntldr代码区搜索特征码 C7 46 34 00 40 ,该特征码相应的代码为:
.text:00415914 mov dword ptr [esi+34h], 4000h 。 C7 46 34 00 40 .text:0041591B mov word ptr [esi+38h], 1 ; 66 C7 46 38 01 00 .text:00415921 mov eax, _BlLoaderBlock ; A1 C4 82 46 00 注 :C4 82 46 00 为地址部分
由此可定位到 BlLoaderBlock,其类型为PLOADER_PARAMETER_BLOCK,。在BlLoadBootDrivers调用以后,全部Boot型的驱动都会被 增加到内存中,相关信息,如地址,名称,大小等都会保存到链表 BlLoadBootDrivers中。
(c)定位系统初始化时IoInitSystem的调用点
依据上一步骤获取到的BlLoadBootDrivers可定位到NtosKernel的ImageBase 和SizeOfImage。然后搜获特征码6A 4B 6A 19 E8 * * * * E8 * * * *
此处相应的代码为:
INIT:005ACEC9 push 4Bh ;6a 4b INIT:005ACECB push 19h 。6a 19 INIT:005ACECD call _InbvSetProgressBarSubset@8 ; E8 ** INIT:005ACED2 push dword ptr [ebp-470h] INIT:005ACED8 call _IoInitSystem@4 ; E8 **
由此可搜索到IoInitSystem 将IoInitSystem地址 和 Ntoskenel 基址保存在 0x9f800 + 4 和 0x9f800 + 0xc处
将0x9f800 —0x9fa00处共512字节的代码挪至Ntoskenel 尾部(0x8068)
将 call _IoInitSystem@4 替换成 call 0x8068 完毕对NtOskernel的hook
(四)Kernel Code Hook
依据之前保存的Ntoskenel 基址,搜索到ExAllocatePool 申请一片内存(分页内存池和非分页内存池都已初始化完成)。将代码挪个窝
然后调用 原始IoInitSystem。调用完毕后,windows运行体函数大多能够使用了。
可搜索ZwCreateKey,ZwClose创建“RegistryMachineSystemBootKit”