虚拟机去虚拟化及检测技术攻防.docx

上传人:b****8 文档编号:12818458 上传时间:2023-06-08 格式:DOCX 页数:40 大小:330.68KB
下载 相关 举报
虚拟机去虚拟化及检测技术攻防.docx_第1页
第1页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第2页
第2页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第3页
第3页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第4页
第4页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第5页
第5页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第6页
第6页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第7页
第7页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第8页
第8页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第9页
第9页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第10页
第10页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第11页
第11页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第12页
第12页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第13页
第13页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第14页
第14页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第15页
第15页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第16页
第16页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第17页
第17页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第18页
第18页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第19页
第19页 / 共40页
虚拟机去虚拟化及检测技术攻防.docx_第20页
第20页 / 共40页
亲,该文档总共40页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

虚拟机去虚拟化及检测技术攻防.docx

《虚拟机去虚拟化及检测技术攻防.docx》由会员分享,可在线阅读,更多相关《虚拟机去虚拟化及检测技术攻防.docx(40页珍藏版)》请在冰点文库上搜索。

虚拟机去虚拟化及检测技术攻防.docx

虚拟机去虚拟化及检测技术攻防

虚拟机去虚拟化及检测技术攻防

是精简,源码分析如下:

代码:

#include int main () {  unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";  //相当于SIDT[adrr],其中addr用于保存IDT地址  *((unsigned*)&rpill[3]) = (unsigned)m;  //将sidt[addr]中的addr设为m的地址  ((void(*)())&rpill)();  //执行SIDT指令,并将读取后IDT地址保存在数组m中  printf ("idt base:

 %#x\n", *((unsigned*)&m[2]));   //由于前2字节为IDT大小,因此从m[2]开始即为IDT地址  if (m[5]>0xd0) printf ("Inside Matrix!

\n", m[5]); //当IDT基址大于0xd0xxxxxx时则说明程序处于VMware中  else printf ("Not in Matrix.\n");  return 0;}

测试结果如图2所示:

 

 

 图2

   利用此IDT检测的方法存在一个缺陷,由于IDT的值只针对处于正在运行的处理器而言,在单CPU中它是个常量,但当它处于多CPU时就可能会受到影响了,因为每个CPU都有其自己的IDT,这样问题就自然而然的产生了。

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

为此,有人提出了使用LDT的检测方法,它在具有多个CPU的环境下检测虚拟机明显优于IDT检测方法,该方法具体内容参见下节内容。

    

方法三:

利用LDT和GDT的检测方法

   在 《Intel® 64 and IA-32  Architecture Software Developer’s Manual Volume 3A:

 System Programming Guide》第二章的Vol.3 2-5 一页(我的Intel开发手册是2008版的)中对于LDT和GDT的描述如下(以下内容为个人翻译):

在保护模式下,所有的内存访问都要通过全局描述符表(GDT)或者本地描述符表(LDT)才能进行。

这些表包含有段描述符的调用入口。

各个段描述符都包含有各段的基址,访问权限,类型和使用信息,而且每个段描述符都拥有一个与之相匹配的段选择子,各个段选择子都为软件程序提供一个GDT或LDT索引(与之相关联的段描述符偏移量),一个全局/本地标志(决定段选择子是指向GDT还是LDT),以及访问权限信息。

    若想访问段中的某一字节,必须同时提供一个段选择子和一个偏移量。

段选择子为段提供可访问的段描述符地址(在GDT 或者LDT 中)。

通过段描述符,处理器从中获取段在线性地址空间里的基址,而偏移量用于确定字节地址相对基址的位置。

假定处理器在当前权限级别(CPL)可访问这个段,那么通过这种机制就可以访问在GDT 或LDT 中的各种有效代码、数据或者堆栈段,这里的CPL是指当前可执行代码段的保护级别。

