本帖最后由 梦幻的彼岸 于 2021-5-25 11:12 编辑
备注
原文地址:https://evasions.checkpoint.com/techniques/processes.html
原文标题:Evasions: Processes
更新日期:2021年5月21日
此文后期:根据自身所学进行内容扩充
因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。
目录
- 进程和库的检测方法
- 1.检查特定的正在运行进程和已加载的库
- 1.1. 检查特定进程是否正在运行
- 1.2. 检查进程地址空间中是否加载了特定的库
- 1.3. 检查特定库中是否存在特定函数
- 1.4. 反制措施
- 2.检查进程地址空间中是否存在特定的伪装(仅限于Sandboxie)
- 2.1. 反制措施
- 归功于
进程和库的检测方法
虚拟环境启动了一些特定的辅助进程,这些进程在通常的主机操作系统中没有被执行。还有一些特定的模块被加载到进程地址空间。
1.检查特定的正在运行进程和已加载的库
1.1. 检查特定进程是否正在运行
使用的函数:
- CreateToolhelp32Snapshot
- psapi.EnumProcesses (WinXP, Vista)
- kernel32.EnumProcesses (Win7+)
代码样本:
[C++] 纯文本查看 复制代码 check_process_is_running("vmtoolsd.exe"); // sample value from the table
bool check_process_is_running(const std::string &proc_name) {
HANDLE hSnapshot;
PROCESSENTRY32 pe = {};
pe.dwSize = sizeof(pe);
bool present = false;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
if (Process32First(hSnapshot, &pe)) {
do {
if (!StrCmpI(pe.szExeFile, proc_name.c_str())) {
present = true;
break;
}
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
return present;
}
识别标志:
没有提供识别标志,因为很难说清楚进程的快照中到底查询了什么。
检测表:
检查以下进程是否正在运行: | 检测 | 进程 | JoeBox | joeboxserver.exe | joeboxcontrol.exe | Parallels | prl_cc.exe | prl_tools.exe | VirtualBox | vboxservice.exe | vboxtray.exe | VirtualPC | vmsrvc.exe | vmusrvc.exe | VMware | vmtoolsd.exe | vmacthlp.exe | vmwaretray.exe | vmwareuser.exe | vmware.exe | vmount2.exe | Xen | xenservice.exe | xsvc_depriv.exe | WPE Pro | WPE Pro.exe |
注意:WPE Pro是一个嗅探器,不是虚拟机,但它与虚拟机检测一起使用。
1.2. 检查进程地址空间中是否加载了特定的库
使用的函数:
代码样本:
[C++] 纯文本查看 复制代码 VOID loaded_dlls()
{
/* Some vars */
HMODULE hDll;
/* Array of strings of blacklisted dlls */
TCHAR* szDlls[] = {
_T("sbiedll.dll"),
_T("dbghelp.dll"),
_T("api_log.dll"),
_T("dir_watch.dll"),
_T("pstorec.dll"),
_T("vmcheck.dll"),
_T("wpespy.dll"),
};
WORD dwlength = sizeof(szDlls) / sizeof(szDlls[0]);
for (int i = 0; i < dwlength; i++)
{
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process loaded modules contains: %s "),
szDlls[i]);
/* Check if process loaded modules contains the blacklisted dll */
hDll = GetModuleHandle(szDlls[i]);
if (hDll == NULL)
print_results(FALSE, msg);
else
print_results(TRUE, msg);
}
}
该代码样本的作者:al-khaser项目
识别标志:
如果以下函数包含其唯一的参数来自于列表`库`。
- GetModuleHandle(module_name)
那么这就表明应用程序试图使用这种规避技术。
检测表:
检查进程地址空间中是否加载了下列库: | 检测 | 库 | CWSandbox | api_log.dll | dir_watch.dll | pstorec.dll | Sandboxie | sbiedll.dll | ThreatExpert | dbghelp.dll | VirtualPC | vmcheck.dll | WPE Pro | wpespy.dll |
注意:WPE Pro是一个嗅探器,不是虚拟机,但它与虚拟机检测一起使用。
1.3. 检查特定库中是否存在特定函数
使用的函数(请参阅有关本机函数的注释):
- kernel32.GetProcAddress
- kernel32.LdrGetProcedureAddress (called internally)
- ntdll.LdrGetProcedureAddress
- ntdll.LdrpGetProcedureAddress (called internally)
代码样本:
[C++] 纯文本查看 复制代码 BOOL wine_exports()
{
/* Some vars */
HMODULE hKernel32;
/* Get kernel32 module handle */
hKernel32 = GetModuleHandle(_T("kernel32.dll"));
if (hKernel32 == NULL) {
print_last_error(_T("GetModuleHandle"));
return FALSE;
}
/* Check if wine_get_unix_file_name is exported by this dll */
if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL) // sample value from the table
return FALSE;
else
return TRUE;
}
该代码样本的作者:al-khaser项目
识别标志:
如果以下函数包含列表 "函数 "中的第2个参数,并且第1个参数是表中匹配 "库 "名称的地址。
- kernel32.GetProcAddress(lib_handle, func_name)
- kernel32.LdrGetProcedureAddress(lib_handle, func_name)
- ntdll.LdrGetProcedureAddress(lib_handle, func_name)
- ntdll.LdrpGetProcedureAddress(lib_handle, func_name)
那么这就表明应用程序试图使用这种规避技术。
检测表:
检查以下函数是否存在于以下库中: | 检测 | 库 | 函数 | Wine | kernel32.dll | wine_get_unix_file_name | ntdll.dll | wine_get_version |
1.4. 反制措施
- 对于进程:从枚举中排除目标进程或终止它们。
- 对于库:将它们从PEB的枚举列表中排除。
- 对于库中的函数:拦截适当的函数并将其参数与目标参数进行比较。
2. 检查进程地址空间中是否存在特定的伪装(仅限于Sandboxie)。
使用的函数:
代码样本:
[C++] 纯文本查看 复制代码 BOOL AmISandboxied(LPVOID lpMinimumApplicationAddress, LPVOID lpMaximumApplicationAddress)
{
BOOL IsSB = FALSE;
MEMORY_BASIC_INFORMATION RegionInfo;
ULONG_PTR i, k;
SIZE_T Length = 0L;
i = (ULONG_PTR)lpMinimumApplicationAddress;
do {
NTSTATUS Status = NtQueryVirtualMemory(GetCurrentProcess(),
(PVOID)i,
MemoryBasicInformation,
&RegionInfo,
sizeof(MEMORY_BASIC_INFORMATION),
&Length);
if (NT_SUCCESS(Status)) {
// Check if executable code
if (((RegionInfo.AllocationProtect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) &&
((RegionInfo.State & MEM_COMMIT) == MEM_COMMIT)) {
for (k = i; k < i + RegionInfo.RegionSize; k += sizeof(DWORD)) {
if (
(*(PDWORD)k == 'kuzt') ||
(*(PDWORD)k == 'xobs')
)
{
IsSB = TRUE;
break;
}
}
}
i += RegionInfo.RegionSize;
}
else {
i += 0x1000;
}
} while (i < (ULONG_PTR)lpMaximumApplicationAddress);
return IsSB;
}
Take a look at VMDE project sources.
看看VMDE项目源代码。
识别标志:
没有提供识别标志,因为很难说在检查内存缓冲区时到底查询了什么。
2.1. 反制措施
从内存中抹除现在的伪装
归功于
归功于开源项目,代码样本来自该项目:
尽管Check Point工具InviZzzible已经实现了所有这些功能,但由于代码的模块化结构,需要更多的空间来展示这个工具的代码样本,以达到相同的目的。这就是为什么我们决定在整个百科全书中使用其他伟大的开源项目作为例子。
|