看到了就记下,慢慢积累嘛

特征检测

文件及目录

  • 通常,各种 hypervisor 会在虚拟机上安装驱动程序和其他软件,以使客户机能够利用 hypervisor 提供的功能。恶意软件可以搜索这些文件、目录或进程的存在。VMware 虚拟机中可能会有如下的文件列表:

    C:\Program Files\VMware\
    C:\Windows\System32\vm3dc003.dll
    C:\Windows\System32\vm3ddevapi64-debug.dll
    C:\Windows\System32\vm3ddevapi64-release.dll
    C:\Windows\System32\vm3ddevapi64-stats.dll
    C:\Windows\System32\vm3ddevapi64.dll
    C:\Windows\System32\vm3dgl64.dll
    C:\Windows\System32\vm3dglhelper64.dll
    C:\Windows\System32\vm3dservice.exe
    C:\Windows\System32\vm3dum64-debug.dll
    C:\Windows\System32\vm3dum64-stats.dll
    C:\Windows\System32\vm3dum64.dll
    C:\Windows\System32\vm3dum64_10-debug.dll
    C:\Windows\System32\vm3dum64_10-stats.dll
    C:\Windows\System32\vm3dum64_10.dll
    C:\Windows\System32\vm3dum64_loader.dll
    C:\Windows\System32\vmGuestLib.dll
    C:\Windows\System32\vmGuestLibJava.dll
    C:\Windows\System32\vmhgfs.dll
    C:\Windows\System32\VMWSU.DLL
    C:\Windows\System32\vsocklib.dll
    C:\Windows\System32\drivers\vm3dmp.sys
    C:\Windows\System32\drivers\vm3dmp_loader.sys
    C:\Windows\System32\drivers\vm3dmp-debug.sys
    C:\Windows\System32\drivers\vm3dmp-stats.sys
    C:\Windows\System32\drivers\vmnet.sys
    C:\Windows\System32\drivers\vmmouse.sys
    C:\Windows\System32\drivers\vmusb.sys
    C:\Windows\System32\drivers\vmci.sys
    C:\Windows\System32\drivers\vmhgfs.sys
    C:\Windows\System32\drivers\vmmemctl.sys
    C:\Windows\System32\drivers\vmx86.sys
    C:\Windows\System32\drivers\vmrawdsk.sys
    C:\Windows\System32\drivers\vmusbmouse.sys
    C:\Windows\System32\drivers\vmkdb.sys
    C:\Windows\System32\drivers\vmnetuserif.sys
    C:\Windows\System32\drivers\vmnetadapter.sys

Devices

  • 相关 API:CreateFile
  • 在 Windows 虚拟机中,虚拟机通常拥有独特命名的 “devices”。

    • \.\HGFS,主机和虚拟机之间共享的文件系统
    • \.\vmci,虚拟机和主机之间的通信管道

MAC 地址

  • 相关API:GetAdaptersAddresses、GetAdaptersInfo、Netbios
  • Hypervisors 通常为虚拟机提供虚拟化的网卡(NICs),具有独占于 hypervisor 供应商的 MAC 地址。
  • 已知的 VMware 虚拟机的 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

BIOS 字符串

  • 相关 API:RegOpenKeyEx、RegQueryValueEx
  • 虚拟化产品通常会附带一个基本输入/输出系统(BIOS),其中包含虚拟机特有的字符串。可以通过检查Windows注册表来查看。
  • HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System 中键值 “SystemBiosVersion” 包含 “VMware, Inc.”
  • HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS 中包含键值

    “BIOSVendor” 为 “VMware, Inc.”
    “BIOSVersion” 的起始字符串为 “VM.”
    “SystemManufacturer” 为 “VMware, Inc.”
    “SystemProductName” 包含 “VMware.”
  • HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SystemInformation 中也有类似的信息

其他 Windows 注册表项

  • VMware中,以下注册表项会带有 “VMWARE” 或者 “VM” 字符串

    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Disk\Enum
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\IDE
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\SCSI

SMBIOS 字符串

  • 相关 API:GetSystemFirmwareTable
  • System Management BIOS 是由 BIOS 读取的一组数据结构。虚拟机会带有有特殊的字符串。VMware 虚拟机会带有 “VMware”。