……

    GDT的线性基址被保存在GDT寄存器(GDTR)中,而LDT的线性基址被保存在LDT寄存器(LDTR)中。

 

    由于虚拟机与真实主机中的GDT和LDT并不能相同,这与使用IDT的检测方法一样,因此虚拟机必须为它们提供一个“复制体”。

关于GDT和LDT的基址可通过SGDT和SLDT指令获取。

虚拟机检测工具Scoopy suite的作者Tobias Klein经测试发现,当LDT基址位于0x0000(只有两字节)时为真实主机,否则为虚拟机,而当GDT基址位于0xFFXXXXXX时说明处于虚拟机中,否则为真实主机。

具体实现代码如下:

代码:

#include void LDTDetect(void){    unsigned short ldt_addr = 0;    unsigned char ldtr[2];    _asm sldt ldtr    ldt_addr = *((unsigned short *)&ldtr);    printf("LDT BaseAddr:

 0x%x\n", ldt_addr);    if(ldt_addr == 0x0000)    {        printf("Native OS\n");    }    else        printf("Inside VMware\n");}void GDTDetect(void){    unsigned int gdt_addr = 0;    unsigned char gdtr[4];    _asm sgdt gdtr    gdt_addr = *((unsigned int *)&gdtr[2]);    printf("GDT BaseAddr:

0x%x\n", gdt_addr);    if((gdt_addr >> 24) == 0xff)    {        printf("Inside VMware\n");    }    else        printf("Native OS\n");}int main(void){    LDTDetect();    GDTDetect();    return 0;}

测试结果如图3所示:

 

 图3

方法四:

基于STR的检测方法

    在保护模式下运行的所有程序在切换任务时,对于当前任务中指向TSS的段选择器将会被存储在任务寄存器中,TSS中包含有当前任务的可执行环境状态,包括通用寄存器状态,段寄存器状态,标志寄存器状态,EIP寄存器状态等等,当此项任务再次被执行时,处理器就会其原先保存的任务状态。

每项任务均有其自己的TSS,而我们可以通过STR指令来获取指向当前任务中TSS的段选择器。

这里STR(Store task register)指令是用于将任务寄存器 (TR) 中的段选择器存储到目标操作数,目标操作数可以是通用寄存器或内存位置,使用此指令存储的段选择器指向当前正在运行的任务的任务状态段 (TSS)。

在虚拟机和真实主机之中,通过STR读取的地址是不同的,当地址等于0x0040xxxx时,说明处于虚拟机中,否则为真实主机。

实现代码如下:

 代码:

#include int main(void){    unsigned char mem[4] = {0};    int i;    __asm str mem;    printf (" STR base:

 0x");    for (i=0; i<4; i++)    {        printf("%02x",mem[i]);    }    if ( (mem[0]==0x00) && (mem[1]==0x40))        printf("\n INSIDE MATRIX!

!

\n");    else        printf("\n Native OS!

!

\n");    return 0;}测试结果如图4所示:

 

 图4

方法五:

基于注册表检测虚拟机

    在windows虚拟机中常常安装有VMware Tools以及其它的虚拟硬件(如网络适配器、虚拟打印机,USB集线器……),它们都会创建任何程序都可以读取的windows注册表项,因此我们可以通过检测注册表中的一些关键字符来判断程序是否处于虚拟机之中。

关于这些注册表的位置我们可以通过在注册表中搜索关键词“vmware”来获取,下面是我在VMware下的WinXP中找到的一些注册表项:

项名:

HKEY_CLASSES_ROOT\Applications\VMwareHostOpen.exe

项名:

HKEY_CLASSES_ROOT\Installer\Products\C2A6F2EFE6910124C940B2B12CF170FE\ProductName

键值“VMware Tools”

项名:

HKEY_CLASSES_ROOT\Installer\Products\C2A6F2EFE6910124C940B2B12CF170FE\SourceList\PackageName

键值:

VMware Tools.msi

项名:

HKEY_CURRENT_USER\Printers\DeviceOld

键值:

_#VMwareVirtualPrinter,winspool,TPVM:

