虚拟机检测技术详解(第22课)

在当今信息安全领域,特别是恶意软件分析中,经常需要利用到虚拟机技术,以提高病毒分析过程的安全性以及硬件资源的节约性,因此它在恶意软件领域中是应用越来越来广泛。这里我们所谓的虚拟机(Virtual Machine)是指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。

 

一、VMWare

 

1、查找注册表

1、通过检测注册表“HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0”,在数据项中查找目标数据VMWARE:

VMWARE

 

2、HKEY_LOCAL_MACHINE_SYSTEM_ControlSet001\Services\VMware Pyhsical Disk Helper Service:VMware Pyhsical Disk Helper Service

 

3、Vmware总线设备驱动,查看PCI。

VMWare

 

2、搜索特定程序

Vmtoolsd.exe

vmacthlp.exe

VMwareUser.exe

VMwareTray.exe

VMUpgradeHelper.exe

bool SearchTargetPro(WCHAR* strProName)

{

PROCESSENTRY32 pe32;

pe32.dwSize = sizeof(pe32);

HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == INVALID_HANDLE_VALUE)

{

exit(1);

}

bool bMore = ::Process32First(hProcessSnap, &pe32);

while (bMore)

{

if (wcsstr(pe32.szExeFile, strProName))

{

return true;

bMore = false;

}

else

{

bMore = ::Process32Next(hProcessSnap, &pe32);

}

}

CloseHandle(hProcessSnap);

return bMore;

}

 

3、通过执行特权指令

Vmware为真主机与虚拟机之间提供了相互沟通的通讯机制,它使用“IN”指令来读取特定端口的数据以进行两机通讯,但由于IN指令属于特权指令,在处于保护模式下的真机上执行此指令时,除非权限允许,否则将会触发类型为“EXCEPTION_PRIV_INSTRUCTION”的异常,而在虚拟机中并不会发生异常,在指定功能号0A(获取VMware版本)的情况下,它会在EBX中返回其版本号“VMXH”;而当功能号为0x14时,可用于获取VMware内存大小,当大于0时则说明处于虚拟机中。VMDetect正是利用前一种方法来检测VMware的存在,其检测代码分析如下:

void IsInsideVMWare()

