虚拟机反检测技术:进程

目录

  • 进程和库的检测方法

  • 1.检查特定的正在运行进程和已加载的库

  • 1.1. 检查特定进程是否正在运行

  • 1.2. 检查进程地址空间中是否加载了特定的库

  • 1.3. 检查特定库中是否存在特定函数

  • 1.4. 反制措施

  • 2.检查进程地址空间中是否存在特定的伪装(仅限于Sandboxie)

  • 2.1. 反制措施

  • 归功于

进程和库的检测方法
虚拟环境启动了一些特定的辅助进程,这些进程在通常的主机操作系统中没有被执行。还有一些特定的模块被加载到进程地址空间。
1.检查特定的正在运行进程和已加载的库
1.1. 检查特定进程是否正在运行
使用的函数:

  • CreateToolhelp32Snapshot

  • psapi.EnumProcesses (WinXP, Vista)

  • kernel32.EnumProcesses (Win7+)

代码样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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. 检查进程地址空间中是否加载了特定的库
使用的函数:

  • GetModuleHandle

代码样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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)

代码样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)。
使用的函数:

  • NtQueryVirtualMemory

代码样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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. 反制措施
从内存中抹除现在的伪装

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容