叢佩春 王治杰
摘 要 首先介紹了緩沖區溢出的基本概念,研究并總結了緩沖區溢出的原理和過程。還通過一些攻擊示例介紹了系統如何被溢出攻擊,描述了網絡攻擊者利用緩沖區溢出漏洞進行系統攻擊的一般過程,最后簡單討論了幾種緩沖區溢出的保護方法。
關鍵詞 緩沖區溢出漏洞 緩沖區溢出攻擊 緩沖區溢出保護
中圖分類號:TP3 文獻標識碼:A
1緩沖區溢出的概述
安全漏洞與緩沖區溢出是分不開的,據微軟發布的安全報告可知,目前最常見的安全問題80%以上都是緩沖區溢出產生的問題。市場上幾乎每個應用程序和操作系統都存在黑客可能利用的緩沖區溢出漏洞,對于微軟Windows系統來說是尤其嚴重,以至于微軟在產品的新版本中采用了一種完全不同的解決方法。
2緩沖區溢出國內外研究現狀
緩沖區溢出攻擊作為一種主流的攻擊手法,早在20世紀80年代,國外就有人開始討論溢出攻擊,例如1988年的Morris蠕蟲,利用的攻擊方法之一就是Fingerd的緩沖區溢出,這次蠕蟲攻擊導致全球6000多臺機器被感染,損失巨大由此,緩沖區溢出問題逐漸得到人們的重視。1989年,Spafford提交了一份分析報告,描述了VAX機上的BSD版unix的Fingerd的緩沖區溢出程序的技術細節,從而引起了一部分安全人士對這個研究領域的重視。
緩沖區溢出的防御有一個主要的方面,第一個方面是從操作系統本身的機制對溢出進行遏制,提出了堆棧不可執行的技術;第二個方面是開發一些工具來保護堆棧2003年,Richard Jones和Paul Kelly開發了一個gcc的補丁,用來實現C程序數組邊界檢查,防范溢出問題。第三個方面是在溢出發生后,使用防火墻,入侵檢測系統(IDS)等進行一些訪問控制。
3緩沖區溢出攻擊原理
當正常的使用者操作程序的時候,所進行的操作一般不會超出程序的運行范圍,數據被添加到分配給該緩沖區的內存塊之外,會發生緩沖區溢出,這時候就會出現數據泄漏或侵占了其它的數據空間。緩沖區溢出的攻擊原理就是越過緩沖區長度界限向程序中輸入超出其常規長度的內容,造成緩沖區的溢出從而破壞程序的堆棧,使程序運行出現特殊的問題轉而執行其它指令。
4緩沖區溢出漏洞攻擊方式
(1)在程序的地址空間里安排適當的代碼
在程序的地址空間里安排適當的代碼往往是相對簡單的。如果要攻擊的代碼在所攻擊程序中已經存在了,那么就簡單地對代碼傳遞一些參數,然后使程序跳轉到目標中就可以完成了。攻擊代碼要求執行“exec(‘/bin/sh)”,而在libc庫中的代碼執行“exec(arg)”,其中的“arg”是個指向字符串的指針參數,只要把傳入的參數指針修改指向“/bin/sh”,然后再跳轉到libc庫中的響應指令序列就可以了。當然,很多時候這個可能性是很小的,那么就得用一種叫“植入法”的方式來完成了。緩沖區可以設在:堆棧(自動變量)、堆(動態分配的)和靜態數據區(初始化或者未初始化的數據)等的任何地方。也可以不必為達到這個目的而溢出任何緩沖區,只要找到足夠的空間來放置這些攻擊代碼就夠了。
(2)控制程序轉移到攻擊代碼的形式
緩沖區溢出漏洞攻擊都是在尋求改變程序的執行流程,使它跳轉到攻擊代碼,最為基本的就是溢出一個沒有檢查或者其他漏洞的緩沖區,這樣做就會擾亂程序的正常執行次序。通過溢出某緩沖區,可以改寫相近程序的空間而直接跳轉過系統對身份的驗證。原則上來講攻擊時所針對的緩沖區溢出的程序空間可為任意空間。但因不同地方的定位相異,所以也就帶出了多種轉移方式。
(3)植入綜合代碼和流程控制
常見的溢出緩沖區攻擊類是在一個字符串里綜合了代碼植入和Activation Records。攻擊時定位在一個可供溢出的自動變量,然后向程序傳遞一個很大的字符串,在引發緩沖區溢出改變Activation Records的同時植入代碼(權因C在習慣上只為用戶和參數開辟很小的緩沖區)。這樣的方法一般是用于可供溢出的緩沖區不能放入全部代碼時的。如果想使用已經駐留的代碼不需要再外部植入的時候,通常必須先把代碼做為參數。在libc(熟悉C的朋友應該知道,現在幾乎所有的C程序連接都是利用它來連接的)中的一部分代碼段會執行“exec(something)”,當中的something就是參數,使用緩沖區溢出改變程序的參數,然后利用另一個緩沖區溢出使程序指針指向libc中的特定的代碼段。
5緩沖區溢出的保護方法
(1)通過操作系統使得緩沖區不可執行,從而阻止攻擊者殖入攻擊代碼。這種方法有效地阻止了很多緩沖區溢出的攻擊,但是攻擊者并不一定要殖入攻擊代碼來實現緩沖區溢出的攻擊,所以這種方法還是存在很多弱點的。
(2)在程序指針失效前進行完整性檢查。這樣雖然這種方法不能使得所有的緩沖區溢出失效,但它的確確阻止了絕大多數的緩沖區溢出攻擊,而能夠逃脫這種方法保護的緩沖區溢出也很難實現。
(3)強制寫正確的代碼的方法。編寫正確的代碼是一件非常有意義但耗時的工作,特別像編寫C語言那種具有容易出錯傾向的程序(如:字符串的零結尾),這種風格是由于追求性能而忽視正確性的傳統引起的。盡管花了很長的時間使得人們知道了如何編寫安全的程序,具有安全漏洞的程序依舊出現。