欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

緩沖區(qū)溢出:十年來(lái)攻擊和防衛(wèi)的弱點(diǎn)

 更新時(shí)間:2007年01月16日 00:00:00   作者:  
摘要: 在過(guò)去的十年中,以緩沖區(qū)溢出為類(lèi)型的安全漏洞占是最為 常見(jiàn)的一種形式了。更為嚴(yán)重的是,緩沖區(qū)溢出漏洞占了遠(yuǎn)程網(wǎng) 絡(luò)攻擊的絕大多數(shù),這種攻擊可以使得一個(gè)匿名的Internet用戶 有機(jī)會(huì)獲得一臺(tái)主機(jī)的部分或全部的控制權(quán)!如果能有效地消除 緩沖區(qū)溢出的漏洞,則很大一部分的安全威脅可以得到緩解。在 本文中,我們研究了各種類(lèi)型的緩沖區(qū)溢出漏洞和攻擊手段,同 時(shí)我們也研究了各種的防御手段,這些手段用來(lái)消除這些漏洞所 造成的影響,其中包括我們自己的堆棧保護(hù)方法。然后我們要考 慮如何在保證現(xiàn)有系統(tǒng)功能和性能不變的情況下,如何使用這些 方法來(lái)消除這些安全漏洞。 
 一、前言 在過(guò)去的十年中,以緩沖區(qū)溢出為類(lèi)型的安全漏洞占是最為 常見(jiàn)的一種形式了。更為嚴(yán)重的是,緩沖區(qū)溢出漏洞占了遠(yuǎn)程網(wǎng) 絡(luò)攻擊的絕大多數(shù),這種攻擊可以使得一個(gè)匿名的Internet用戶 有機(jī)會(huì)獲得一臺(tái)主機(jī)的部分或全部的控制權(quán)!由于這類(lèi)攻擊使任 何人都有可能取得主機(jī)的控制權(quán),所以它代表了一類(lèi)極其嚴(yán)重的 安全威脅。 緩沖區(qū)溢出攻擊之所以成為一種常見(jiàn)安全攻擊手段其原因在 于緩沖區(qū)溢出漏洞太普通了,并且易于實(shí)現(xiàn)。而且,緩沖區(qū)溢出 成為遠(yuǎn)程攻擊的主要手段其原因在于緩沖區(qū)溢出漏洞給予了攻擊 者他所想要的一切:殖入并且執(zhí)行攻擊代碼。被殖入的攻擊代碼 以一定的權(quán)限運(yùn)行有緩沖區(qū)溢出漏洞的程序,從而得到被攻擊主 機(jī)的控制權(quán)。 比如,在1998年Lincoln實(shí)驗(yàn)室用來(lái)評(píng)估入侵檢測(cè)的的5種遠(yuǎn) 程攻擊中,有3種是基于社會(huì)工程學(xué)的信任關(guān)系,2種是緩沖區(qū)溢 出。而在1998年CERT的13份建議中,有9份是是與緩沖區(qū)溢出有 關(guān)的,在1999年,至少有半數(shù)的建議是和緩沖區(qū)溢出有關(guān)的。在 Bugtraq的調(diào)查中,有2/3的被調(diào)查者認(rèn)為緩沖區(qū)溢出漏洞是一個(gè) 很?chē)?yán)重的安全問(wèn)題。 緩沖區(qū)溢出漏洞和攻擊有很多種形式,我們會(huì)在第二部分對(duì) 他們進(jìn)行描述和分類(lèi)。相應(yīng)地防衛(wèi)手段也隨者攻擊方法的不同而 不同,我們會(huì)放在第三部分描述,它的內(nèi)容包括針對(duì)每種攻擊類(lèi) 型的有效的防衛(wèi)手段。我們還要要介紹堆棧保護(hù)方法,這種方法 在解決緩沖區(qū)溢出的漏洞方面很有效果,并且沒(méi)有犧牲系統(tǒng)的兼 容性和性能。在第四部分,我們要討論各種防衛(wèi)方法的綜合使 用。最后在第五部分是我們的結(jié)論。 
二、緩沖區(qū)溢出的漏洞和攻擊 緩沖區(qū)溢出攻擊的目的在于擾亂具有某些特權(quán)運(yùn)行的程序的 功能,這樣可以使得攻擊者取得程序的控制權(quán),如果該程序具有 足夠的權(quán)限,那么整個(gè)主機(jī)就被控制了。一般而言,攻擊者攻擊 root程序,然后執(zhí)行類(lèi)似“exec(sh)”的執(zhí)行代碼來(lái)獲得root的 shell,但不一直是這樣的。為了達(dá)到這個(gè)目的,攻擊者必須達(dá) 到如下的兩個(gè)目標(biāo): 
 1. 在程序的地址空間里安排適當(dāng)?shù)拇a。 
