簡單的沙箱反除錯

Punished發表於2021-04-19

前言

很多殺軟都有自己的後端雲沙箱,這些沙箱能夠模擬出軟體執行所需的執行環境,通過程式hook技術來對軟體執行過程中的行為進行分析,判斷其是否有敏感的操作行為,或者更高階的檢測手法是,將獲取到的程式的API呼叫序列以及其他的一些行為特徵輸入到智慧分析引擎中(基於機器學習org)進行檢測。所以,如果我們的木馬沒有做好反除錯,很容易就被沙箱檢測出來。

最簡單的反除錯的措施就是檢測父程式。一般來說,我們手動點選執行的程式的父程式都是explorer。如果一個程式的父程式不是explorer,那麼我們就可以認為他是由沙箱啟動的。那麼我們就直接exit退出,這樣,殺軟就無法繼續對我們進行行為分析了。

explorer.exe是Windows程式管理器或者檔案資源管理器,它用於管理Windows圖形殼,包括桌面和檔案管理,刪除該程式會導致Windows圖形介面無法使用。

 

 

 標頭檔案

1 #include <iostream>
2 #include <windows.h>
3 #include <tlhelp32.h>
4 #include <tchar.h>

核心程式碼

通過Loadlibrary 和 GetProcAddress 來獲取 CreateToolhelp32Snapshot函式的地址 獲取一個快照,找到當前的父程式,當然這個函式也可以直接用

HMODULE hModule = LoadLibrary(_T("Kernel32.dll"));
FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot");

鑲嵌一點組合語言進行傳參

_asm{
        push 0
        push 2
        call Address
        mov hkz, eax
    }

記得傳參是從右往左傳參 所以CreateToolhelp32Snapshot的第一個引數是 2

 

 

 第二個引數是 0 傳入0的話就是預設的當前程式

然後遍歷並返回,找到當前程式的父程式

pe.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hkz, &pe)) {
    do {
        if (pe.th32ProcessID == pid) {
            ParentProcessID = pe.th32ParentProcessID;
            break;
        }
    }while (Process32Next(hkz, &pe));
}
return ParentProcessID;

然後找到explorer.exe的Pid

 1 DWORD get_explorer_processid() {
 2     DWORD explorer_id = -1;
 3     PROCESSENTRY32 pe;
 4     HANDLE hkz;
 5     HMODULE hModule = LoadLibrary(_T("Kernel32.dll"));
 6 
 7     if (hModule == NULL) {
 8         OutputDebugString(_T("Loaddll error"));
 9         return(-1);
10     }
11     FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot");
12 
13     if (Address == NULL) {
14         OutputDebugString(_T("GetProc error"));
15         return(-1);
16     }
17 
18     _asm {
19         push 0
20         push 2
21         call Address
22         mov hkz, eax
23     }
24 
25     pe.dwSize = sizeof(PROCESSENTRY32);
26 
27     if (Process32First(hkz, &pe)) {
28         do {
29             if (_wcsicmp(pe.szExeFile, L"explorer.exe") == 0)
30             {
31                 explorer_id = pe.th32ProcessID;
32                 break;
33             }
34         }         while (Process32Next(hkz, &pe));
35     }
36     return explorer_id;
37 }

將我們程式的父程式的pid和explorer.exe 的pid進行比較,相同則執行,不同就直接退出了,我這裡是個MessageBox

void domain() {
    DWORD explorer_id = get_explorer_processid();
    DWORD parent_id = get_parent_processid(GetCurrentProcessId());
    if (explorer_id == parent_id) 
    { 
        MessageBox(NULL, L"Fine", L"OK", NULL);
    }
    else 
    {
        exit(1);
    }
}

驗證

正常啟動

 

 我們假設通過x32debug除錯,相當於另一個程式開啟了我們保護的程式,可以看到直接結束了

 

 

參考

https://github.com/Airboi/bypass-av-note

相關文章