簡單的沙箱反調試
前言
很多殺軟都有自己的後端雲沙箱,這些沙箱能夠模擬出軟體執行所需的運行環境,通過進程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調試,相當於另一個進程打開了我們保護的進程,可以看到直接結束了
參考
//github.com/Airboi/bypass-av-note