彭小利,侯 翔
(四川文理學(xué)院 計算機學(xué)院,四川 達州635000)
隨著全球信息時代進入互聯(lián)網(wǎng)階段,網(wǎng)絡(luò)給人們的工作和生活都帶來了很大的便利,而不法分子利用系統(tǒng)的漏洞對用戶主機發(fā)起的攻擊也使人們不寒而栗.據(jù)國家計算機網(wǎng)絡(luò)入侵防范中心每個月對網(wǎng)絡(luò)安全漏洞的監(jiān)測和分析中可看到,所有漏洞中,緩沖區(qū)溢出漏洞幾乎均居首位,如2011年9月份十大重要安全漏洞分析,[1]居首位的仍是緩沖區(qū)溢出漏洞.緩沖區(qū)溢出漏洞攻擊占所有系統(tǒng)攻擊總數(shù)的80%以上.[2]圖1是緩沖區(qū)溢出攻擊后的一種表現(xiàn).很多損失巨大的網(wǎng)絡(luò)攻擊都是由緩沖區(qū)溢出攻擊造成的.如2001年造成26億美金損失的紅色代碼及其變體就是利用了Microsoft IIS的緩沖區(qū)溢出進行的攻擊.
圖1
緩沖區(qū)是計算機內(nèi)存中堆棧的一個區(qū)域,用來暫時存放CPU輸入輸出的數(shù)據(jù),是連續(xù)的臨時存儲區(qū).在內(nèi)存中,不同類型的數(shù)據(jù)存放在不同的區(qū)域中,用高級語言編寫的程序的機器碼存放于代碼段CS;已經(jīng)初始化的全局變量和靜態(tài)局部變量放在數(shù)據(jù)段DS;未初始化的全局變量和局部變量放在BBS段;函數(shù)的參數(shù)、返回地址等放在棧;動態(tài)分配的內(nèi)存則放在堆.內(nèi)存存放數(shù)據(jù)是從低地址向高地址的方向存,而棧存放數(shù)據(jù)的方向剛好和內(nèi)存存放的方向相反,如圖2所示.現(xiàn)通過一段程序來說明溢出的過程:
#include<stdio.h>
int main()
{
char name[5];
printf("Please enter your name:");
gets(name);
printf("Hello",name);
return 0;
}
圖2
編譯并執(zhí)行該程序,在對話框中輸入“PXL”并回車,就會輸出“Hello PXL”,重新執(zhí)行程序并在對話框中輸入“abcdefgabcdefgabcdefg”并回車,就會產(chǎn)生圖1的結(jié)果,此時就發(fā)生了緩沖區(qū)溢出.原因在:name[5]將用來裝用戶輸入的字符,串長度定義為5,第二次輸入的“abcdefgabcdefgabcdefg”已經(jīng)遠遠超過了5個字符的長度,每一個字符占一個內(nèi)存單元,由于存放name的堆只定義了5個字符即5個內(nèi)存單元,遠不夠用于存放用戶輸入的“abcdefgabcdefgabcdefg”,只好向內(nèi)存的高地址方向存放,而棧中存放的是主程序的返回地址等信息,且向低地址方向依次存放,因此name數(shù)組中用戶輸入的內(nèi)容就會占據(jù)棧中的信息,覆蓋棧中的返回地址等數(shù)據(jù).在main返回時,就會把覆蓋在原返回地址上的用戶輸入的一部分?jǐn)?shù)據(jù)作為返回地址,CPU試圖執(zhí)行該位置處的地址,結(jié)果出現(xiàn)錯誤,于是就有可能出現(xiàn)圖1所示的系統(tǒng)提示,這就是一次緩沖區(qū)(堆棧)的溢出.
緩沖區(qū)內(nèi)的數(shù)據(jù)及數(shù)據(jù)的長度是用戶輸入的數(shù)據(jù)決定的,而一般情況下程序都不會檢查輸入數(shù)據(jù)的長度,當(dāng)輸入的數(shù)據(jù)過長不但占據(jù)緩沖區(qū)還占據(jù)了邊界外的空間,此時緩沖區(qū)溢出就隨之產(chǎn)生,如該例中所示.
緩沖區(qū)溢出將會導(dǎo)致兩種后果,一是因過長的字符覆蓋了相鄰的空間,導(dǎo)致原有程序運行失敗甚至系統(tǒng)崩潰;二是不法者(后文均用攻擊者)則可利用此漏洞發(fā)起攻擊.
緩沖區(qū)溢出攻擊就是攻擊者利用緩沖區(qū)溢出漏洞而進行的攻擊行為.通過向緩沖區(qū)中寫入攻擊者事先設(shè)計好的超長數(shù)據(jù),以破壞堆棧,使得計算機轉(zhuǎn)至攻擊者編寫的具有攻擊目的的程序而運行之,緩沖區(qū)溢出示意圖如圖2(a)、(b)所示.
圖2
發(fā)起緩沖區(qū)溢出攻擊的攻擊者的目的是為了取得被攻擊主機的控制權(quán),因此其攻擊的對象主要是具有特權(quán)運行的程序,擾亂這些特權(quán)運行程序的功能,最終運行攻擊者的程序,達到攻擊的目的.
緩沖區(qū)溢出攻擊的關(guān)鍵是向攻擊主機植入攻擊代碼,然后利用緩沖區(qū)溢出漏洞控制攻擊主機執(zhí)行攻擊代碼.
利用緩沖區(qū)溢出攻擊取得被攻擊主機的程序運行權(quán)前,需要在被攻擊主機上放置好攻擊代碼,可以是事先已經(jīng)安放在被攻擊主機外存中具有系統(tǒng)功能調(diào)用的程序,也可以是存放于被攻擊主機的代碼段或數(shù)據(jù)段的代碼,這些代碼攻擊者會通過郵件的方式發(fā)送到被攻擊主機,也可以是攻擊者安放在某些網(wǎng)頁上,當(dāng)用戶在網(wǎng)站上進行下載操作甚至是進入靜態(tài)網(wǎng)頁時都有可能將這些攻擊代碼存入自己的主機.
攻擊者通過檢測被攻擊主機的緩沖區(qū)漏洞,即通過試探性的攻擊,向其輸入一超長數(shù)據(jù),使之改變被攻擊主機原定的執(zhí)行程序,將被攻擊主機將要執(zhí)行的指令指針指向攻擊者事先植入的攻擊代碼.
一旦將指令指針指向事先安插好的攻擊代碼地址,攻擊代碼就開始執(zhí)行,可以是攻擊者設(shè)計好的任何非法操作.
由于很多軟件開發(fā)人員都從C語言學(xué)起,并已經(jīng)將C語言中的習(xí)慣應(yīng)用在了其他的高級語言中,且很多軟件都是用C語言所編寫,因此要完全根除緩沖區(qū)溢出已不可能,但可盡量避免緩沖區(qū)溢出攻擊.
在C語言的庫版本中有很多可能引起緩沖區(qū)溢出的脆弱函數(shù),如strcpy()、sprintf()、gets()、scanf(),以及在循環(huán)內(nèi)的getc()、getchar()等,這些函數(shù)使用頻率很高,而C語言在習(xí)慣上只為用戶和參數(shù)分配一個很小的緩沖區(qū),且不對用戶輸入的數(shù)據(jù)長度進行判斷,因此程序員在編程時可加入數(shù)組上限等代碼用于檢測用戶輸入數(shù)據(jù)長度是否超長,從根源上阻止緩沖區(qū)溢出不被攻擊者所利用.在使用C++、JAVA、C#等高級語言編寫時,同樣需要注意這個問題.
在緩沖區(qū)溢出漏洞存在的情況下,禁止未經(jīng)授權(quán)的控制流的改變.即使攻擊者檢測到緩沖區(qū)溢出漏洞,也注入了攻擊代碼,但不允許控制語句指向攻擊代碼.
當(dāng)緩沖區(qū)溢出漏洞存在,且被攻擊者利用以修改了程序的控制流,使之轉(zhuǎn)向攻擊代碼,但可設(shè)置系統(tǒng)禁止執(zhí)行如exec()等系統(tǒng)調(diào)用函數(shù)的使用.
緩沖區(qū)溢出攻擊是危害極大的網(wǎng)絡(luò)攻擊方式,本文從計算機用戶使用過程中的常見現(xiàn)象出發(fā)來分析緩沖區(qū)溢出攻擊,以引起人們的足夠重視,就目前來說,要根除緩沖區(qū)溢出攻擊已是不可能的,只能盡量多加防范免受攻擊,除以上的防范方式以外,還可使用一些安全的編程語言和使用相對安全的標(biāo)準(zhǔn)庫函數(shù)等軟件技術(shù);而軟硬件具有相通性,[3]所以還有很多硬件技術(shù)也可輔助防御,最終做到減少損失.
[1]羅鴻彥,薛 質(zhì).Linux下緩沖區(qū)溢出的分析與利用[J].信息安全與通信保密,2008(8):133-135.
[2]彭小利.軟硬件的相通性[J].四川文理學(xué)院學(xué)報,2010(9):57-59.
[3]張 君.緩沖區(qū)溢出分析與防御[J].安全視窗,2011(9):55-57.