恶意样本分析手册-虚拟机检测篇(下)

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

虚拟机检测

一、VMWare

1.1查找注册表

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

HKEY_LOCAL_MACHINE_SYSTEM_ControlSet001\Services\VMware Pyhsical Disk Helper Service

 

1.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;

}

 

1.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");

}

1.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

1.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);

}

 

1.6检测系统对象

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

图:XP下检测结果

图:win7下检测结果

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

1.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

2.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.2检测系统对象

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

3.1搜索注册表项

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

3.2CPUID

原理介绍:当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.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

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

3.4搜索特定进程

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

VBoxService.exe

VBoxTray.exe

3.5查找底层模块

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

VBoxGuest.sys

VBoxSF.sys

VBoxMouse.sys

VBoxVideo.sys

VBoxDisp.dll

四、SandBox

4.1检测系统对象

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

4.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;

}

 

 

4.3检测SbieDll.dll与API完整性

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

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

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

4.4检测CPU个数

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

4.5可成功提权的进程个数

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

图:主机运行结果

图:沙箱运行结果

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

5.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,类型如下:

检测结果如下图所示:

5.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 Version

5.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指令,类型如下:

图:检测结果

5.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

功能号如下:

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

图:检测结果

声 明

本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。

关于绿盟科技

北京神州绿盟信息安全科技股份有限公司(简称绿盟科技)成立于2000年4月,总部位于北京。在国内外设有30多个分支机构,为政府、运营商、金融、能源、互联网以及教育、医疗等行业用户,提供具有核心竞争力的安全产品及解决方案,帮助客户实现业务的安全顺畅运行。
基于多年的安全攻防研究,绿盟科技在网络及终端安全、互联网基础安全、合规及安全管理等领域,为客户提供入侵检测/防护、抗拒绝服务攻击、远程安全评估以及Web安全防护等产品以及专业安全服务。
北京神州绿盟信息安全科技股份有限公司于2014年1月29日起在深圳证券交易所创业板上市交易,股票简称:绿盟科技,股票代码:300369。

如果您需要了解更多内容,可以
加入QQ群:570982169
直接询问:010-68438880

Spread the word. Share this post!

Meet The Author

Leave Comment