项名:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier

键值:

VMware Virtual IDE Hard Drive

项名:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier

键值:

NECVMWar VMware IDE CDR10

项名:

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\C2A6F2EFE6910124C940B2B12CF170FE\ProductName

键值:

VMware Tools

项名:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\C2A6F2EFE6910124C940B2B12CF170FE\InstallProperties\DisplayName

键值:

VMware Tools

项名:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Reinstall\0002\DeviceDesc

键值:

VMware SVGA II

项名:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\2\Description

键值:

VMware Accelerated AMD PCNet Adapter

项名:

HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.\VMware Tools

项名:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\DriverDesc

键值:

VMware SVGA II

项名:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4D36E968-E325-11CE-BFC1-

08002BE10318}\0000\ProviderName

键值:

VMware, Inc.

项名:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0001\DriverDesc

键值:

VMware Accelerated AMD PCNet Adapter

项名:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0000\DriverDesc

键值:

VMware SCSI Controller

项名:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare

补充另外一处具体代码如下:

[cpp] viewplaincopy

1.BOOL DetectVM() {  

2.  

3.    HKEY hKey;  

4.  

5.    char szBuffer[64];  

6.  

7.    unsigned long hSize= sizeof(szBuffer) - 1;  

8.  

9.    if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\BIOS\\", 0, KEY_READ, &hKey )==ERROR_SUCCESS ) {  

10.  

11.        RegQueryValueEx( hKey, "SystemManufacturer", NULL, NULL, (unsigned char *)szBuffer, &hSize );  

12.  

13.                if( strstr( szBuffer, "VMWARE" )) {       

14.  

15.                    RegCloseKey( hKey );  

16.  

17.                    return TRUE;  

18.  

19.        }  

20.  

21.        RegCloseKey( hKey );  

22.  

23.    }  

24.  

25.    return FALSE;  

26.  

27.} 

    除以上这些表项之外,还有很多地方可以检测,特别是虚拟机提供的虚拟化软硬件、服务之类,比如文件共享服务,VMware 物理磁盘助手服务,VMware Ethernet Adapter Driver,VMware SCSI Controller等等的这些信息都可作为检测虚拟机的手段。

这里我们就以其中某表项为例编程举例一下,其它表项检测方法同理,具体代码如下:

 代码:

.386.model flat, stdcalloption casemap:

none   include  windows.inc   include  user32.inc   include  kernel32.inc   include  advapi32.inc   includelib  user32.lib   includelib  kernel32.lib   includelib  advapi32.lib.dataszCaption     db "VMware Detector ",0szInside         db "Inside VMware!

",0szOutside              db "Native OS!

",0szSubKey      db "software\VMWare, Inc.\VMware tools",0hKey              dd    ?

.codestart:

  invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szSubKey, 0,\                 KEY_WRITE or KEY_READ, addr hKey  .if eax == ERROR_SUCCESS  invoke MessageBox, NULL,addr szInside, addr szCaption, MB_OK  .else  invoke MessageBox, NULL,addr szOutside, addr szCaption, MB_OK  .endif  invoke RegCloseKey,hKey  invoke ExitProcess,NULLend start

测试结果如图5所示:

 

 图5

方法六:

基于时间差的检测方式

   本方法通过运行一段特定代码,然后比较这段代码在虚拟机和真实主机之中的相对运行时间,以此来判断是否处于虚拟机之中。

这段代码我们可以通过RDTSC指令来实现,RDTSC指令是用于将计算机启动以来的CPU运行周期数存放到EDX:

EAX里面,其中EDX是高位,而EAX是低位。

下面我们以xchg    ecx,  eax 一句指令的运行时间为例,这段指令在我的真实主机windows 7系统上的运行时间为0000001E,如图6所示:

 图6

 而该指令在虚拟机WinXP下的运行时间为00000442,如图7所示:

 

图7

