亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

相關(guān)文章

最新評論