本文为看雪论坛优秀文章
看雪论坛作者ID:gmhax
一
基于特征的检测
1.1 文件以及目录
GetFileAttributes
、etModuleHandle
通常,各种 hypervisor 会在虚拟机上安装驱动程序和其他软件,以使客户机能够利用 hypervisor 提供的功能。恶意软件可以搜索这些文件、目录或进程的存在。VMware 虚拟机中可能会有如下的文件列表:
C:Program FilesVMware
C:WindowsSystem32vm3dc003.dll
C:WindowsSystem32vm3ddevapi64-debug.dll
C:WindowsSystem32vm3ddevapi64-release.dll
C:WindowsSystem32vm3ddevapi64-stats.dll
C:WindowsSystem32vm3ddevapi64.dll
C:WindowsSystem32vm3dgl64.dll
C:WindowsSystem32vm3dglhelper64.dll
C:WindowsSystem32vm3dservice.exe
C:WindowsSystem32vm3dum64-debug.dll
C:WindowsSystem32vm3dum64-stats.dll
C:WindowsSystem32vm3dum64.dll
C:WindowsSystem32vm3dum64_10-debug.dll
C:WindowsSystem32vm3dum64_10-stats.dll
C:WindowsSystem32vm3dum64_10.dll
C:WindowsSystem32vm3dum64_loader.dll
C:WindowsSystem32vmGuestLib.dll
C:WindowsSystem32vmGuestLibJava.dll
C:WindowsSystem32vmhgfs.dll
C:WindowsSystem32VMWSU.DLL
C:WindowsSystem32vsocklib.dll
C:WindowsSystem32driversvm3dmp.sys
C:WindowsSystem32driversvm3dmp_loader.sys
C:WindowsSystem32driversvm3dmp-debug.sys
C:WindowsSystem32driversvm3dmp-stats.sys
C:WindowsSystem32driversvmnet.sys
C:WindowsSystem32driversvmmouse.sys
C:WindowsSystem32driversvmusb.sys
C:WindowsSystem32driversvmci.sys
C:WindowsSystem32driversvmhgfs.sys
C:WindowsSystem32driversvmmemctl.sys
C:WindowsSystem32driversvmx86.sys
C:WindowsSystem32driversvmrawdsk.sys
C:WindowsSystem32driversvmusbmouse.sys
C:WindowsSystem32driversvmkdb.sys
C:WindowsSystem32driversvmnetuserif.sys
C:WindowsSystem32driversvmnetadapter.sys
1.2 Devices
CreateFile
在Windows虚拟机中,虚拟机通常拥有独特命名的 “devices”。
◆\.HGFS
,主机和虚拟机之间共享的文件系统
◆\.vmci
,虚拟机和主机之间的通信管道
1.3 MAC 地址
GetAdaptersAddresses
、GetAdaptersInfo
、Netbios
Hypervisors 通常为虚拟机提供虚拟化的网卡(NICs),具有独占于hypervisor供应商的MAC地址。
◆00:50:56:XX:XX:XX
◆00:1C:14:XX:XX:XX
◆00:0C:29:XX:XX:XX
◆00:05:69:XX:XX:XX
1.4 BIOS 字符串
RegOpenKeyEx
、RegQueryValueEx
虚拟化产品通常会附带一个基本输入/输出系统(BIOS),其中包含虚拟机特有的字符串。可以通过检查Windows注册表来查看。
HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystem
中键值 “SystemBiosVersion” 包含 “VMware, Inc.”HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemBIOS
中包含键值-
“BIOSVendor” 为 “VMware, Inc.”
-
“BIOSVersion” 的起始字符串为 “VM.”
-
“SystemManufacturer” 为 “VMware, Inc.”
-
“SystemProductName” 包含 “VMware.”
HKEY_LOCAL_MACHINESYSTEMControlSet001ControlSystemInformation
中也有类似的信息1.5 其他 Windows 注册表项
HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPScsiScsi Port 0Scsi Bus 0Target Id 0Logical Unit Id 0
HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPScsiScsi Port 1Scsi Bus 0Target Id 0Logical Unit Id 0
HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPScsiScsi Port 2Scsi Bus 0Target Id 0Logical Unit Id 0
HKEY_LOCAL_MACHINESystemCurrentControlSetServicesDiskEnum
HKEY_LOCAL_MACHINESystemCurrentControlSetEnumIDE
HKEY_LOCAL_MACHINESystemCurrentControlSetEnumSCSI
1.6 SMBIOS 字符串
GetSystemFirmwareTable
System Management BIOS 是由BIOS读取的一组数据结构。虚拟机会带有有特殊的字符串。VMware 虚拟机会带有 “VMware”。
1.7 ACPI 字符串
GetSystemFirmwareTable
Advanced Configuration and Power Interface (ACPI) 是操作系统通过 BIOS 或 UEFI 与各种硬件组件进行通信的接口。VMware 虚拟机会带有 “VMware”。
1.8 进程
CreateToolhelp32Snapshot
、Process32First
、Process32Next
一些虚拟机利会有特殊的后台进程。这些进程主要提供一些方便的功能,例如自动配置屏幕分辨率和配置网络设置等。
◆Vmtoolsd.exe
◆Vmwaretray.exe
◆Vmwareuser.exe
◆VGAuthService.exe
◆Vmacthlp.exec
1.9 硬盘硬件ID以及名称
SetupDiGetClassDevs
、SetupDiGetDeviceRegistryProperty
Win32/Winwebsec的一些变种使用了一种通过 Setup API来检查硬盘设备名的方法。类似的也可以检测硬盘硬件ID。
1.10 通过 WMI 获取硬件信息
VOID CheckBIOSSerialNumberWMI()
{
IWbemServices* pSvc = NULL;
IWbemLocator* pLoc = NULL;
IEnumWbemClassObject* pEnumerator = NULL;
BOOL bFound = FALSE;
HRESULT hRes;
// Init WMI
if (!InitWMI(&pSvc, &pLoc, _T("ROOT\CIMV2")))
return;
// If success, execute the desired query
if (!ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BIOS")))
return;
// Get the data from the query
IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;
VARIANT vtProp;
while (pEnumerator)
{
hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn)
break;
// Get the value of the Name property
VariantInit(&vtProp);
hRes = pclsObj->Get(_T("SerialNumber"), 0, &vtProp, 0, 0);
if (SUCCEEDED(hRes)) {
if (vtProp.vt == VT_BSTR) {
if (StrStrI(vtProp.bstrVal, _T("VMWare")) != 0)
{
bFound = TRUE;
VariantClear(&vtProp);
pclsObj->Release();
break;
}
}
VariantClear(&vtProp);
}
// release the current result object
pclsObj->Release();
}
// Cleanup
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
PrintResult(bFound, _T("Checking SerialNumber from BIOS using WMI"));
}
SELECT * FROM Win32_Fan // 风扇
SELECT * FROM Win32_CacheMemory //
SELECT * FROM Win32_VoltageProbe // 电压探针
SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation // 热区信息
SELECT * FROM CIM_Memory // 物理内存
SELECT * FROM CIM_Sensor // 传感器设备
SELECT * FROM CIM_NumericSensor // 数字传感器
SELECT * FROM CIM_TemperatureSensor // 温度传感器
SELECT * FROM CIM_VoltageSensor // 电压传感器
二
基于指令的检测
2.1 IN
bool isVmwarePresent()
{
__try {
_asm {
mov eax, 0x564d5868 // 'VMXh'
mov ebx, 0
mov cx, 1
mov dx, 0x5658 // 'VX'
in eax, dx
}
return true;
}
__except (GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION) {
return false;
}
}
2.2 CPUID
BOOL CheckCPUIDVendor()
{
INT CPUInfo[4] = { -1 };
CHAR szHypervisorVendor[0x40];
__cpuid(CPUInfo, 0x40000000);
SecureZeroMemory(szHypervisorVendor, sizeof(szHypervisorVendor));
memcpy(szHypervisorVendor, CPUInfo + 1, 12);
if (_strcmpi(szHypervisorVendor, "VMwareVMware") == 0)
return TRUE;
return FALSE;
}
BOOL CheckCPUIDVendor()
{
INT CPUInfo[4] = { -1 };
__cpuid(CPUInfo, 1);
if ((CPUInfo[2] >> 31 ) & 1)
return TRUE;
return FALSE;
}
BOOL rdtsc_diff_vmexit()
{
ULONGLONG tsc1 = 0;
ULONGLONG tsc2 = 0;
ULONGLONG avg = 0;
INT cpuInfo[4] = {};
// Try this 10 times in case of small fluctuations
for (INT i = 0; i < 10; i++)
{
tsc1 = __rdtsc();
__cpuid(cpuInfo, 0);
tsc2 = __rdtsc();
// Get the delta of the two RDTSC
avg += (tsc2 - tsc1);
}
// We repeated the process 10 times so we make sure our check is as much reliable as we can
avg = avg / 10;
return (avg < 1000 && avg > 0) ? FALSE : TRUE;
}
2.3 SIDT(已失效)
2.4 SGDT(已失效)
2.5 SLDT(已失效)
2.6 STR(已失效)
2.7 SMSW(已失效)
2.8 VM “Synthetic Instructions”(已失效)
bool IsVmcpuidSupported()
{
bool supported = true;
void* mempool;
char vmcpuid[] = "x0FxC7xC8x01x00"; // VMCPUID OPCODE
mempool = malloc(sizeof(vmcpuid));
memcpy(mempool, &vmcpuid, sizeof(vmcpuid));
DWORD prevAccess;
VirtualProtect(mempool, sizeof(vmcpuid), PAGE_EXECUTE_READ, &prevAccess);
__try {
((void(*)())mempool)();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
supported = false;
}
return supported;
}
CMPXCHG8B EAX
ADD DWORD PTR DS:[EAX],EAX
三
其他检测方法
3.1 Thermal Zone Temperature
function Get-AntiVMwithTemperature {
$t = Get-WmiObject MSAcip_ThermalZoneTemperature -Namespace "root/wmi"
$valorTempKelvin = $t.CurrentTemperature / 10
$valorTempCelsius = $valorTempKelvin - 273.15
$valorTempFashrenheit = (9/5) * $valorTempCelsius + 32
return $valorTempCelsius.ToString() + " C : " + valorTempFashrenheit.ToString() +
" F : " + $valorTempKelvin.ToString() + "K"
}
Anti-VM Technique with MSAcpi_ThermalZoneTemperature
3.2 IP Timestamp Patterns
M. Noorafiza, H. Maeda, T. Kinoshita and R. uda, "Virtual Machines Detection Methods using IP Timestamps pattern Characteristic," vol. 8, 2016
3.3 CPU Detail Anomalies
3.4 Physical memory resource maps
VM Detection Tricks, Part 1: Physical memory resource maps
3.5 Driver Thread Fingerprinting
VM Detection Tricks, Part 2: Driver Thread Fingerprinting
3.6 基于鼠标行为的方法
◆GetTickCount函数调用两次,间隔20秒休眠。如果GetTickCount值没有改变(即时间已经加速),恶意软件将终止自身。
◆连续两次调用GetCursorPos函数。如果鼠标在X轴上的位置发生了变化(即鼠标位置是随机生成的),恶意软件将终止自身。
◆调用GetGlobalMemoryStatusEx。如果实际物理内存的数量小于1.5GB,恶意软件将终止自身
◆只有左键(物理)鼠标按钮按下至少三次后(在无限循环中查询GetAsyncKeyState),负载才开始。
ESET_Okrum_and_Ketrican.pdf
参考
转自:网络安全与取证研究
原文始发于微信公众号(电子物证):【虚拟机检测技术】
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论