惡意代碼編寫者經(jīng)常使用反虛擬機技術逃避分析,這種技術可以檢測自己是否運行在虛擬機中。如果惡意代碼探測到自己在虛擬機中運行,它會執(zhí)行與其本身行為不同的行為,其中最簡單的行為是停止自身運行。
近年來,隨著虛擬化技術的使用不斷增加,采用反虛擬機技術的惡意代碼數(shù)量逐漸下降。惡意代碼編寫者已經(jīng)開始意識到,目標主機是虛擬機,也并不意味著它就沒有攻擊價值。
隨著虛擬化技術的不斷發(fā)展和普通應用,反虛擬機技術可能變得更加少見。這里研究最常見的反虛擬機技術(包括VMware、virtualbox和virtualpc,重點是最常用的VMware),并且介紹一些如何防御它們的辦法。
一、檢測虛擬機痕跡
1.根據(jù)MAC地址
通常,MAC地址的前三個字節(jié)標識一個提供商。以00:05:69、00:0c:29和00:50:56開始的MAC地址與VMware相對應;以00:03:ff開始的MAC地址與virtualpc對應;以08:00:27開始的MAC地址與virtualbox對應。
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.基于主板序列號、主機型號、系統(tǒng)盤所在磁盤名稱等其他硬件信息
//通過WMI獲取主機信息
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;
}
//通過連接接口連接WMI的內核對象名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;
}
//設置請求代理的安全級別
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;
}
//通過請求代理來向WMI發(fā)送請求
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)枚舉所有的結果對象
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ù)當前進程信息
通過進程快照讀取當前進程信息,查找是否存在虛擬機中特有的進程,如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
+關注
關注
0文章
1095瀏覽量
51341 -
惡意代碼
+關注
關注
0文章
10瀏覽量
7626 -
虛擬機
+關注
關注
1文章
905瀏覽量
28022
發(fā)布評論請先 登錄
相關推薦
評論