两者之间的运行时间明显差别很多,在虚拟机中的运行速度远不如真实主机的,一般情况下,当它的运行时间大于0xFF时,就可以确定它处于虚拟机之中了,因此不难写出检测程序,具体实现代码如下:

代码:

.586p.model flat, stdcalloption casemap:

noneinclude      windows.incinclude       kernel32.incinclude      user32.incincludelib    kernel32.libincludelib    user32.lib      .dataszTitle      db  "VMDetect With RDTSC", 0hszInsideVM    db  "Inside VMware!

", 0hszOutsideVM    db  "Native OS!

", 0h.codestart:

  RDTSC  xchg     ecx, eax  RDTSC    sub    eax, ecx  cmp    eax, 0FFh  jg    Detected    invoke  MessageBox, 0, offset szOutsideVM, offset szTitle, 0  ret  Detected:

  invoke   MessageBox, 0, offset szInsideVM, offset szTitle, 0  retend start

测试结果如图8所示:

 

 图8

    方法七:

利用虚拟硬件指纹检测虚拟机

利用虚拟硬件指纹也可用于检测虚拟机的存在,比如VMware默认的网卡MAC地址前缀为“00-05-69,00-0C-29或者00-50-56”,这前3节是由VMware分配的唯一标识符OUI,以供它的虚拟化适配器使用。

在我的VMWare WinXP下的MAC地址为00-0C-29-5B-D7-67,

如图9所示:

 图9

    但由于这些可经过修改配置文件来绕过检测。

另外,还可通过检测特定的硬件控制器,BIOS,USB控制器,显卡,网卡等特征字符串进行检测,这些在前面使用注册表检测方法中已有所涉及。

另外之前在看雪论坛上也有朋友提到通过检测硬盘Model Number是否含有“vmware”或“virtual”等字样来实现检测虚拟机的功能,具体转载如下:

[cpp] viewplaincopy

1.小试 anti vmware  

2.     今天偶然看到一款绿色版的硬盘专业工具,突然发现可以利用其中的一项功能来实现anti vmware。

  

3.  今日事今日毕,那就在今晚12:

00之前把这个想法实现吧,let's go!

  

4.     我的想法就是检测硬盘的modelnumber,具体什么是modelnumber自己网上搜吧,反正不是硬盘序列号。

难点就是在多种操作系统下都要能起到anti vmware的效果。

程序在xp、2k、2003下都可以检测到vmware的运行。

  

5.    直接贴代码了,如果看不懂也没关系,我也是逆了人家的代码写出来的。

Delphi也可以当汇编语言开发工具用,难道不是吗?

  

6.    unit Unit1;  

7.  interface    

8.  uses  

9.    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  

10.    Dialogs, StdCtrls, Buttons;  

11.  type  

12.    TForm1 = class(TForm)  

13.    BitBtn1:

 TBitBtn;  

14.    procedure BitBtn1Click(Sender:

 TObject);  

15.    procedure FormClose(Sender:

 TObject; var Action:

 TCloseAction);  

16.    private  

17.    { Private declarations }  

18.    public  

19.    { Public declarations }  

20.    end;  

21.    

22.  var  

23.    Form1:

 TForm1;  

24.    hDeviceHandle:

Thandle;  

25.    

26.  implementation  

27.    

28.  {$R *.dfm}  

29.    

30.  procedure TForm1.BitBtn1Click(Sender:

 TObject);  

31.  var  

32.     InBuffer:

 array[0..$8f] of byte;  

33.     cb:

Cardinal;  

34.     tmp:

Pchar;  

35.  begin  

36.       hDeviceHandle:

=CreateFile('\\.\PHYSICALDRIVE0',$C0000000,$3,nil,OPEN_EXISTING,$8000000,0);  

37.       ZeroMemory(@InBuffer,sizeof(InBuffer));  

38.      asm  

39.        pushad  

40.        lea ebx,InBuffer  

41.        xor ecx,ecx  

42.        mov al,$2c  

43.        MOV [ebx],al  

44. 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2