ACPI 字符串

  • 相关 API:GetSystemFirmwareTable
  • Advanced Configuration and Power Interface (ACPI) 是操作系统通过 BIOS 或 UEFI 与各种硬件组件进行通信的接口。VMware 虚拟机会带有 “VMware”。

进程

  • 相关 API:CreateToolhelp32Snapshot、Process32First、Process32Next
  • 一些虚拟机利会有特殊的后台进程。这些进程主要提供一些方便的功能,例如自动配置屏幕分辨率和配置网络设置等。
  • VMware 虚拟机中可能会有以下进程:

    • Vmtoolsd.exe
    • Vmwaretray.exe
    • Vmwareuser.exe
    • VGAuthService.exe
    • Vmacthlp.exec

有些恶意软件还会通过进程数来检测虚拟环境,比如 ”EvilBunny“ 会检测是否存在至少 15 个进程。

硬盘硬件 ID 以及名称

  • 相关 API:SetupDiGetClassDevs、SetupDiGetDeviceRegistryProperty
  • Win32/Winwebsec 的一些变种使用了一种通过 Setup API 来检查硬盘设备名的方法。类似的也可以检测硬盘硬件 ID。


通过 WMI 获取硬件信息

  • Windows Management Instrumentation(WMI),提供了一种标准化的接口,允许程序获取系统信息并执行管理任务。WMI 是基于 COM(Component Object Model)技术构建的,并使用 WQL(WMI 查询语言)来查询数据。
  • 可以通过 WMI 获取 BIOS 序列号并查看是否带有类似“VMWARE”的字符串。类似的还可以检测 Win32_ComputerSystem 下的 Model 以及 Manufacturer 字段。

    VOID CheckBIOSSerialNumberWMI()
  • 可以通过返回结果的条目数,检查是否存在一些物理机应该有的硬件,比如:

    SELECT * FROM Win32_Fan // 风扇

指令检测

  • 某些 CPU 指令在虚拟机中执行时返回值与在物理机机上执行时返回值不同。恶意软件可以执行这些指令,并尝试根据返回值推断虚拟机的存在。虽然这些检测方法不普遍适用于所有虚拟机,且随着虚拟机的迭代也已经部分失效,但仍然有必要了解。下面列出已知的用于虚拟机检测的指令。

IN

  • IN 指令从指定的 I/O 端口读取值到指定的内存地址。I/O 端口是操作系统和 I/O 设备(如磁盘控制器和声音设备)之间的通信手段。基于 VMware 的虚拟机具有端口号为 0x5658 的 I/O 设备,允许 hypervisor 和虚拟机之间通信。通常,在非特权用户模式下运行 IN 指令将触发特权指令异常。但在 VMware 中,不会引发此类异常。VMware 公司甚至将此作为官方检测 VMware hypervisor 的手段。VMware 也提供了一个接口,允许用户“关闭”此方法。

    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;
      }
    }

CPUID

  • CPUID 是一种 x86 指令,用来获取 CPU 的各种信息。该指令通过输入 EAX 中的值来确定要在 EAX,EBX,ECX 和 EDX 寄存器中返回的信息。下面给出三种基于 CPUID 指令的检测方法。
  • 1、当 EAX=0 时, CPUID 将按 EBX,EDX 和 ECX 寄存器的顺序返回一个 12 个字符的制造商 ID 字符串。Intel CPU 返回“GenuineIntel”,而 AMD CPU 在 K5 型号之后返回“AuthenticAMD” 。当在虚拟机中运行时,ID 将被专属于某些虚拟机的自定义字符串替换。VMware 虚拟机中理论上将返回 “VmwareVmware”。

    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;
    }
  • 2、当 EAX=1 时,CPUID 将返回有关处理器功能的信息,例如处理器支持的指令。返回值 ECX 中的第 31 位确定是否存在 hypervisor。在物理机中此值为 0,在虚拟机中为 1。

    BOOL CheckCPUIDVendor()
    {
     INT CPUInfo[4] = { -1 };
     
     __cpuid(CPUInfo, 1);
     
     if ((CPUInfo[2] >> 31 ) & 1)
       return TRUE;
       return FALSE;
    }
  • 3、在虚拟机中执行 CPUID 还会触发 VM-Exit Event,使得进程从 guest 切换到 VMM。可以用 RDTSC 指令来计算这个开销。

    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;
    }

