基于MBR逆向分析工程实验报告
电子科技大学
信息与软件工程学院 逆向工程
实
验
报
告
姓
名:XXX
学
号:201852090710
指导教师:何兴高
一、题目 基于 MBR 的 Bootkit 的逆向分析 二、题目梗概
利用逆向工程技术,从可运行的程序系统出发,运用解密、反汇编、系统分析、程序理解等多种计算机技术,对软件的结构、流程、算法、代码等进行逆向拆解和分析,推导出软件产品的源代码、设计原理、结构、算法、处理过程、运行方法及相关文档等。随着用户需求的复杂度越来越高,软件开发难度不断上升,快速高效地软件开发已成为项目成败的关键之一。
Bootkit 是一种比较旧的技术,这个概念最早是在 2005 年由 eEye Digital安全公司在他们的“BootRoot"项目中提及的。Rootkit 是一种特殊的恶意软件,它的功能是在安装目标上隐藏自身及指定的文件、进程和网络链接等信息,比较多见到的是 Rootkit 一般都和木马、后门等其他恶意程序结合使用。Rootkit 通过加载特殊的驱动,修改系统内核,进而达到隐藏信息的目的。rootkit 并不一定是用作获得系统 root 访问权限的工具。实际上,rootkit 是攻击者用来隐藏自己的踪迹和保留 root 访问权限的工具。通常,攻击者通过远程攻击获得 root访问权限,或者首先密码猜测或者密码强制破译的方式获得系统的访问权限。进入系统后,如果他还没有获得 root 权限,再通过某些安全漏洞获得系统的 root权限。接着,攻击者会在侵入的主机中安装 rootkit,然后他将经常通过 rootkit的后门检查系统是否有其他的用户登录,如果只有自己,攻击者就开始着手清理日志中的有关信息。通过 rootkit 的嗅探器获得其它系统的用户和密码之后,攻击者就会利用这些信息侵入其它的系统。所有在开机时比 Windows 内核更早加载,实现内核劫持的技术,都可以称之为 Bootkit。Bootkit 主要是利用其内核准入和开机过程的隐身技术,在功能上无异于 Rootkit。传统的 Rootkit 利用系统启动时提升权限,而 Bootkit 主要被安置在外设的主引导扇区(也有放于 Ntldr 文件、BIOS 中的 Bootkit)并驻留在整个系统的启动过程。Bootkit 属于 Rootkit的一种,但它却是更加高级的 Rootkit,因为其存放于主引导扇区、启动文件之类地方,在操作系统启动之前驻留内存并内核运行之前劫持内核。
MBR 即主引导扇区(Master Boot Record)是装有 Linux 系统的硬盘的第一个扇区,即 C/H/S 地址的 0 柱面 0 磁头 1 扇区。这个扇区是系统开启时必须访问
的扇区,记录本磁盘相关信息以及硬盘各个分区的大小和信息。
本实验旨在对基于MBR的BootKit的启动模块代码,也就是感染MBR后第1、第 61、62 扇区的模块进行逆向分析。
三、涉及知识点 在本项目中,逆向涉及到的知识点有以下几个,分别是:
保护模式下 的 汇编语言 实模式下的汇编语言 S BIOS 中断服务 多级 K HOOK 技术 计算机系统内核原理 NTLDR (系统加载程序 ,用于装载 Windows
xp
3 2003 等版本 )
四、涉及工具 在本项目中,涉及到的工具有以下几个,分别是:
IDA (主要静态分析 Bootkit )、
Windbg
Bochs (主要是用于动态调试这个 Bootkit )
x Winhex 工具
五、源程序 见附件 六、过程及分析
首先介绍一下这个样本黑盒后的症状:感染 MBR(感染的具体形式为:真正的 MBR 被挪到了第 63 个扇区,Bootkit 启动模块的代码在第 1、61、62 个扇区。)直接在硬盘上写入了一个驱动(这种写入不是普通的在磁盘上释放一个文件,在系统的文件系统里面是看不见这个驱动的,在实验的虚拟机上是写入了未分区的空间中,通过 Winhex 工具可以查看到);生成一个 DLL 并运行然后 10 分钟后自动关机。第 1、61、62 个扇区的代码中,第 1 个扇区的代码是实模式下的汇编语言,第 61、62 个扇区是保护模式下的汇编语言,所以在用 IDA 分析的时候要进行选择,至于这三个扇区的代码直接用 Winhex 截取出来然后进行逆向分析。
这个 Bootkit 的启动代码主要用了三级 HOOK,分别为 HOOK INT13h、HOOK NTLDR 的特征码,HOOK 内核的特征码。下面将主要分析这三级 HOOK 的行为。
1 1 、第一级 HOOK ( HOOK INT13h)
seg000:7C35
@HOOK_INT13H: seg000:7C35
xor
bx, bx seg000:7C37
mov
eax, [bx+4Ch] seg000:7C3B
mov
es:73h, eax seg000:7C40
mov
word ptr [bx+4Ch], 66h ; "f" seg000:7C45
mov
word ptr [bx+4Eh], es seg000:7C48
push
es seg000:7C49
push
4Dh ; "M" seg000:7C4C
retf 上面的代码实现了 HOOK INT13h ,即 HOOK 了 BIOS 的磁盘中断服务。
下面为 HOOK INT13h 后的主要代码,其中主要是搜索了 NTLDR 文件的特征码,特征码为:
SignatureCode is :
8B F0
mov esi,eax
85 F6
test esi,esi
74 21
jz $+23h
80.............. 这段代码运行后内核和 BootDriver 已经加载到内存中,当找到这段代码以后就对这段特征码进行 HOOK,HOOK 的过程用到了 CALL NEAR[offset32],即相对的寻址方式。这个 HOOK 利用了 eEye BootRoot 里面的技术。上面的主要代码是在第一个扇区中的代码实现的,是实模式下执行的代码。
2 2 、第二级 HO OK (R HOOK NTLDR 的特征码)
这里主要为 HOOK 了 NLTDR 以后代码执行的过程,第二个 HOOK 的代码主要是在第 61 个扇区中实现的。
首先第二个 HOOK 会去搜索 NTLDR 中的特征码,搜索这个特征码是为了定位到BlLoaderBlock 这个变量,这个变量中包括了很多有用的信息,如内核和BootDriver 等等。搜索过程为下图:
图 1 当搜索到以后就可以定位到 BlLoaderBlock,然后[[BlLoaderBlock]+0]就正好为模块链表的指针。这个指针所指向的结构的一些主要成员为:
+00h
LIST_ENTRY
module list links +08h
[10h]
不太了解 +18h
PTR
image base address +1Ch
PTR
module entry point +20h
DWORD
size of loaded module in memory +24h
UNICODE_STRING
full module path and file name +2Ch
UNICODE_STRING
module file name 下图的代码就是利用上面介绍 BlLoaderBlock 的结构定位到了内核的基址。
图 2 当定位到内核以后,Bootkit 将搜索内核的特征代码,然后对内核进行 HOOK。
搜索的内核代码为:
push
4Bh
6Ah 4Bh
push
19h
6Ah 19h
call
InbvSetProgressBarSubset(x,x)
E8 E8 DD E6 FF
push
[ebp+var_470]
FF B5 90 FB FF FF call
IoInitSystem(x)
E8 53 E6 FF FF
当搜索到了上面的内核特征码后,就对内核的 call IoInitSystem(x)进行了HOOK,这个搜索特征码的过程如下图所示:
图 3 当搜索到特征码后接下就会对Kernel的特征码进行HOOK,HOOK的特征码为:
call
IoInitSystem(x)
E8 53 E6 FF FF 修改的地方为后面四个字节的偏移量。通过这个 HOOK Bootkit 就能在内核运行的时候再次获得执行的机会。
下面的代码便是对内核进行 HOOK 的操作:
图 4
从上图的代码看出,在这个过程中 Bootkit 会将 HOOK 内核的代码挪到内存中内核映像文件的末尾位置,大小正好为 200 个字节。
上面便是 Bootkit 的第二个 HOOK 所完成的工作。
3 3 、第三级 HOOK (l HOOK Kernel 的特征码)
当 HOOK Kernel 后的代码运行时,主要的代码是在第 62 个扇区中。其中的代码有些复杂,这里只介绍主要的执行流程。这个 HOOK 代码主要的功能实现了加载并运行一个驱动程序。
第三级 HOOK 中首先是通过内核的输出表定位到 ExAllocatePool 函数,搜索这个内核的函数是通过 Hash 的比较。当找到这个函数的地址以后就调用这个函数分配一片内存池,然后把下面的代码拷贝到这份内存中并在内存池中执行Bootkit 后面的代码。上面这个过程具体实现如下入所示:
图 5 接下来 Bootkit 会把调用之前被 HOOK 的 IoInitSystem(x)函数,即去 Call 这个函数,让 IO 去初始化系统。当执行完这步操作以后,则会在内核中搜索和多函数,如 NtReadFile、NtOpenFile、NtClose 等函数,调用这些函数主要是为了能够把驱动直接从磁盘上读出来,然后运行。
具体过程为如下。
首先调用 NtOpenFile 打开磁盘,并定位那个驱动的位置。过程为:
图 6
接下来调用 NtReadFile 函数,把驱动从磁盘上读到内存中,过程为下图所
示:
图 7 当把驱动读入到内存以后 Bootkit 还有一个将驱动进行内存对齐的操作。
具体过程为下图所示:
图 8 当对驱动进行内存对齐以后,就开始根据偏移定位到驱动的入口地址,然后运行驱动程序,具体过程下图所示为:
图 9 当驱动执行完毕后,则把控制权交还给 Bootkit 的启动代码,Bootkit 最后做的善后处理为:把正在运行的内存池里面的代码清零,然后把控制权交给操作系统的内核,让内核继续进行计算机的启动过程。
以上便是这个 Bootkit 样本的启动模块代码执行流程。
最后附上一个图,下图为 HOOK Kernel 处留下的痕迹。
图 10 Call IoInitSystem(x)被替换成了 Call 806cee00,而 806cee00 地址处的代码是 Bootkit 第三个 HOOK 的代码。
七、心得
逆向工程是一个实践性很强的学科,通过在线课程的学习以及亲手上机实验使得我在本次课程中收获很大,通过对程序的逆向工程的分析,本人对计算机技术有了更加深刻的认识。
感谢何兴高老师在课堂上的谆谆教诲,更感谢何老师在休息时间对我们的耐心讲解。