虚拟机检测技术剖析

上传人:ni****g 文档编号:552786423 上传时间:2023-05-25 格式:DOC 页数:12 大小:382.01KB
返回 下载 相关 举报
虚拟机检测技术剖析_第1页
第1页 / 共12页
虚拟机检测技术剖析_第2页
第2页 / 共12页
虚拟机检测技术剖析_第3页
第3页 / 共12页
虚拟机检测技术剖析_第4页
第4页 / 共12页
虚拟机检测技术剖析_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《虚拟机检测技术剖析》由会员分享,可在线阅读,更多相关《虚拟机检测技术剖析(12页珍藏版)》请在金锄头文库上搜索。

1、虚拟机检测技术剖析作者:riusksk (泉哥)主页:http:/前言在当今信息安全领域,特别是恶意软件分析中,经常需要利用到虚拟机技术,以提高病毒分析过程的安全性以及硬件资源的节约性,因此它在恶意软件领域中是应用越来越来广泛。这里我们所谓的虚拟机(Virtual Machine)是指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。通过虚拟机软件(比如VMware,Virtual PC ,VirtualBox),你可以在一台物理计算机上模拟出一台或多台虚拟的计算机,这些虚拟机完全就像真正的计算机那样进行工作,例如你可以安装操作系统、安装应用程序、访问网络资源等等

2、。攻击者为了提高恶意程序的隐蔽性以及破坏真实主机的成功率,他们都在恶意程序中加入检测虚拟机的代码,以判断程序所处的运行环境。当发现程序处于虚拟机(特别是蜜罐系统)中时,它就会改变操作行为或者中断执行,以此提高反病毒人员分析恶意软件行为的难度。本文主要针对基于Intel CPU的虚拟环境VMware中的Windows XP SP3系统进行检测分析,并列举出当前常见的几种虚拟机检测方法。方法一:通过执行特权指令来检测虚拟机Vmware为真主机与虚拟机之间提供了相互沟通的通讯机制,它使用“IN”指令来读取特定端口的数据以进行两机通讯,但由于IN指令属于特权指令,在处于保护模式下的真机上执行此指令时,

3、除非权限允许,否则将会触发类型为“EXCEPTION_PRIV_INSTRUCTION”的异常,而在虚拟机中并不会发生异常,在指定功能号0A(获取VMware版本)的情况下,它会在EBX中返回其版本号“VMXH”;而当功能号为0x14时,可用于获取VMware内存大小,当大于0时则说明处于虚拟机中。VMDetect正是利用前一种方法来检测VMware的存在,其检测代码分析如下:bool IsInsideVMWare() bool rc = true; _try _asm push edx push ecx push ebx mov eax, VMXh mov ebx, 0 / 将ebx设置为非

4、幻数VMXH的其它值 mov ecx, 10 / 指定功能号,用于获取VMWare版本,当它为0x14时用于获取VMware内存大小 mov edx, VX / 端口号 in eax, dx / 从端口dx读取VMware版本到eax/若上面指定功能号为0x14时,可通过判断eax中的值是否大于0,若是则说明处于虚拟机中 cmp ebx, VMXh / 判断ebx中是否包含VMware版本VMXh,若是则在虚拟机中 setz rc / 设置返回值 pop ebx pop ecx pop edx _except(EXCEPTION_EXECUTE_HANDLER) /如果未处于VMware中,则

5、触发此异常 rc = false; return rc;测试结果: 图1如图1所示,VMDetect成功检测出VMWare的存在。方法二:利用IDT基址检测虚拟机利用IDT基址检测虚拟机的方法是一种通用方式,对VMware和Virtual PC均适用。中断描述符表IDT(Interrupt Descriptor Table)用于查找处理中断时所用的软件函数,它是一个由256项组成的数据,其中每一中断对应一项函数。为了读取IDT基址,我们需要通过SIDT指令来读取IDTR(中断描述符表寄存器,用于IDT在内存中的基址),SIDT指令是以如下格式来存储IDTR的内容:typedef struct

6、WORD IDTLimit;/ IDT的大小 WORD LowIDTbase;/ IDT的低位地址 WORD HiIDTbase;/ IDT的高位地址 IDTINFO;由于只存在一个IDTR,但又存在两个操作系统,即虚拟机系统和真主机系统。为了防止发生冲突,VMM(虚拟机监控器)必须更改虚拟机中的IDT地址,利用真主机与虚拟机环境中执行sidt指令的差异即可用于检测虚拟机是否存在。著名的“红丸”(redpill)正是利用此原理来检测VMware的。Redpill作者在VMware上发现虚拟机系统上的IDT地址通常位于0xFFXXXXXX,而Virtual PC通常位于0xE8XXXXXX,而在

