當前位置:編程學習大全網 - 編程語言 - 網絡安全-----緩沖區溢出的保護方法有哪些

網絡安全-----緩沖區溢出的保護方法有哪些

目前有四種基本的方法保護緩沖區免受緩沖區溢出的攻擊和影響。

編寫正確的代碼 非執行的緩沖區 數組邊界檢查 程序指針完整性檢查

壹、編寫正確的代碼 Top

編寫正確的代碼是壹件非常有意義但耗時的工作,特別像編寫C語言那種具有容易出錯傾向的程序(如:字符串的零結尾),這種風格是由於追求性能而忽視正確性的傳統引起的。盡管花了很長的時間使得人們知道了如何編寫安全的程序組具有安全漏洞的程序依舊出現。因此人們開發了壹些工具和技術來幫助經驗不足的程序員編寫安全正確的程序。

最簡單的方法就是用grep來搜索源代碼中容易產生漏洞的庫的調用,比如對strcpy和sprintf的調用,這兩個函數都沒有檢查輸入參數的長度。事實上,各個版本C的標準庫均有這樣的問題存在。為了尋找壹些常見的諸如緩沖區溢出和操作系統競爭條件等漏洞,壹些代碼檢查小組檢查了很多的代碼。然而依然有漏網之魚存在。盡管采用了strcpy和sprintf這些替代函數來防止緩沖區溢出的發生,但是由於編寫代碼的問題,仍舊會有這種情況發生。比如lprm程序就是最好的例子,雖然它通過了代碼的安全檢查,但仍然有緩沖區溢出的問題存在。

為了對付這些問題,人們開發了壹些高級的查錯工具,如faultinjection等。這些工具的目的在於通過人為隨機地產生壹些緩沖區溢出來尋找代碼的安全漏洞。還有壹些靜態分析工具用於偵測緩沖區溢出的存在。雖然這些工具可以幫助程序員開發更安全的程序,但是由於C語言的特點,這些工具不可能找出所有的緩沖區溢出漏洞。所以,偵錯技術只能用來減少緩沖區溢出的可能,並不能完全地消除它的存在,除非程序員能保證他的程序萬元壹失。

二、非執行的緩沖區 Top

通過使被攻擊程序的數據段地址空間不可執行,從而使得攻擊者不可能執行被植入被攻擊程序輸入緩沖區的代碼,這種技術被稱為非執行的緩沖區技術。事實上,很多老的Unix系統都是這樣設計的,但是近來的Unix和MS Windows系統為實現更好的性能和功能,往往在數據段中動態地放人可執行的代碼。所以為了保持程序的兼容性不可能使得所有程序的數據段不可執行。但是我們可以設定堆棧數據段不可執行,這樣就可以最大限度地保證了程序的兼容性。Linux和Solaris都發布了有關這方面的內核補丁。因為幾乎沒有任何合的

程序會在堆棧中存放代碼,這種做法幾乎不產生任何兼容性問題,除了在Linux中的兩個特例,這時可執行的代碼必須被放入堆棧中:

1.信號傳遞

Linux通過向進程堆棧釋放代碼然後引發中斷來執行在堆棧中的代碼進而實現向進程發送Unix信號.非執行緩沖區的補丁在發送信號的時候是允許緩沖區可執行的.

2.GCC的在線重用

研究發現gcc在堆棧區裏放置了可執行的代碼以便在線重用。然而,關閉這個功能並不產生任何問題.只有部分功能似乎不能使用。非執行堆棧的保護可以有效地對付把代碼植入自動變量的緩沖區溢出攻擊,而對於其他形式的攻擊則沒有效果。通過引用壹個駐留

的程序的指針,就可以跳過這種保護措施。其他的攻擊可以采用把代碼植入堆或者靜態數據段中來跳過保護。

三、數組邊界檢查 Top