其它检测

Thermal Zone Temperature

  • 恶意软件“Win32/gravityRAT”采用了一种通过检测系统 thermal zone 来检测虚拟机存在的方法。通过使用下面的 powershell 脚本,可以轻松检查机器是否支持“MSAcip_ThermalZoneTemperature”对象。如果此脚本没有返回结果,则假定该计算机在虚拟机中,因为虚拟机默认不支持热力监控。由于 Thermal zone sensors 可以在系统的 BIOS 或 UEFI 中禁用和启用,在多个物理机上测试结果不一致,所以该方法并不可靠。

    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

IP Timestamp Patterns

  • 这种虚拟机检测方法是由 Noorafize 等人发现的 ,它基于虚拟机无法像物理机一样保持准确的时间。虚拟机通常通过与主机计算机共享时间来进行时间同步,以尝试伪装成物理机,但来自虚拟机的 IP 报文时间戳存在不一致性。研究人员发现,由于虚拟机需要与 hypervisor 进行交互,导致虚拟机的时间戳信息略有不同。为了使用此检测方法,攻击者需要向目标系统发送大量的 IP / ICMP 数据包以获取足够的信息,以推断目标机器是否为虚拟机。
    来源:M. Noorafiza, H. Maeda, T. Kinoshita and R. uda, "Virtual Machines Detection Methods using IP Timestamps pattern Characteristic," vol. 8, 2016

CPU Detail Anomalies

  • 通过检查 CPU 物理核心数、逻辑核心数和 cache 容量与实际产品配置的不一致性来检测虚拟机。
    来源:Mettrick D. Virtual machine detection through Central Processing Unit (CPU) detail anomalies[D]. , 2022.

Physical memory resource maps

  • 在 Windows 中,设备驱动程序需要访问硬件资源(如内存、I/O 端口、中断等),这些资源的地址通常是硬件相关的,因此在不同的系统上地址可能会发生变化。为了方便驱动程序的编写和移植,Windows 内核提供了资源映射机制,将硬件相关的地址转换为系统相关的地址,从而使驱动程序可以在不同的系统上运行而不需要进行修改。内存翻译就是其中一种资源映射类型,它将硬件设备的物理内存地址映射为系统中的虚拟内存地址,使驱动程序可以通过虚拟地址来访问设备内存。可以通过比对虚拟地址的不同检测虚拟机环境。测试发现 Hyper-V 虚拟机具有与 00001000-000a0000 匹配的物理内存映射区域。VirtualBox 虚拟机具有与 00001000-009f000 匹配的物理内存映射区域。
    来源:VM Detection Tricks, Part 1: Physical memory resource maps

Driver Thread Fingerprinting

基于鼠标行为的方法

  • 恶意软件 Win32/Okrum 使用了基于行为的一些方法来检测沙箱:

    • GetTickCount 函数调用两次,间隔 20 秒休眠。如果 GetTickCount 值没有改变(即时间已经加速),恶意软件将终止自身。
    • 连续两次调用 GetCursorPos 函数。如果鼠标在X轴上的位置发生了变化(即鼠标位置是随机生成的),恶意软件将终止自身。
    • 调用 GetGlobalMemoryStatusEx。如果实际物理内存的数量小于 1.5GB,恶意软件将终止自身
    • 只有左键(物理)鼠标按钮按下至少三次后(在无限循环中查询 GetAsyncKeyState),负载才开始。
  • 来源:ESET_Okrum_and_Ketrican.pdf

硬盘大小检测

  • 一半虚拟机的硬盘大小不会是正常的大小,通过这个方法可以检测出来是否在虚拟机中运行。

参考内容

[1] 虚拟机检测技术整理
[2] Anti-VM Technique with MSAcpi_ThermalZoneTemperature
[3] VM Detection Tricks, Part 1: Physical memory resource maps
[4] VM Detection Tricks, Part 2: Driver Thread Fingerprinting
[[5] ESET_Okrum_and_Ketrican.pdf[6]

https://www.cnblogs.com/Sna1lGo/category/1970959.html