当前位置:范文大全 > 调查报告 > 基于MBR逆向分析工程实验报告|

基于MBR逆向分析工程实验报告|

时间:2021-10-15 13:31:42 浏览次数:

 电子科技大学

 信息与软件工程学院

 逆向工程

 实

 验

 报

 告

  姓 名: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扇区的模块进行逆向分析。

 三、涉及知识点

 在本项目中,逆向涉及到的知识点有以下几个,分别是:

 保护模式下的汇编语言

 实模式下的汇编语言

 BIOS中断服务

 多级HOOK技术

 计算机系统内核原理

 NTLDR(系统加载程序,用于装载Windows xp 2003等版本)

 四、涉及工具

 在本项目中,涉及到的工具有以下几个,分别是:

 IDA(主要静态分析Bootkit)、

 Windbg

 Bochs(主要是用于动态调试这个Bootkit)

 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、第一级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、第二级HOOK(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、第三级HOOK(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的代码。

 七、心得

  逆向工程是一个实践性很强的学科,通过在线课程的学习以及亲手上机实验使得我在本次课程中收获很大,通过对程序的逆向工程的分析,本人对计算机技术有了更加深刻的认识。

  感谢何兴高老师在课堂上的谆谆教诲,更感谢何老师在休息时间对我们的耐心讲解。