植入代碼引起緩沖區溢出是壹個方面,擾亂程序的執行流程是另壹個方面。不像非執行緩沖區保護,數組邊界檢查完全沒有了緩沖區溢出的產生和攻擊。這樣,只要數組不能被溢出,溢出攻擊也就無從談起。為了實現數組邊界檢查,則所有的對數組的讀寫操作都應當被檢查以確保對數組的操作在正確的範圍內。最直接的方法是檢查所有的數組操作,但是通常可以來用壹些優化的技術來減少檢查的次數。目前有以下的幾種檢查方法:

1、Compaq C編譯器

Compaq公司為Alpha CPU開發的C編譯器支持有限度的邊界檢查(使用—check_bounds參數)。這些限制是:只有顯示的數組引用才被檢查,比如“a[3]”會被檢查,而“*(a

+3)"則不會。由於所有的C數組在傳送的時候是指針傳遞的,所以傳遞給函數的的數組不會被檢查。帶有危險性的庫函數如strcpy不會在編譯的時候進行邊界檢查,即便是指定了邊界檢查。在C語言中利用指針進行數組操作和傳遞是非常頻繁的,因此這種局限性是非常嚴重的。通常這種邊界檢查用來程序的查錯,而且不能保證不發生緩沖區溢出的漏洞。

2、Jones&Kelly:C的數組邊界檢查

Richard Jones和Paul Kelly開發了壹個gcc的補丁,用來實現對C程序完全的數組邊界檢查。由於沒有改變指針的含義,所以被編譯的程序和其他的gcc模塊具有很好的兼容性。更進壹步的是,他們由此從沒有指針的表達式中導出了壹個“基”指針,然後通過檢查這個基指針來偵測表達式的結果是否在容許的範圍之內。當然,這樣付出的性能上的代價是巨大的:對於壹個頻繁使用指針的程序,如向量乘法,將由於指針的頻繁使用而使速度慢30倍。這個編譯器目前還很不成熟,壹些復雜的程序(如elm)還不能在這個上面編譯、執行通過。然而在它的壹個更新版本之下,它至少能編譯執行ssh軟件的加密軟件包,但其實現的性能要下降12倍。

3、Purify:存儲器存取檢查

Purify是C程序調試時查看存儲器使用的工具而不是專用的安全工具。Purify使用"目標代碼插入"技術來檢查所有的存儲器存取。通過用Purify連接工具連接,可執行代碼在執行的時候帶來的性能的損失要下降3—5倍。

4、類型——安全語言

所有的緩沖區溢出漏洞都源於C語言的類型安全。如果只有類型—安全的操作才可以被允許執行,這樣就不可能出現對變量的強制操作。如果作為新手,可以推薦使用具有類型—安全的語言如JAVA和ML。

但是作為Java執行平臺的Java虛擬機是C程序.因此攻擊JVM的壹條途徑是使JVM的緩沖區溢出。因此在系統中采用緩沖區溢出防衛技術來使用強制類型—安全的語言可以收到預想不到的效果。

四、程序指針完整性檢查 Top

程序指針完整性檢查和邊界檢查有略微的不同。與防止程序指針被改變不同,程序指針完整性檢查在程序指針被引用之前檢測到它的改變。因此,即便壹個攻擊者成功地改變程序的指針,由於系統事先檢測到了指針的改變,因此這個指針將不會被使用。與數組邊界檢查相比,這種方法不能解決所有的緩沖區溢出問題;采用其他的緩沖區溢出方法就可以避免這種檢測。但是這種方法在性能上有很大的優勢,而且兼容性也很好。

l、手寫的堆棧監測

Snarskii為FreeBSD開發丁壹套定制的能通過監測cpu堆棧來確定緩沖區溢出的libc。這個應用完全用手工匯編寫的,而且只保護libc中的當前有效紀錄函數.這個應用達到了設計要求,對於基於libc庫函數的攻擊具有很好的防衛,但是不能防衛其它方式的攻擊.