2. 通過(guò)適當(dāng)?shù)爻跏蓟拇嫫骱痛鎯?chǔ)器,讓程序跳轉(zhuǎn)到我們安排 的地址空間執(zhí)行。 我們根據(jù)這兩個(gè)目標(biāo)來(lái)對(duì)緩沖區(qū)溢出攻擊進(jìn)行分類(lèi)。在2.1 部分,我們將描述攻擊代碼是如何放入被攻擊程序的地址空間的 (這個(gè)就是“緩沖區(qū)”名字的的由來(lái))。在2.2部分,我們介紹 攻擊者如何使一個(gè)程序的緩沖區(qū)溢出,并且執(zhí)行轉(zhuǎn)移到攻擊代碼 (這個(gè)就是“溢出”的由來(lái))。在2.3部分,我們介紹綜合在2.1 和2.2部分所討論的代碼安排和控制程序執(zhí)行流程的技術(shù)。 2.1 在程序的地址空間里安排適當(dāng)?shù)拇a的方法 有兩種在被攻擊程序地址空間里安排攻擊代碼的方法: 殖入法: 攻擊者向被攻擊的程序輸入一個(gè)字符串,程序會(huì)把這個(gè)字符 串放到緩沖區(qū)里。這個(gè)字符串包含的數(shù)據(jù)是可以在這個(gè)被攻擊的 硬件平臺(tái)上運(yùn)行的指令序列。在這里攻擊者用被攻擊程序的緩沖 區(qū)來(lái)存放攻擊代碼。具體的方式有以下兩種差別: 1. 攻擊者不必為達(dá)到此目的而溢出任何緩沖區(qū),可以找到足夠 的空間來(lái)放置攻擊代碼 2. 緩沖區(qū)可以設(shè)在任何地方:堆棧(自動(dòng)變量)、堆(動(dòng)態(tài)分 配的)和靜態(tài)數(shù)據(jù)區(qū)(初始化或者未初始化的數(shù)據(jù)) 利用已經(jīng)存在的代碼: 有時(shí)候,攻擊者想要的代碼已經(jīng)在被攻擊的程序中了,攻擊 者所要做的只是對(duì)代碼傳遞一些參數(shù),然后使程序跳轉(zhuǎn)到我們的 目標(biāo)。比如,攻擊代碼要求執(zhí)行“exec("/bin/sh")”,而在 libc庫(kù)中的代碼執(zhí)行“exec(arg)”,其中arg使一個(gè)指向一個(gè)字 符串的指針參數(shù),那么攻擊者只要把傳入的參數(shù)指針改向指向 "/bin/sh",然后調(diào)轉(zhuǎn)到libc庫(kù)中的相應(yīng)的指令序列。 2.2 控制程序轉(zhuǎn)移到攻擊代碼的方法 所有的這些方法都是在尋求改變程序的執(zhí)行流程,使之跳轉(zhuǎn) 到攻擊代碼。最基本的就是溢出一個(gè)沒(méi)有邊界檢查或者其他弱點(diǎn) 的緩沖區(qū),這樣就擾亂了程序的正常的執(zhí)行順序。通過(guò)溢出一個(gè) 緩沖區(qū),攻擊者可以用近乎暴力的方法改寫(xiě)相鄰的程序空間而直 接跳過(guò)了系統(tǒng)的檢查。 這里分類(lèi)的基準(zhǔn)是攻擊者所尋求的緩沖區(qū)溢出的程序空間類(lèi) 型。原則上是可以任意的空間。比如,最初的Morris Worm使用 了fingerd程序的緩沖區(qū)溢出,擾亂fingerd要執(zhí)行的文件的名 字。實(shí)際上,許多的緩沖區(qū)溢出是用暴力的方法來(lái)尋求改變程序 指針的。這類(lèi)程序的不同的地方就是程序空間的突破和內(nèi)存空間 的定位不同。 (圖1) 激活紀(jì)錄(Activation Records): 每當(dāng)一個(gè)函數(shù)調(diào)用發(fā)生時(shí),調(diào)用者會(huì)在堆棧中留下一個(gè)激活 紀(jì)錄,它包含了函數(shù)結(jié)束時(shí) 返回的地址。攻擊者通過(guò)溢出這些自動(dòng)變量,使這個(gè)返回地址指 向攻擊代碼,如圖1所示。通過(guò)改變程序的返回地址,當(dāng)函數(shù)調(diào) 用結(jié)束時(shí),程序就跳轉(zhuǎn)到攻擊者設(shè)定的地址,而不是原先的地 址。這類(lèi)的緩沖區(qū)溢出被稱為“stack smashing attack”,使 目前常用的緩沖區(qū)溢出攻擊方式。 函數(shù)指針(Function Pointers): “void (* foo)()”聲明了一個(gè)返回值為void函數(shù)指針的變 量foo。函數(shù)指針可以用來(lái)定 位任何地址空間,所以攻擊者只需在任何空間內(nèi)的函數(shù)指針附近 找到一個(gè)能夠溢出的緩沖區(qū),然后溢出這個(gè)緩沖區(qū)來(lái)改變函數(shù)指 針。 
在某一時(shí)刻,當(dāng)程序通過(guò)函數(shù)指針調(diào)用函數(shù)時(shí),程序的流程 就按攻擊者的意圖實(shí)現(xiàn)了!它的一個(gè)攻擊范例就是在Linux系統(tǒng) 下的superprobe程序。 長(zhǎng)跳轉(zhuǎn)緩沖區(qū)(Longjmp buffers): 在C語(yǔ)言中包含了一個(gè)簡(jiǎn)單的檢驗(yàn)/恢復(fù)系統(tǒng),稱為 setjmp/longjmp。意思是在檢驗(yàn)點(diǎn)設(shè) 定“setjmp(buffer)”,用“l(fā)ongjmp(buffer)”來(lái)恢復(fù)檢驗(yàn) 點(diǎn)。然而,如果攻擊者能夠進(jìn)入緩沖區(qū)的空間,那么 “l(fā)ongjmp(buffer)”實(shí)際上是跳轉(zhuǎn)到攻擊者的代碼。象函數(shù)指 針一樣,longjmp緩沖區(qū)能夠指向任何地方,所以攻擊者所要做 的就是找到一個(gè)可供溢出的緩沖區(qū)。一個(gè)典型的例子就是Perl 5.003,攻擊者首先進(jìn)入用來(lái)恢復(fù)緩沖區(qū)溢出的的longjmp緩沖 區(qū),然后誘導(dǎo)進(jìn)入恢復(fù)模式,這樣就使Perl的解釋器跳轉(zhuǎn)到攻擊 代碼上了! 2.3 綜合代碼殖入和流程控制技術(shù) 現(xiàn)在我們研究綜合代碼殖入和流程控制的技術(shù)。 最簡(jiǎn)單和常見(jiàn)的緩沖區(qū)溢出攻擊類(lèi)型就是在一個(gè)字符串里 綜合了代碼殖入和激活紀(jì)錄。攻擊者定位一個(gè)可供溢出的自動(dòng)變量, 然后向程序傳遞一個(gè)很大的字符串,在引發(fā)緩沖區(qū)溢出改變 激活紀(jì)錄的同時(shí)殖入了代碼。這個(gè)是由Levy指出的攻擊的模板。 因?yàn)镃在習(xí)慣上只為用戶和參數(shù)開(kāi)辟很小的緩沖區(qū),因此這種漏 洞攻擊的實(shí)例不在少數(shù)。 代碼殖入和緩沖區(qū)溢出不一定要在在一次動(dòng)作內(nèi)完成。攻擊 者可以在一個(gè)緩沖區(qū)內(nèi)放置代碼,這是不能溢出緩沖區(qū)。然后, 攻擊者通過(guò)溢出另外一個(gè)緩沖區(qū)來(lái)轉(zhuǎn)移程序的指針。這種方法一 般用來(lái)解決可供溢出的緩沖區(qū)不夠大(不能放下全部的代碼)的 情況。 如果攻擊者試圖使用已經(jīng)常駐的代碼而不是從外部殖入代 碼,他們通常有必須把代碼作為參數(shù)化。舉例來(lái)說(shuō),在libc(幾 乎所有的C程序都要它來(lái)連接)中的部分代碼段會(huì)執(zhí)行 “exec(something)”,其中somthing就是參數(shù)。攻擊者然后使 用緩沖區(qū)溢出改變程序的參數(shù),然后利用另一個(gè)緩沖區(qū)溢出使程 序指針指向libc中的特定的代碼段。 3. 緩沖區(qū)溢出的保護(hù)方法 目前有四種基本的方法保護(hù)緩沖區(qū)免受緩沖區(qū)溢出的攻擊和 影響。在3.1中介紹了強(qiáng)制寫(xiě)正確的代碼的方法。 
在3.2中介紹了 通過(guò)操作系統(tǒng)使得緩沖區(qū)不可執(zhí)行,從而阻止攻擊者殖入攻擊代 碼。這種方法有效地阻止了很多緩沖區(qū)溢出的攻擊,但是攻擊者 并不一定要殖入攻擊代碼來(lái)實(shí)現(xiàn)緩沖區(qū)溢出的攻擊(參見(jiàn)2.1 節(jié)),所以這種方法還是存在很弱點(diǎn)的。在3.3中,我們介紹了 利用編譯器的邊界檢查來(lái)實(shí)現(xiàn)緩沖區(qū)的保護(hù)。這個(gè)方法使得緩沖 區(qū)溢出不可能出現(xiàn),從而完全消除了緩沖區(qū)溢出的威脅,但是相 對(duì)而言代價(jià)比較大。在3.4中我們介紹一種間接的方法,這個(gè)方 法在程序指針失效前進(jìn)行完整性檢查。這樣雖然這種方法不能使 得所有的緩沖區(qū)溢出失效,但它的的確確阻止了絕大多數(shù)的緩沖 區(qū)溢出攻擊,而能夠逃脫這種方法保護(hù)的緩沖區(qū)溢出也很難實(shí) 現(xiàn)。然后在3.5,我們要分析這種保護(hù)方法的兼容性和性能優(yōu)勢(shì) (與數(shù)組邊界檢查)。 3.1 編寫(xiě)正確的代碼 編寫(xiě)正確的代碼是一件非常有意義但耗時(shí)的工作,特別象編 寫(xiě)C語(yǔ)言那種具有容易出錯(cuò)傾向的程序(如:字符串的零結(jié) 尾),這種風(fēng)格是由于追求性能而忽視正確性的傳統(tǒng)引起的。盡 管花了很長(zhǎng)的時(shí)間使得人們知道了如何編寫(xiě)安全的程序,具有安 全漏洞的程序依舊出現(xiàn)。因此人們開(kāi)發(fā)了一些工具和技術(shù)來(lái)幫助 經(jīng)驗(yàn)不足的程序員編寫(xiě)安全正確的程序。 最簡(jiǎn)單的方法就是用grep來(lái)搜索源代碼中容易產(chǎn)生漏洞的庫(kù) 的調(diào)用,比如對(duì)strcpy和sprintf的調(diào)用,這兩個(gè)函數(shù)都沒(méi)有檢 查輸入?yún)?shù)的長(zhǎng)度。事實(shí)上,各個(gè)版本C的標(biāo)準(zhǔn)庫(kù)均有這樣的問(wèn) 題存在。 為了尋找一些常見(jiàn)的諸如緩沖區(qū)溢出和操作系統(tǒng)競(jìng)爭(zhēng)條件等 漏洞,代碼檢查小組檢查了很多的代碼。然而依然有漏網(wǎng)之魚(yú)存 在。盡管采用了strncpy和snprintf這些替代函數(shù)來(lái)防止緩沖區(qū) 溢出的發(fā)生,但是由于編寫(xiě)代碼的問(wèn)題,仍舊會(huì)有這種情況發(fā) 生。比如lprm程序就是最好的例子,雖然它通過(guò)了代碼的安全 檢查,但仍然有緩沖區(qū)溢出的問(wèn)題存在。 為了對(duì)付這些問(wèn)題,人們開(kāi)發(fā)了一些高級(jí)的查錯(cuò)工具,如 fault injection等。這些工具的目的在于通過(guò)人為隨機(jī)地產(chǎn)生 一些緩沖區(qū)溢出來(lái)尋找代碼的安全漏洞。還有一些靜態(tài)分析工具 用于偵測(cè)緩沖區(qū)溢出的存在。 雖然這些工具幫助程序員開(kāi)發(fā)更安全的程序,但是由于C語(yǔ) 言的特點(diǎn),這些工具不可能找出所有的緩沖區(qū)溢出漏洞。所以, 偵錯(cuò)技術(shù)只能用來(lái)減少緩沖區(qū)溢出的可能,并不能完全地消除它 的存在。除非程序員能保證他的程序萬(wàn)無(wú)一失,否則還是要用到 以下3.2到3.4部分的內(nèi)容來(lái)保證程序的可靠性能。 
 3.2 非執(zhí)行的緩沖區(qū) 通過(guò)使被攻擊程序的數(shù)據(jù)段地址空間不可執(zhí)行,從而使得攻 擊者不可能執(zhí)行被殖入被攻擊程序輸入緩沖區(qū)的代碼,這種技術(shù) 被稱為非執(zhí)行的緩沖區(qū)技術(shù)。事實(shí)上,很多老的Unix系統(tǒng)都是這 樣設(shè)計(jì)的,但是近來(lái)的Unix和MS Windows系統(tǒng)由于實(shí)現(xiàn)更好的性 能和功能,往往在在數(shù)據(jù)段中動(dòng)態(tài)地放入可執(zhí)行的代碼。所以為 了保持程序的兼容性不可能使得所有程序的數(shù)據(jù)段不可執(zhí)行。 但是我們可以設(shè)定堆棧數(shù)據(jù)段不可執(zhí)行,這樣就可以最大限 度地保證了程序的兼容性。Linux和Solaris都發(fā)布了有關(guān)這方面 的內(nèi)核補(bǔ)丁。因?yàn)閹缀鯖](méi)有任何合法的程序會(huì)在堆棧中存放代 碼,這種做法幾乎不產(chǎn)生任何兼容性問(wèn)題,除了在Linux中的兩 個(gè)特例,這時(shí)可執(zhí)行的代碼必須被放入堆棧中: 信號(hào)傳遞: Linux通過(guò)向進(jìn)程堆棧釋放代碼然后引發(fā)中斷來(lái)執(zhí)行在堆棧 中的代碼來(lái)實(shí)現(xiàn)向進(jìn)程發(fā)送Unix信號(hào)。非執(zhí)行緩沖區(qū)的補(bǔ)丁在發(fā) 送信號(hào)的時(shí)候是允許緩沖區(qū)可執(zhí)行的。 GCC的在線重用: 研究發(fā)現(xiàn)gcc在堆棧區(qū)里放置了可執(zhí)行的代碼作為在線重用 之用。然而,關(guān)閉這個(gè)功能并不產(chǎn)生任何問(wèn)題,只有部分功能似 乎不能使用。 非執(zhí)行堆棧的保護(hù)可以有效地對(duì)付把代碼殖入自動(dòng)變量的緩 沖區(qū)溢出攻擊,而對(duì)于其他形式的攻擊則沒(méi)有效果(參見(jiàn)2.1)。 通過(guò)引用一個(gè)駐留的程序的指針,就可以跳過(guò)這種保護(hù)措施。其 他的攻擊可以采用把代碼殖入堆或者靜態(tài)數(shù)據(jù)段中來(lái)跳過(guò)保護(hù)。 
 3.3 數(shù)組邊界檢查 殖入代碼引起緩沖區(qū)溢出是一個(gè)方面,擾亂程序的執(zhí)行流程 是另一個(gè)方面。不象非執(zhí)行緩沖區(qū)保護(hù),數(shù)組邊界檢查完全放置 了緩沖區(qū)溢出的產(chǎn)生和攻擊。這樣,只要數(shù)組不能被溢出,溢出 攻擊也就無(wú)從談起。為了實(shí)現(xiàn)數(shù)組邊界檢查,則所有的對(duì)數(shù)組的 讀寫(xiě)操作都應(yīng)當(dāng)被檢查以確保對(duì)數(shù)組的操作在正確的范圍內(nèi)。最 直接的方法是檢查所有的數(shù)組操作,但是通常可以采用一些優(yōu)化 的技術(shù)來(lái)減少檢查的次數(shù)。目前有以下的幾種檢查方法: 3.3.1 Compaq C 編譯器 Compaq公司為Alpha CPU開(kāi)發(fā)的C編譯器(在Tru64的Unix平 臺(tái)上是cc,在Alpha Linux平臺(tái)上是ccc)支持有限度的邊界檢查 (使用-check_bounds參數(shù))。這些限制是: ·只有顯示的數(shù)組引用才被檢查,比如“a[3]”會(huì)被檢查,而 “*(a+3)”則不會(huì)。 ·由于所有的C數(shù)組在傳送的時(shí)候是指針傳遞的,所以傳遞給函 數(shù)的的數(shù)組不會(huì)被檢查。 ·帶有危險(xiǎn)性的庫(kù)函數(shù)如strcpy不會(huì)在編譯的時(shí)候進(jìn)行邊界檢 查,即便是指定了邊界檢查。 由于在C語(yǔ)言中利用指針進(jìn)行數(shù)組操作和傳遞是如此的頻 繁,因此這種局限性是非常嚴(yán)重的。通常這種邊界檢查用來(lái)程序 的查錯(cuò),而且不能保證不發(fā)生緩沖區(qū)溢出的漏洞。 

相關(guān)文章

最新評(píng)論