惡意代碼編寫者經(jīng)常使用反虛擬機(jī)技術(shù)逃避分析,這種技術(shù)可以檢測(cè)自己是否運(yùn)行在虛擬機(jī)中。如果惡意代碼探測(cè)到自己在虛擬機(jī)中運(yùn)行,它會(huì)執(zhí)行與其本身行為不同的行為,其中最簡(jiǎn)單的行為是停止自身運(yùn)行。
近年來(lái),隨著虛擬化技術(shù)的使用不斷增加,采用反虛擬機(jī)技術(shù)的惡意代碼數(shù)量逐漸下降。惡意代碼編寫者已經(jīng)開始意識(shí)到,目標(biāo)主機(jī)是虛擬機(jī),也并不意味著它就沒(méi)有攻擊價(jià)值。
隨著虛擬化技術(shù)的不斷發(fā)展和普通應(yīng)用,反虛擬機(jī)技術(shù)可能變得更加少見。這里研究最常見的反虛擬機(jī)技術(shù)(包括VMware、virtualbox和virtualpc,重點(diǎn)是最常用的VMware),并且介紹一些如何防御它們的辦法。
一、檢測(cè)虛擬機(jī)痕跡
1.根據(jù)MAC地址
通常,MAC地址的前三個(gè)字節(jié)標(biāo)識(shí)一個(gè)提供商。以00:05:69、00:0c:29和00:50:56開始的MAC地址與VMware相對(duì)應(yīng);以00:03:ff開始的MAC地址與virtualpc對(duì)應(yīng);以08:00:27開始的MAC地址與virtualbox對(duì)應(yīng)。
BOOL CheckVMWare()
{
string mac;
get_3part_mac(mac);
if (mac=="00-05-69" || mac=="00-0c-29" || mac=="00-50-56")
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualPC()
{
string mac;
get_3part_mac(mac);
if (mac=="00-03-ff")
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualBox()
{
string mac;
get_3part_mac(mac);
if (mac=="08-00-27")
{
return TRUE;
}
else
{
return FALSE;
}
}
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff[30];
} ASTAT, *PASTAT;
void get_3part_mac(string &mac)
{
NCB Ncb;
ASTAT Adapter;
UCHAR uRetCode;
LANA_ENUM lenum;
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBENUM;
Ncb.ncb_buffer = (UCHAR *)&lenum;
Ncb.ncb_length = sizeof(lenum);
uRetCode = Netbios(&Ncb);
for (int i = 0; i < lenum.length; i++)
{
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBRESET;
Ncb.ncb_lana_num = lenum.lana[i];
uRetCode = Netbios(&Ncb);
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = lenum.lana[i];
strcpy((char *)Ncb.ncb_callname, "*");
Ncb.ncb_buffer = (unsigned char *)&Adapter;
Ncb.ncb_length = sizeof(Adapter);
uRetCode = Netbios(&Ncb);
if (uRetCode == 0)
{
char tmp[128];
sprintf(tmp, "%02x-%02x-%02x",
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2]
);
mac = tmp;
}
}
}
2.基于主板序列號(hào)、主機(jī)型號(hào)、系統(tǒng)盤所在磁盤名稱等其他硬件信息
//通過(guò)WMI獲取主機(jī)信息
BOOL ManageWMIInfo(string &result, string table, wstring wcol)
{
HRESULT hres;
char bord[1024];
//初始化COM
hres = CoInitialize(0);
//獲得WMI連接COM接口
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object."
<< "Err code = 0x"
<< hex << hres << endl;
CoUninitialize();
return false;
}
//通過(guò)連接接口連接WMI的內(nèi)核對(duì)象名ROOT//CIMV2
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return false;
}
//設(shè)置請(qǐng)求代理的安全級(jí)別
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return false;
}
//通過(guò)請(qǐng)求代理來(lái)向WMI發(fā)送請(qǐng)求
IEnumWbemClassObject* pEnumerator = NULL;
string select = "SELECT * FROM "+ table;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(select.c_str()),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
cout << "Query for Network Adapter Configuration failed."
<< " Error code = 0x”"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return false;
}
//循環(huán)枚舉所有的結(jié)果對(duì)象
ULONG uReturn = 0;
IWbemClassObject *pclsObj;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
VariantInit(&vtProp);
hr = pclsObj->Get(wcol.c_str(), 0, &vtProp, 0, 0);
if(!FAILED(hr))
{
CW2A tmpstr1(vtProp.bstrVal);
strcpy_s(bord,200,tmpstr1);
result = bord;
}
VariantClear(&vtProp);
}
//釋放資源
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
pclsObj->Release();
CoUninitialize();
return true;
}
BOOL CheckVMWare()
{
string table = "Win32_BaseBoard";
wstring wcol = L"SerialNumber";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret == "None")
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVMWare()
{
string table = "Win32_DiskDrive";
wstring wcol = L"Caption";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("VMware") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVMWare()
{
string table = "Win32_computersystem";
wstring wcol = L"Model";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("VMware") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualBox()
{
string table = "Win32_computersystem";
wstring wcol = L"Model";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("VirtualBox") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualBox()
{
string table = "Win32_DiskDrive";
wstring wcol = L"Caption";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("VBOX") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualPC()
{
string table = "Win32_DiskDrive";
wstring wcol = L"Caption";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("Virtual HD") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CheckVirtualPC()
{
string table = "Win32_computersystem";
wstring wcol = L"Model";
string ret;
ManageWMIInfo(ret, table, wcol);
if (ret.find("Virtual Machine") != string::npos)
{
return TRUE;
}
else
{
return FALSE;
}
}
3.根據(jù)當(dāng)前進(jìn)程信息
通過(guò)進(jìn)程快照讀取當(dāng)前進(jìn)程信息,查找是否存在虛擬機(jī)中特有的進(jìn)程,如VMware中的vmware.exe和VirtualBox中的VBoxService.exe。
BOOL CheckVMWare()
{
DWORD ret = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bMore = Process32First(hProcessSnap, &pe32);
while(bMore)
{
if (strcmp(pe32.szExeFile, "vmware.exe")==0)
{
return TRUE;
}
bMore = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return FALSE;
}
BOOL CheckVirtualBox()
{
DWORD ret = 0;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bMore = Process32First(hProcessSnap, &pe32);
while(bMore)
{
if (strcmp(pe32.szExeFile, "VBoxService.exe")==0)
{
return TRUE;
}
bMore = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return FALSE;
}
-
Mac
+關(guān)注
關(guān)注
0文章
1117瀏覽量
52695 -
惡意代碼
+關(guān)注
關(guān)注
0文章
12瀏覽量
7727 -
虛擬機(jī)
+關(guān)注
關(guān)注
1文章
963瀏覽量
29104
發(fā)布評(píng)論請(qǐng)先 登錄
虛擬機(jī)下載與安裝的步驟有哪些

什么是虛擬機(jī)?虛擬機(jī)真的那么好用嗎?

有關(guān)虛擬機(jī)及虛擬化技術(shù)的幾點(diǎn)詮注
虛擬機(jī)及虛擬化技術(shù)
基于虛擬機(jī)技術(shù)的DSC仿真系統(tǒng)設(shè)計(jì)

基于虛擬機(jī)技術(shù)的DCS仿真系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)

虛擬機(jī):QEMU虛擬機(jī)和主機(jī)無(wú)線網(wǎng)絡(luò)通訊設(shè)置

KVM虛擬機(jī)管理和基本使用
反虛擬機(jī)技術(shù)合集2

反虛擬機(jī)技術(shù)合集3

反虛擬機(jī)技術(shù)合集4

linux虛擬機(jī)使用教程
Docker與虛擬機(jī)的區(qū)別
虛擬機(jī)ubuntu怎么聯(lián)網(wǎng)
虛擬機(jī)數(shù)據(jù)恢復(fù)—KVM虛擬機(jī)被誤刪除的數(shù)據(jù)恢復(fù)案例

評(píng)論