简单介绍
通用的一些查询方式
- 检查用户名是否特定
- GetUserNameA/W
- 检查计算机名称是否特定
- GetComputerNameA/W
- 检查主机名是否特定
- GetComputerNameExA/W
- 检查总 RAM 是否较低
- GetMemoryStatusEx
- 直接 syscall 调用内核函数,等等。。。。
- 检查处理器数量是否较低
- GetSystemInfo
- 利用内联汇编或内部函数从 PEB 中获取处理器数量
- 通过 KUSER_SHARED_DATA 中获取
__declspec(naked)
DWORD get_number_of_processors() {
__asm {
; get pointer to Process Environment Block (PEB)
mov eax, fs:0x30
; read the field containing target number
mov eax, [eax + 0x64]
; return from function
retn
}
}__declspec(naked)
DWORD get_number_of_active_processors() {
__asm {
mov eax, 0x7ffe0000 ; KUSER_SHARED_DATA structure fixed address
mov eax, byte ptr [eax+0x3c0] ; checking ActiveProcessorCount
retn ; return from function
}
}- 检查硬盘驱动器大小和可用空间是否较小
- 检查系统正常运行时间是否较短
通过文件系统检测
检查特定文件是否存在
可以先通过编写一些获取信息的程序上传到云沙箱或者虚拟设备获取特征,根据这些特征编写对应的应对脚本。或者参考已经披露出来的一些沙箱的特征,针对性的编写对抗代码。
比如说我们用现在的主流沙箱微步云为例:
- 编写一个载荷,获取关键文件信息和硬件信息。
- 上传到云沙箱中,通过截图反馈获得沙箱的一些信息
- 在我们的载荷中添加对这些关键信息的检测,从而绕过这些检测。