{

bool rc = true;

__try

{

__asm

{

push   edx

push   ecx

push   ebx

mov    eax, 'VMXh'

mov    ebx, 0  // 将ebx设置为非幻数’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中,则触发此异常

{

rc = false;

}

if (rc == true)

{

cout << "In VMWare!" << endl;

}

else

{

cout << "Not In VMWare!" << endl;

}

}

void test6(void)

{

unsigned int    a = 0;

__try {

__asm {

// save register values on the stack

push eax

push ebx

push ecx

push edx

// perform fingerprint

mov eax, 'VMXh'

mov ecx, 14h

mov dx, 'VX'

in eax, dx

mov a, eax

pop edx

pop ecx

pop ebx

pop eax

}

}

__except (EXCEPTION_EXECUTE_HANDLER) {}

printf("\n[+] Test 6: VMware \"get memory size\" command\n");

if (a > 0)

printf("Result  : VMware detected\n\n");

else

printf("Result  : Native OS\n\n");

}

 

4、查找特定的驱动模块

hgfs.sys

vmhgfs.sys

prleth.sys

prlfs.sys

prlmouse.sys

prlvideo.sys

prl_pv32.sys

vpc-s3.sys

vmsrvc.sys

vmx86.sys

vmnet.sys

 

5、CPUID

原理介绍:当eax=1时,运行CPUID之后,ecx的高31位可以判断出是否在虚拟机中,如果ecx的高31位为0表示在虚拟机下,否则在主机下。

 

参考代码:

void CheckCPUID()

{

DWORD dwECX = 0;

bool isVM = true;

_asm {

pushad;

pushfd;

mov eax, 1;

cpuid;

mov dwECX, ecx;

and ecx, 0x80000000;

test ecx, ecx;

setz[isVM];

popfd;

popad;

}

if (isVM)//主机下

{

cout << "在主机下" << endl;

}

else//虚拟机下

{

cout << "在虚拟机下" << endl;

}

}



当eax=0x40000000时,运行CPUID之后,ebx+ecx+edx=”VMWareVMWare”;

参考代码:

void CheckCPUID()

{

DWORD dwECX = 0;

bool isVM = true;

DWORD dwReg[3] = { 0 };

_asm {

pushad;

pushfd;

mov eax, 0x40000000;

cpuid;

mov dword ptr[dwReg], ebx;

mov dword ptr[dwReg + 4], ecx;

mov dword ptr[dwReg + 8], edx;



popfd;

popad;

}

printf("%s\r\n", dwReg);

}

 

6、检测系统对象

在WinXP和Win7中都有VMwareToolsQuitEvent_wmsvc和VMwareToolsDumpStateEvent_vmsvc,可以通过检测这两项事件对象是否存在来判断是不是运行在虚拟机里?

XP下检测结果

XP下检测结果

 

win7下检测结果

win7下检测结果

 

7、查询csrss.exe内存中的可疑字符

查询csrss.exe内存中的可疑字符

 

8、硬件特征

VMWare硬件特征如下所示:

显卡 Name=VMware SVGA II

网卡 Name=VMware Accelerated AMD PCNet Adapter

鼠标 Name=VMware Pointing Device

磁盘驱动器 Caption=VMware Virtual IDE Hard Drive

SCSI控制器 name=VMware VMSCSI Controller

 

可以通过获取当前系统的硬件信息来判定是否运行在虚拟机中?获取当前系统的硬件信息来判定是否运行在虚拟机中

 

二、Virtual PC

 

1、使用非法指令

使用非法指令0x0F,0x3F,0xXX,0xXX。这些指令在VirtualPC上不会产生异常,但是在主机和其他虚拟机中会产生异常。并且需要注册异常处理函数来处理。

 

参考代码:

static DWORD lpOldHandler;

typedef LPTOP_LEVEL_EXCEPTION_FILTER(_stdcall  *pSetUnhandledExceptionFilter)(

LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter

);

pSetUnhandledExceptionFilter lpSetUnhandledExceptionFilter;



LONG WINAPI TopUnhandledExceptionFilter(

struct _EXCEPTION_POINTERS *ExceptionInfo

)

{

_asm pushad



//  lpSetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)lpOldHandler);

//  ExceptionInfo->ContextRecord->Eip = NewEip;//转移到安全位置

MessageBox(NULL,L"HelloWorld",L"hh",0);

_asm popad

return EXCEPTION_CONTINUE_EXECUTION;

}

void CheckOrder()

{

// TODO: Add your control notification handler code here

lpSetUnhandledExceptionFilter = (pSetUnhandledExceptionFilter)GetProcAddress(LoadLibrary((L"kernel32.dll")),

"SetUnhandledExceptionFilter");

//当异常没有处理的时候,系统就会调用此函数所设置的异常处理函数,此函数返回以前设置的回调函数

lpOldHandler = (DWORD)lpSetUnhandledExceptionFilter(TopUnhandledExceptionFilter);

_asm {  //获取这个安全地址

}

_asm {

__emit 0Fh

__emit 3Fh

__emit 07h

__emit 0Bh

}

}

 

2、检测系统对象

检测系统对象

 

3、硬件特征

Virtual PC的硬件特征如下:

光驱:Caption=MS C/DVD-ROM  Name=MS C/DVD-ROM

硬盘:Caption=Virtual HD        Model=Virtual HD

显卡:Caption=Virtual PC Intergration Components S3 Trio32/64

Description=Virtual PC Intergration Components S3 Trio32/64

Name= Virtual PC Intergration Components S3 Trio32/64

InfSection=vpc-s3     VideoProcessor=S3 732

主板:Manufacturer=Microsoft Corporation        Product=Virtual Machine

特定指令:CPUID

功能号:0x40000001

返回: eax=“VPC7” ,最后一个数字可变

 

可以通过获取硬件特征值来进行判定是否运行在虚拟机里?硬件特征

 

三、VirtualBox

 

1、搜索注册表项

搜索特定的注册表项来判断是不是运行在虚拟系统中?VirtualBox注册表

 

VirtualBox注册表

 

2、CPUID

原理介绍:当eax=0x40000000时,运行CPUID之后,ebx,ecx,edx不等于0,则运行在虚拟机里,如果等于0表示不在虚拟机里。

 

实例代码:

BOOL isVirtualBoxBySpecInstruct()

{

bool res = FALSE;

__asm

{

mov eax,0x40000000      //HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS

cpuid

cmp ebx,0               //ebx,ecx,edx != 0 in vm other not in vm

jne l1

mov res,0

jmp ed

l1:

mov res,1

ed:

}

return res;

}

 

3、硬件特征

VirtualBox的硬件特征如下:

光驱:Caption=VBOX CD-ROM      Name=VBOX CD-ROM

硬盘:Caption=VBOX HARDDISK   Model=VBOX HARDDISK

显卡:Caption=VirtualBox Graphics Adapter        Description=VirtualBox Graphics Adapter

InfSection=VBOXVideo    Name=VirtualBox Graphics Adapter

VideoProcessor=VBOXVideo

BIOS:Manufacturer=innotek GmbH     SMBIOSVersion=VirtualBox

Version=VBOX – 1

主板:Manufacturer=Oracle Corporation      Product=VirtualBox

 

可以通过获取硬件特征值来进行判定是否运行在虚拟机里?VirtualBox的硬件特征

 

4、搜索特定进程

在虚拟机里,会有一些虚拟机特有的进程,可以通过检测这些进程是否存在来判断是不是运行在虚拟机里。

VBoxService.exe

VBoxTray.exeVirtualBox搜索特定进程

 

5、查找底层模块

虚拟机的服务需要有底层模块的支持,一些比较明显的模块有如下几个。

VBoxGuest.sys

VBoxSF.sys

VBoxMouse.sys

VBoxVideo.sys

VBoxDisp.dll

 

四、SandBox

 

1、检测系统对象

Sandbox开启之后,会在会在RPC Control目录下,有一个端口名称:SbieSvcPortSbieSvcPort

 

2、查看当前进程是否包含目标动态库

在当前的进程空间中搜索目标动态库来判断是否运行在沙箱中?

Comodo sandbox—–cmdvrt32.dll

Qihoo360 sandbox—-SxIn.dll

Sandboxie sandbox—–SbieDll.dll

 

参考代码:

void CheckSbieDll()

{

TCHAR ModuleToFind[MAX_PATH] = L"SbieDll.dll";

HMODULE moduleHandle[1024];

DWORD cbNeeded;

unsigned int i;

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,GetCurrentProcessId());

if (hProcess == NULL)

{

cout << "OpenProcess Error" << endl;

}

if (EnumProcessModules(hProcess, moduleHandle, sizeof(moduleHandle), &cbNeeded))

{

for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)

{

TCHAR moduleName[MAX_PATH];



if (GetModuleFileNameEx(hProcess, moduleHandle[i], moduleName, sizeof(moduleName) / sizeof(TCHAR))) {

if (wcsstr(moduleName, ModuleToFind) != nullptr)

{

cout << "In SandBox" << endl;

return;

}

}

}

}

else

{

cout << "EnumProcessModules Error" << endl;

return;

}

cout << "Not In SandBox" << endl;

return;

}

 

