简单介绍
通用的一些查询方式
- 检查用户名是否特定
- 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_FileExists(TCHAR* szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
/*
Check against some of VMware blacklisted files
*/
VOID vmware_files()
{
/* Array of strings of blacklisted paths */
TCHAR* szPaths[] = {
_T("system32\\drivers\\vmmouse.sys"),
_T("system32\\drivers\\vmhgfs.sys"),
};
/* Getting Windows Directory */
WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]);
TCHAR szWinDir[MAX_PATH] = _T("");
TCHAR szPath[MAX_PATH] = _T("");
GetWindowsDirectory(szWinDir, MAX_PATH);
/* Check one by one */
for (int i = 0; i < dwlength; i++)
{
PathCombine(szPath, szWinDir, szPaths[i]);
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s: "), szPath);
if (is_FileExists(szPath))
print_results(TRUE, msg);
else
print_results(FALSE, msg);
}
}
检查特定目录是否存在
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 接口检查
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 中的思路
相比于直接检测用户的电脑环境,我们可以在逻辑中加入对指定注册表项/结构体环境/文件系统/……的检测,只有符合这些环境的用户才能成功运行程序进行下一步分析