检查特定目录是否存在
BOOL is_DirectoryExists(TCHAR* szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
/*
Check against VMware blacklisted directory
*/
BOOL vmware_dir()
{
TCHAR szProgramFile[MAX_PATH];
TCHAR szPath[MAX_PATH] = _T("");
TCHAR szTarget[MAX_PATH] = _T("VMware\\");
if (IsWoW64())
ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
else
SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
PathCombine(szPath, szProgramFile, szTarget);
return is_DirectoryExists(szPath);
}其余的方法
- 检查可执行文件的完整路径是否包含特定字符串之一
- 检查可执行文件是否从特定目录运行
- 检查物理磁盘驱动器根目录中是否存在具有特定名称的可执行文件
通过注册表检测
检查特定注册表路径是否存在
/* sample of usage: see detection of VirtualBox in the table below to check registry path */
int vbox_reg_key7() {
return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\FADT\\VBOX__");
}
/* code is taken from "pafish" project, see references on the parent page */
int pafish_exists_regkey(HKEY hKey, char * regkey_s) {
HKEY regkey;
LONG ret;
/* regkey_s == "HARDWARE\\ACPI\\FADT\\VBOX__"; */
if (pafish_iswow64()) {
ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ | KEY_WOW64_64KEY, ®key);
}
else {
ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ, ®key);
}
if (ret == ERROR_SUCCESS) {
RegCloseKey(regkey);
return TRUE;
}
else
return FALSE;
}一些可以检测的注册表路径(但是注意访问这些特殊的注册表路径可能会被 edr 监控,在云沙箱中报毒)
| Detect | Registry path | Details (if any) |
|---|---|---|
| [general] | HKLM\Software\Classes\Folder\shell\sandbox | |
| Hyper-V | HKLM\SOFTWARE\Microsoft\Hyper-V | |
| Hyper-V | HKLM\SOFTWARE\Microsoft\VirtualMachine | |
| Hyper-V | HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters | Usually “HostName” and “VirtualMachineName” values are read under this path |
| Hyper-V | HKLM\SYSTEM\ControlSet001\Services\vmicheartbeat | |
| Hyper-V | HKLM\SYSTEM\ControlSet001\Services\vmicvss | |
| Hyper-V | HKLM\SYSTEM\ControlSet001\Services\vmicshutdown | |
| Hyper-V | HKLM\SYSTEM\ControlSet001\Services\vmicexchange | |
| Parallels | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_1AB8* | Subkey has the following structure: VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZ&REV_WW |
| Sandboxie | HKLM\SYSTEM\CurrentControlSet\Services\SbieDrv | |
| Sandboxie | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Sandboxie | |
| VirtualBox | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_80EE* | Subkey has the following structure: VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZ&REV_WW |
| VirtualBox | HKLM\HARDWARE\ACPI\DSDT\VBOX__ | |
| VirtualBox | HKLM\HARDWARE\ACPI\FADT\VBOX__ | |
| VirtualBox | HKLM\HARDWARE\ACPI\RSDT\VBOX__ | |
| VirtualBox | HKLM\SOFTWARE\Oracle\VirtualBox Guest Additions | |
| VirtualBox | HKLM\SYSTEM\ControlSet001\Services\VBoxGuest | |
| VirtualBox | HKLM\SYSTEM\ControlSet001\Services\VBoxMouse | |
| VirtualBox | HKLM\SYSTEM\ControlSet001\Services\VBoxService | |
| VirtualBox | HKLM\SYSTEM\ControlSet001\Services\VBoxSF | |
| VirtualBox | HKLM\SYSTEM\ControlSet001\Services\VBoxVideo | |
| VirtualPC | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_5333* | Subkey has the following structure: VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZ&REV_WW |
| VirtualPC | HKLM\SYSTEM\ControlSet001\Services\vpcbus | |
| VirtualPC | HKLM\SYSTEM\ControlSet001\Services\vpc-s3 | |
| VirtualPC | HKLM\SYSTEM\ControlSet001\Services\vpcuhub | |
| VirtualPC | HKLM\SYSTEM\ControlSet001\Services\msvmmouf | |
| VMware | HKLM\SYSTEM\CurrentControlSet\Enum\PCI\VEN_15AD* | Subkey has the following structure: VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZ&REV_WW |
| VMware | HKCU\SOFTWARE\VMware, Inc.\VMware Tools | |
| VMware | HKLM\SOFTWARE\VMware, Inc.\VMware Tools | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\vmdebug | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\vmmouse | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\VMTools | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\VMMEMCTL | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\vmware | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\vmci | |
| VMware | HKLM\SYSTEM\ControlSet001\Services\vmx86 | |
| VMware | HKLM\SYSTEM\CurrentControlSet\Enum\IDE\CdRomNECVMWar_VMware_IDE_CD* | |
| VMware | HKLM\SYSTEM\CurrentControlSet\Enum\IDE\CdRomNECVMWar_VMware_SATA_CD* | |
| VMware | HKLM\SYSTEM\CurrentControlSet\Enum\IDE\DiskVMware_Virtual_IDE_Hard_Drive* | |
| VMware | HKLM\SYSTEM\CurrentControlSet\Enum\IDE\DiskVMware_Virtual_SATA_Hard_Drive* | |
| Wine | HKCU\SOFTWARE\Wine | |
| Wine | HKLM\SOFTWARE\Wine | |
| Xen | HKLM\HARDWARE\ACPI\DSDT\xen | |
| Xen | HKLM\HARDWARE\ACPI\FADT\xen | |
| Xen | HKLM\HARDWARE\ACPI\RSDT\xen | |
| Xen | HKLM\SYSTEM\ControlSet001\Services\xenevtchn | |
| Xen | HKLM\SYSTEM\ControlSet001\Services\xennet | |
| Xen | HKLM\SYSTEM\ControlSet001\Services\xennet6 | |
| Xen | HKLM\SYSTEM\ControlSet001\Services\xensvc | |
| Xen | HKLM\SYSTEM\ControlSet001\Services\xenvdb |
检查特定注册表项是否包含指定字符串
通过 CPU 特征检测
CPUID 检测供应商 ID
__declspec(naked) void get_cpuid_vendor(char *vendor_id) {
__asm {
; save non-volatile register
push ebx
; nullify output registers
xor ebx, ebx
xor ecx, ecx
xor edx, edx
; call cpuid with argument in EAX
mov eax, 0x40000000
cpuid
; store vendor_id ptr to destination
mov edi, vendor_id
; move string parts to destination
mov eax, ebx ; part 1 of 3 from EBX
stosd
mov eax, ecx ; part 2 of 3 from ECX
stosd
mov eax, edx ; part 3 of 3 from EDX
stosd
; restore saved non-volatile register
pop ebx
; return from function
retn
}
}对应的一些厂商
| Detect | EAX as argument to CPUID | String |
|---|---|---|
| FreeBSD HV | 0 x 40000000 | bhyve bhyve |
| Hyper-V | 0 x 40000000 | Microsoft Hv |
| KVM | 0 x 40000000 | KVMKVMKVM |
| Parallels | 0 x 40000000 | prl hyperv |
| VirtualBox | 0 x 40000000 | VBoxVBoxVBox |
| VirtualPC | 0 x 40000000 | Microsoft Hv |
| VMware | 0 x 40000000 | VMwareVMware |
| Xen | 0 x 40000000 | XenVMMXenVMM |
通过一些硬件设备检测
-
检查硬盘是否有特殊名字
- 一些沙箱的硬盘有特殊命名
-
检查是否存在音频设备
-
检查 CPU 温度是否可用
- 通过 wmi 接口检查
wmic /namespace:\\root\WMI path MSAcpi_ThermalZoneTemperature get CurrentTemperature
- 通过 wmi 接口检查
特定的网络属性
一些虚拟环境的厂商会给虚拟设备硬编码一些特殊的值,比如 MAC 地址或者网络适配器的名称。
可以通过这些函数进行检测:
- GetAdaptersAddresses(AF_UNSPEC, …)
- GetAdaptersInfo()
一些厂商可能为虚拟网卡配置的 mac 地址:
| Check if MAC address starts from one of the following values: | ||
|---|---|---|
| Detect | MAC address starts with | Bytes |
| Parallels | 00:1C:42 | \x00\x1C\x42 |
| VirtualBox | 08:00:27 | \x08\x00\x27 |
| VMware | 00:05:69 | \x00\x05\x69 |
| VMware | 00:0C:29 | \x00\x0C\x29 |
| VMware | 00:1C:14 | \x00\x1C\x14 |
| VMware | 00:50:56 | \x00\x50\x56 |
| Xen | 00:16:E3 | \x00\x16\xE3 |
HOOKS
检查一些比较敏感的函数是否被 Hook 了(用户态)
-
ReadFile
-
DeleteFile
-
CreateProcessA/W
-
…
-
Comparing first N bytes with \xCC - software breakpoint (int 3), not connected with hooks directly but still a suspicious behavior.
- 检查是否存在调试/篡改状态,通常是调试的时候才会插入 \xCC
-
Comparing first N bytes with \xE 9 (call) or with \xEB (jmp instruction) — typical instructions for redirecting execution.
- 检查是否存在 jump 到别处的命令
-
Checking for push/ret combo for execution redirection.
- push/ret 组合跳转
- 比如
push 0 x 12345678后再ret相当于 jump 到这个地址
其他
-
浏览器记录
- 存在开源项目可以解析 chrome/edge 浏览器的 cookie,可以根据 cookie 的数量判断是否存在人类活动痕迹
-
文件历史
-
鼠标活动
- 一篇关于鼠标活动向量检测分析报告 LummaC2 Stealer
-
社会工程学
- 弹窗诱导用户点击
- 链接诱导
- …
一些关于运用在 CTF 中的思路
相比于直接检测用户的电脑环境,我们可以在逻辑中加入对指定注册表项/结构体环境/文件系统/…的检测,只有符合这些环境的用户才能成功运行程序进行下一步分析,比如今年的腾讯游戏安全竞赛初赛的赛题。