3、检测SbieDll.dll与API完整性

SandBoxie会注入SBIEDLL.DLL,HOOK应用程序使用的API函数,API函数会先跳转到该DLL。

Sanboxie可能会隐藏该SbieDll.dll,所以另一种方法是检测NTDLL API函数的完整性。

 

如果要检测要调用的API函数是否被HOOK,可以判断对应函数的前5个字节是不是0xE9 0xXXXXXXXX,如果被HOOK了,可以通过使用枚举进程模块的方法查看是被哪个模块HOOK了。检测SbieDll.dll与API完整性

 

4、检测CPU个数

通常情况下,虚拟机或者沙箱中的CPU个数是1,所以通过检测虚拟机的个数也可以检测是否运行在虚拟机中。检测CPU个数

 

5、可成功提权的进程个数

沙盒提供了与主机环境非常相似的环境,很多恶意软件的分析就是在沙盒中进行的,检测程序是否运行在沙盒当中的方法就是通过对已有进程的提权操作然后进行统计,统计为可以成功提权的进程数小于等于10(这里为统计值)的时候为程序运行在沙盒环境。

主机运行结果

主机运行结果

 

沙箱运行结果

(虚拟机)沙箱运行结果

 

五、其他(PARALLELS、QEMU、XEN、BOCHS)

 