2、堆棧保護

堆棧保護是壹種提供程序指針完整性檢查的編譯器技術.通過檢查函數活動紀錄中的返回地址來實現。堆棧保護作為gcc的壹個小的補丁,在每個函數中,加入了函數建立和銷毀的代碼。加入的函數建立代碼實際上在堆棧中函數返回地址後面加了壹些附加的字節。而在函數返回時,首先檢查這個附加的字節是否被改動過,如果發生過緩沖區溢出的攻擊,那麽這種攻擊很容易在函數返回前被檢測到。但是,如果攻擊者預見到這些附加字節的存在,並且能在溢出過程中同樣地制造他們.那麽它就能成功地跳過堆棧保護的檢測。通常.我們有如下兩種方案對付這種欺騙:

1.終止符號

利用在C語言中的終止符號如o(null,CR,LF,—1(Eof)等這些符號不能在常用的字符串函數中使用,因為這些函數壹旦遇到這些終止符號,就結束函數過程了。

2.隨機符號

利用壹個在函數調用時產生的壹個32位的隨機數來實現保密,使得攻擊者不可能猜測到附加字節的內容.而且,每次調用附加字節的內容都在改變,也無法預測。通過檢查堆棧的完整性的堆棧保護法是從Synthetix方法演變來的。Synthetix方法通過使用準不變量來確保特定變量的正確性。這些特定的變量的改變是程序實現能預知的,而且只能在滿足壹定的條件才能可以改變。這種變量我們稱為準不變量。Synthetix開發了壹些工具用來保護這些變量。攻擊者通過緩沖區溢出而產生的改變可以被系統當做非法的動作。在某些極端的情況下,這些準不變量有可能被非法改變,這時需要堆棧保護來提供更完善的保護了。實驗的數據表明,堆棧保護對於各種系統的緩沖區溢出攻擊都有很好的保護作用.並能保持較好的兼容性和系統性能。分析表明,堆棧保護能有效抵禦現在的和將來的基於堆棧的攻擊。堆棧保護版本的Red Hat Linux 5.1已經在各種系統上運行了多年,包括個人的筆記本電腦和工作組文件服務器。

3、指針保護

在堆棧保護設計的時候,沖擊堆棧構成了緩沖區溢出攻擊的常見的壹種形式。有人推測存在壹種模板來構成這些攻擊(在1996年的時候)。從此,很多簡單的漏洞被發現,實施和補丁後,很多攻擊者開始用更壹般的方法實施緩沖區溢出攻擊。指針保護是堆錢保護針對這種情況的壹個推廣。通過在所有的代碼指針之後放置附加字節來檢驗指針在被調用之前的合法性,如果檢驗失敗,會發出報警信號和退出程序的執行,就如同在堆棧保護中的行為壹樣。這種方案有兩點需要註意:

(1)附加字節的定位

附加字節的空間是在被保護的變量被分配的時候分配的,同時在被保護字節初始化過程中被初始化。這樣就帶來了問題:為了保持兼容性,我們不想改變被保護變量的大小,因此我們不能簡單地在變量的結構定義中加入附加字。還有,對各種類型也有不同附加字節數目。

(2)查附加字節

每次程序指針被引用的時候都要檢查附加字節的完整性。這個也存在問題因為“從存取器讀”在編譯器中沒有語義,編譯器更關心指針的使用,而各種優化算法傾向於從存儲器中讀人變量.還有隨著變量類型的不同,讀入的方法也各自不同。到目前為止,只有很少—部分使用非指針變量的攻擊能逃脫指針保護的檢測。但是,可以通過在編譯器上強制對某壹變量加入附加字節來實現檢測,這時需要程序員自己手工加入相應的保護了。

  • 上一篇:視貝A799k空調萬能遙控器空調型號設置錯誤怎樣重置
  • 下一篇:Python編程有什麽特性?
  • copyright 2024編程學習大全網