7、真实主机上正如图2所示都位于0x80xxxxxx。Redpill仅仅是通过判断执行SIDT指令后返回的第一字节是否大于0xD0,若是则说明它处于虚拟机,否则处于真实主机中。Redpill的源码甚是精简,源码分析如下:#include int main () unsigned char m2+4, rpill = x0fx01x0dx00x00x00x00xc3;/相当于SIDTadrr,其中addr用于保存IDT地址 *(unsigned*)&rpill3) = (unsigned)m;/将sidtaddr中的addr设为m的地址 (void(*)()&rpill)();/执行SIDT指令,并

8、将读取后IDT地址保存在数组m中 printf (idt base: %#xn, *(unsigned*)&m2); /由于前2字节为IDT大小,因此从m2开始即为IDT地址 if (m50xd0) printf (Inside Matrix!n, m5); /当IDT基址大于0xd0xxxxxx时则说明程序处于VMware中 else printf (Not in Matrix.n); return 0;测试结果如图2所示: 图2利用此IDT检测的方法存在一个缺陷,由于IDT的值只针对处于正在运行的处理器而言,在单CPU中它是个常量,但当它处于多CPU时就可能会受到影响了,因为每个CPU都有

9、其自己的IDT,这样问题就自然而然的产生了。针对此问题,Offensive Computing组织成员提出了两种应对方法,其中一种方法就是利用Redpill反复地在系统上循环执行任务,以此构造出一张当前系统的IDT值变化统计图,但这会增加CPU负担;另一种方法就是windows API函数SetThreadAffinityMask()将线程限制在单处理器上执行,当执行此测试时只能准确地将线程执行环境限制在本地处理器,而对于将线程限制在VM处理器上就可能行不通了,因为VM是计划在各处理器上运行的,VM线程在不同的处理器上执行时,IDT值将会发生变化,因此此方法也是很少被使用的。为此,有人提出了使

10、用LDT的检测方法,它在具有多个CPU的环境下检测虚拟机明显优于IDT检测方法,该方法具体内容参见下节内容。方法三:利用LDT和GDT的检测方法在 Intel 64 and IA-32 Architecture Software Developers Manual Volume 3A: System Programming Guide第二章的Vol.3 2-5 一页(我的Intel开发手册是2008版的)中对于LDT和GDT的描述如下(以下内容为个人翻译):在保护模式下,所有的内存访问都要通过全局描述符表(GDT)或者本地描述符表(LDT)才能进行。这些表包含有段描述符的调用入口。各个段描述符

11、都包含有各段的基址,访问权限,类型和使用信息,而且每个段描述符都拥有一个与之相匹配的段选择子,各个段选择子都为软件程序提供一个GDT或LDT索引(与之相关联的段描述符偏移量),一个全局/本地标志(决定段选择子是指向GDT还是LDT),以及访问权限信息。若想访问段中的某一字节,必须同时提供一个段选择子和一个偏移量。段选择子为段提供可访问的段描述符地址(在GDT 或者LDT 中)。通过段描述符,处理器从中获取段在线性地址空间里的基址,而偏移量用于确定字节地址相对基址的位置。假定处理器在当前权限级别(CPL)可访问这个段,那么通过这种机制就可以访问在GDT 或LDT 中的各种有效代码、数据或者堆栈段

12、,这里的CPL是指当前可执行代码段的保护级别。GDT的线性基址被保存在GDT寄存器(GDTR)中,而LDT的线性基址被保存在LDT寄存器(LDTR)中。 由于虚拟机与真实主机中的GDT和LDT并不能相同,这与使用IDT的检测方法一样,因此虚拟机必须为它们提供一个“复制体”。关于GDT和LDT的基址可通过SGDT和SLDT指令获取。虚拟机检测工具Scoopy suite的作者Tobias Klein经测试发现,当LDT基址位于0x0000(只有两字节)时为真实主机,否则为虚拟机,而当GDT基址位于0xFFXXXXXX时说明处于虚拟机中,否则为真实主机。具体实现代码如下:#include void

13、 LDTDetect(void) unsigned short ldt_addr = 0; unsigned char ldtr2; _asm sldt ldtr ldt_addr = *(unsigned short *)&ldtr); printf(LDT BaseAddr: 0x%xn, ldt_addr); if(ldt_addr = 0x0000) printf(Native OSn); else printf(Inside VMwaren);void GDTDetect(void) unsigned int gdt_addr = 0; unsigned char gdtr4; _a

14、sm sgdt gdtr gdt_addr = *(unsigned int *)&gdtr2); printf(GDT BaseAddr:0x%xn, gdt_addr); if(gdt_addr 24) = 0xff) printf(Inside VMwaren); else printf(Native OSn);int main(void) LDTDetect(); GDTDetect(); return 0;测试结果如图3所示: 图3方法四:基于STR的检测方法在保护模式下运行的所有程序在切换任务时,对于当前任务中指向TSS的段选择器将会被存储在任务寄存器中,TSS中包含有当前任务的可执行环境状态,包括通用寄存器状态,段寄存器状态,标志寄存器状态,EIP寄存器状态等等,当此项

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 幼儿/小学教育 > 幼儿教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号