1、PARALLELS

这是一款运行在Mac电脑上安装windows系统的虚拟机软件,这样就能够在Mac下非常方便的运行Widows操作系统的应用,并且可以轻松切换到苹果的Mac系统,对于苹果电脑用户来说还是很实用的。

检测程序是否运行在PARALLELS中可以通过硬件特征,CPU ID指令和进程特征进行检测。

 

硬件特征

显卡:    Caption= Parallels Video Adapter           Description= Parallels Video Adapter

Name= Parallels Video Adapter              VideoProcessor= Virtual Adapter

网卡:    Caption= Parallels Ethernet Adapter             Description= Parallels Ethernet Adapter

Manufacturer= Parallels                  Name= Parallels Ethernet Adapter

ProductName= Parallels Ethernet Adapter

鼠标:    Caption= Parallels Mouse Synchronization Device

Description= Parallels Mouse Synchronization Device

Manufacturer= Parallels           Name= Parallels Mouse Synchronization Device

声卡:    Caption= Parallels Audio Controller (x32)      Manufacturer= Parallels

Description= Parallels Audio Controller (x32)

Name= Parallels Audio Controller (x32)

ProductName= Parallels Audio Controller (x32)

主板:    Manufacturer= Parallels Software International Inc.

Product= Parallels Virtual Platform

BIOS:  Manufacturer= Parallels Software International Inc.

SerialNumber= Parallels-5E 48 47 9F B5 30 7A 47 84 DB 58 97 C5 AF AB 85

Version= PRLS   – 1

 

进程特征

coherence.exe

prl-tool-service.exe

 

特殊指令,CPUID,类型如下:

检测结果如下图所示:PARALLELS

 

 

2、QEMU

QEMU是一款开源的模拟器及虚拟机监管器(Virtual Machine Monitor, VMM)。QEMU主要提供两种功能给用户使用。一是作为用户态模拟器,利用动态代码翻译机制来执行不同于主机架构的代码。二是作为虚拟机监管器,模拟全系统,利用其他VMM(Xen, KVM, etc)来使用硬件提供的虚拟化支持,创建接近于主机性能的虚拟机。

可以使用qemu的硬件特征和CPUID指令来检测程序是否运行在qemu虚拟机里面。

 

QEMU的硬件特征为:

CPU:Name = QEMU Virtual CPU Version

DISK:Caption=QEMU HARDDISK

BIOS:Manufacturer=Seabios

CDROM:Caption=QEMU QEMU DVD-ROM

Name=QEMU QEMU DVD-ROM

 

特殊指令:CPUID,使用的功能号为eax= 0x80000002,这样的话,CPUID指令将提取处理器商标的字符串,在qemu下面是QEMU Virtual CPU VersionQEMU Virtual CPU Version

 

3、XEN

 

硬件特征:

DISK:Caption=XENSRC PVDISK SCSI Disk Device

BIOS:Manufacturer=Xen

CDROM:Caption=QEMU QEMU DVD-ROM ATA Device

Name=QEMU QEMU DVD-ROM ATA Device

SCSI控制器:Catption=Citrix PV Storage Host Adapter

 

特殊指令:使用CPUID指令,类型如下:XEN

 

XEN

 

4、BOCHS

Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。

 

检测方法通过硬件特征和特殊指令

硬件特征

光驱:  Caption=BOCHS Generic CD-ROM        Name=BOCHS Generic CD-ROM

BIOS:   BiosVersion=BOCHS -1            Manufacturer=The Bochs Project

SMBIOSVersion=Bochs         Version=BOCHS -1

 

特殊指令:CPUID

功能号如下:BOCHS

 

执行指令后如果返回值:eax=0x40  ebx=0x40  ecx=0x3  edx=0x20,那么程序运行在虚拟机中。BOCHS

头像
  • ¥ 58元
  • 市场价:58元
  • ¥ 99.0元
  • 市场价:159.0元
  • ¥ 159.0元
  • 市场价:499.0元
  • ¥ 89.0元
  • 市场价:129.0元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: