压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

如何利用Pafish偵測虛擬環境

本文介紹Pafish。Pafish是一個用來偵 測虛擬環境的開源工具,除了虛擬環境以外,Pafish還能偵測主流的沙箱和debug環境。由于Pafish是開源的,病毒作者們可以很容易的重用其代 碼。Pafish的github主頁在https://github.com/a0rtega/pafish。 目前是V05.3版。

運行Pafish以后,Pafish會對各項特征進行檢查,如果沒有發現匹配特征,就顯示一個綠色的OK, 如果發現了,就顯示一個紅色的traced! 如圖所示,Pafish檢測到當前運行環境匹配virtualbox的各項特征。

virtualbox

看一下pafish的github目錄,包含以下文件

github

基本上,Pafish用一個c文件來對應一個偵測模塊。Pafish包含如下模塊:

·基于cpu的偵測: cpu.c

·偵測 調試環境: debuggers.c

·基本偵測: gensandbox.c

·偵測主流商業虛擬環境:比如vitualbox,VMware等

3 模塊介紹

3.1 基于cpu的偵測

由于架構差異,同樣的代碼在虛擬機的運行速度往往慢于實體機。Pafish用RDTSC指令來計算執行一段代碼所花費的平均CPU運行周期數。RDTSC 指令可以以極小的代價獲得高精度的 CPU 時鐘周期數(Time Stamp Counter)。用法是,先后執行兩次RDTSC,記下兩個 64-bit 整數 ret 和 ret2,那么 ret2-ret1 代表了這期間 所花費的CPU 時鐘周期數。

static?inline?unsigned?long?long?rdtsc_diff()?{
?????????????????????????????unsigned?long?long?ret,?ret2;
?????????????????????????????unsigned?eax,?edx;
?????????????????????????????__asm__?volatile("rdtsc"?:?"=a"?(eax),?"=d"?(edx));
?????????????????????????????ret??=?((unsigned?long?long)eax)?|?(((unsigned?long?long)edx)?<<?32);
?????????????????????????????__asm__?volatile("rdtsc"?:?"=a"?(eax),?"=d"?(edx));
?????????????????????????????ret2??=?((unsigned?long?long)eax)?|?(((unsigned?long?long)edx)?<<?32);
?????????????????????????????return?ret2?-?ret;
}

然后這個取差值的過程重復10次,得到平均值。如果這個平均周期差小于750的話,就認為是實體機環境,否則則認為是虛擬機環境。筆者估計Pafish選擇750作為平均周期差的是根據實踐經驗。

int?cpu_rdtsc()?{
?????????????????????????????int?i;
?????????????????????????????unsigned?long?long?avg?=?0;
?????????????????????????????for?(i?=?0;?i?<?10;?i++)?{
??????????????????????????????????????????????????????????avg?=?avg?+?rdtsc_diff();
??????????????????????????????????????????????????????????Sleep(500);
?????????????????????????????}
?????????????????????????????avg?=?avg?/?10;
?????????????????????????????return?(avg?<?750?&&?avg?>?0)???FALSE?:?TRUE;
}

另一種方法是用cpuid指令得到cpu的名稱和型號。如果名稱中包含一些特殊的字符串,比如KVM, VMware等,則確定在虛擬環境中。

static?inline?void?cpuid_vendor_00(char?*?vendor)?{
?????????????????????????????int?ebx,?ecx,?edx;
?
?????????????????????????????__asm__?volatile("cpuid"?\
???????????????????????????????????????????????????????????????????????????????????????:?"=b"(ebx),?\
?????????????????????????????????????????????????????????????????????????????????????????"=c"(ecx),?\
?????????????????????????????????????????????????????????????????????????????????????????"=d"(edx)?\
???????????????????????????????????????????????????????????????????????????????????????:?"a"(0x00));
?????????????????????????????sprintf(vendor??,?"%c%c%c%c",?ebx,?(ebx?>>?8),?(ebx?>>?16),?(ebx?>>?24));
?????????????????????????????sprintf(vendor+4,?"%c%c%c%c",?edx,?(edx?>>?8),?(edx?>>?16),?(edx?>>?24));
?????????????????????????????sprintf(vendor+8,?"%c%c%c%c",?ecx,?(ecx?>>?8),?(ecx?>>?16),?(ecx?>>?24));
?????????????????????????????vendor[12]?=?0x00;
}
?
int?cpu_known_vm_vendors(char?*?vendor)?{
?????????????????????????????const?int?count?=?4;
?????????????????????????????int?i;
?????????????????????????????string?strs[count];
?????????????????????????????strs[0]?=?"KVMKVMKVMKVM";
?????????????????????????????strs[1]?=?"Microsoft?Hv";
?????????????????????????????strs[2]?=?"VMwareVMware";
?????????????????????????????strs[3]?=?"XenVMMXenVMM";
?????????????????????????????for?(i?=?0;?i?<?count;?i++)?{
??????????????????????????????????????????????????????????if?(!memcmp(vendor,?strs[i],?12))?return?TRUE;
?????????????????????????????}
?????????????????????????????return?FALSE;
}

3.2 偵測 調試環境:

第一種方法很簡單,只需要看一下IsDebuggerPresent的返回值。IsDebuggerPresent是一個kernel32.dll中的函數,通過它可以檢測當前進程是否正在被調試(用戶模式)。

int?debug_isdebuggerpresent()?{
?????????????????????????????if?(IsDebuggerPresent())
?????????????????????????????return?TRUE;
?????????????????????????????else
?????????????????????????????return?FALSE;
}

第二種方法用到OutputDebugString。OutputDebugString用來把調試信息輸出到調試器的輸出窗口。但 是OutputDebugString只能在調試環境下執行。而在非調試環境下,OutputDebugString會產生一個錯誤。Pafish先設置 一個錯誤代碼(99)作為基準值,然后調用OutputDebugString,再取出錯誤代碼與99比較。如果運行在一個調試環境中,那么應該沒有新錯 誤產生,所以取出的錯誤代碼還是99。

int?debug_outputdebugstring()?{
?????????????????????????????DWORD?err?=?99;?/*?Random?error?*/
?????????????????????????????SetLastError(err);
?????????????????????????????/*?If?we're?been?debugging,?this?shouldn't
?????????????????????????????drop?an?error.?*/
?????????????????????????????OutputDebugString("useless");
?????????????????????????????if?(GetLastError()?==?err){
??????????????????????????????????????????????????????????return?TRUE;
?????????????????????????????}
?????????????????????????????else?{
??????????????????????????????????????????????????????????return?FALSE;
?????????????????????????????}
}

3.3 基本偵測:

由于硬件的限制,很多人在創建虛擬機的時候往往只選擇夠用的配置,而不是高配置。(至少配置不會高于實體機)基本偵測是基于鼠標的移動,CPU的數 量,硬盤和內存的大小等等。比如用戶在一段時間內沒有移動鼠標,系統只有一個CPU,硬盤小于60G,內存小于1G,這些都可能說明是一個虛擬環境。這種 偵測方法不會非常準確,比如一個服務器可能沒有配備鼠標,或者一個配置很差的舊電腦都會被誤認為是虛擬環境。但是從統計上看來,還是有一定意義的。

int?gensandbox_one_cpu_GetSystemInfo()?{
?????????????????????????????SYSTEM_INFO?siSysInfo;
?????????????????????????????GetSystemInfo(&siSysInfo);
?????????????????????????????return?siSysInfo.dwNumberOfProcessors?<?2???TRUE?:?FALSE;
}

第二種方法是如果當前系統的用戶名包含sandbox,virus,malware等關鍵字,則認為是在虛擬機中,當然這個檢測方法可以很容易的繞過。

int?gensandbox_username()?{
?????????????????????????????char?username[200];
?????????????????????????????size_t?i;
?????????????????????????????DWORD?usersize?=?sizeof(username);
?????????????????????????????GetUserName(username,?&usersize);
?????????????????????????????for?(i?=?0;?i?<?strlen(username);?i++)?{?/*?case-insensitive?*/
??????????????????????????????????????????????????????????username[i]?=?toupper(username[i]);
?????????????????????????????}
?????????????????????????????if?(strstr(username,?"SANDBOX")?!=?NULL)?{
??????????????????????????????????????????????????????????return?TRUE;
?????????????????????????????}
?????????????????????????????if?(strstr(username,?"VIRUS")?!=?NULL)?{
??????????????????????????????????????????????????????????return?TRUE;
?????????????????????????????}
?????????????????????????????if?(strstr(username,?"MALWARE")?!=?NULL)?{
??????????????????????????????????????????????????????????return?TRUE;
?????????????????????????????}
?????????????????????????????return?FALSE;
}

3.4 偵測商業虛擬環境

除了基本的虛擬環境以外,Pafish還可以根據指紋偵測幾種主流的虛擬機,包括sandboxie,Qemu,Virtualbox, Vmware and wine.偵測方法大同小異,這里只介紹針對virtualbox的偵測方法。

在原有的基礎上,Virtualbox提供了一些增強功能,比如virtualbox guest Additions 和共享文件夾。virtualbox guest Additions可以自動調節窗口的分辨率,把實體機的字符串復制到虛擬機里面。而 共享文件夾解決了虛擬機和實體機共享文件的問題。這些增強功能極大的提高了virtualbox的易用性。然而,福兮禍所伏。若想使用 virtualbox guest Additions,用戶需要在虛擬機上安裝一些特殊的驅動和應用程序。而這些驅動和應用基本不可能出現在實體機上。所以Pafish可以查找這些驅動和 應用來判斷當前運行環境是否是virtualbox。

查找注冊表,看看有沒有VirtualBox Guest Additions的字符串。

int?vbox_reg_key3()?{
?????????????????????????????return?pafish_exists_regkey(HKEY_LOCAL_MACHINE,?"SOFTWARE\\Oracle\\VirtualBox?Guest?Additions");
}

查找有沒有VirtualBox Guest Additions的相關進程 (vboxservice.exe 和vboxtray.exe)

查找右下角有沒有關于VboxTrayTool的任務欄托盤窗口.

int?vbox_traywindow()?{
?????????????????????????????HWND?h1,?h2;
?????????????????????????????h1?=?FindWindow("VBoxTrayToolWndClass",?NULL);
?????????????????????????????h2?=?FindWindow(NULL,?"VBoxTrayToolWnd");
?????????????????????????????if?(h1?||?h2)?return?TRUE;
?????????????????????????????else?return?FALSE;
}

查找是否存在以下文件

"C:\\WINDOWS\\system32\\vboxdisp.dll";
"C:\\WINDOWS\\system32\\vboxhook.dll";
"C:\\WINDOWS\\system32\\vboxmrxnp.dll";
"C:\\WINDOWS\\system32\\vboxogl.dll";
"C:\\WINDOWS\\system32\\vboxoglarrayspu.dll";
"C:\\WINDOWS\\system32\\vboxoglcrutil.dll";
"C:\\WINDOWS\\system32\\vboxoglerrorspu.dll";
"C:\\WINDOWS\\system32\\vboxoglfeedbackspu.dll";
"C:\\WINDOWS\\system32\\vboxoglpackspu.dll";
"C:\\WINDOWS\\system32\\vboxoglpassthroughspu.dll";
"C:\\WINDOWS\\system32\\vboxservice.exe";
"C:\\WINDOWS\\system32\\vboxtray.exe";
"C:\\WINDOWS\\system32\\VBoxControl.exe";
"C:\\program?files\\oracle\\virtualbox?guest?additions\\";
"C:\\WINDOWS\\system32\\drivers\\VBoxMouse.sys";
"C:\\WINDOWS\\system32\\drivers\\VBoxGuest.sys";
"C:\\WINDOWS\\system32\\drivers\\VBoxSF.sys";
"C:\\WINDOWS\\system32\\drivers\\VBoxVideo.sys";

用WNetGetProviderName檢查共享文件夾的網絡類型名稱,如果是”VirtualBox Shared Folders”,則檢查到virtualbox的共享文件夾

int?vbox_network_share()?{
?????????????????????????????unsigned?long?pnsize?=?0x1000;
?????????????????????????????char?provider[pnsize];
?????????????????????????????int?retv?=?WNetGetProviderName(WNNC_NET_RDR2SAMPLE,?provider,?&pnsize);
?????????????????????????????if?(retv?==?NO_ERROR)?{
??????????????????????????????????????????????????????????if?(lstrcmpi(provider,?"VirtualBox?Shared?Folders")?==?0)?{
???????????????????????????????????????????????????????????????????????????????????????return?TRUE;
??????????????????????????????????????????????????????????}
??????????????????????????????????????????????????????????else?{
???????????????????????????????????????????????????????????????????????????????????????return?FALSE;
??????????????????????????????????????????????????????????}
?????????????????????????????}
?????????????????????????????return?FALSE;
}

以上,我們可以看到如果在虛擬機上安裝了virtualbox guest Additions 和共享文件夾,該虛擬機的其他進程可以很容易的發現其相關的窗口,文件,驅動,服務信息。這就相當于李鬼在臉上寫著“我不是李逵,我是李鬼”。那么,是不 是不安裝virtualbox guest Additions 和共享文件夾就安全了吶?答案是未必。一些默認的硬件信息仍然可以被作為指紋用于檢測virtualbox的存在。比如virtualbox默認的網卡 MAC地址前綴為08:00:27,這前3字節是virtualbox分配的唯一標識符OUI,以供其虛擬網卡使用。

int?vbox_mac()?{
?????????????????????????????/*?VirtualBox?mac?starts?with?08:00:27?*/
?????????????????????????????return?pafish_check_mac_vendor("\x08\x00\x27");
}

另外,還可以讀取注冊表信息,通過檢測特定的硬件信息,比如SCSI, systembiosversion, videobiosversion, ACPI,如果這些信息 包含VBOX關鍵字,那么可以斷定是virtualbox虛擬環境。

int?vbox_reg_key1()?{
?????????????????????????????return?pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE,?"HARDWARE\\DEVICEMAP\\Scsi\\Scsi?Port?0\\Scsi?Bus?0\\Target?Id?0\\Logical?Unit?Id?0",?"Identifier",?"VBOX");
}

還可以檢測其系統bios生成日期,如果是1999年6月23號,那么很可能是virtualbox

int?vbox_reg_key10()?{
?????????????????????????????return?pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE,?"HARDWARE\\DESCRIPTION\\System",?"SystemBiosDate",?"06/23/99");
}

4. 總結

綜上,Pafish給出了一些很實用的檢測虛擬機 的方法。虛擬的畢竟就是虛擬的,總歸會留下蛛絲螞跡。不過很多人認為我們也可以利用虛擬機檢測來免疫病毒,比如在實體機上設置一些虛假信息讓病毒誤認為這 個實體機是一個虛擬機,從而跳過“做壞事”的階段。對于這個觀點,有人認為靠譜,有人認為不靠譜,大家怎么看?

上一篇:Kali Linux NetHunter :Nexus設備上的滲透測試平臺

下一篇:如何攻擊光纖網絡并竊取敏感數據