版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
內(nèi)容備注《網(wǎng)絡(luò)攻防原理與技術(shù)》課程教案講課題目:第九講緩沖區(qū)溢出攻擊目的要求:了解緩沖區(qū)溢出攻擊的基本概念;掌握緩沖區(qū)溢出攻擊的基本原理;了解shellcode的構(gòu)造方法;了解緩沖區(qū)溢出攻擊的主要防護方法。重點難點:緩沖區(qū)溢出攻擊的基本原理。方法步驟:理論講授。器材保障:電腦、投影儀。主要教學(xué)內(nèi)容:一、緩沖區(qū)溢出攻擊概述緩沖區(qū)溢出的根源在于程序員沒有對輸入數(shù)據(jù)進行嚴格的邊界檢查。如果緩沖區(qū)被寫滿,而程序沒有去檢查緩沖區(qū)邊界,也沒有停止接收數(shù)據(jù),這時就會發(fā)生緩沖區(qū)溢出。在非惡意情況下,緩沖區(qū)溢出一般會造成進程的狀態(tài)紊亂,執(zhí)行流程失去控制,最終進程通常會因為內(nèi)存讀寫問題被操作系統(tǒng)殺死。如果攻擊者精心構(gòu)造寫入數(shù)據(jù),則當溢出發(fā)生后,攻擊者可以精確執(zhí)行其預(yù)定的代碼,實現(xiàn)攻擊的目的。緩沖區(qū)溢出的缺陷普遍存在并且容易挖掘,而且利用成功后常??梢灾苯荧@得進程特權(quán),甚至控制整臺主機,因此緩沖區(qū)溢出攻擊在安全攻擊中占有很大的比重。緩沖區(qū)溢出不僅僅局限于非安全類型編程語言C/C++,安全類型的編程語言代碼(如Java,Perl)的底層基礎(chǔ)同樣面臨緩沖區(qū)溢出攻擊的威脅。二、緩沖區(qū)溢出攻擊原理(一)進程的內(nèi)存結(jié)構(gòu)在大多數(shù)操作系統(tǒng)中,系統(tǒng)在創(chuàng)建一個進程時,會一次性給該進程分配一塊內(nèi)存(通常稱為“靜態(tài)分配”),這塊內(nèi)存在進程運行期間保持不變,主要由四部分組成:1)文本(Text)段,保存程序的所有指令(操作碼+操作數(shù))。這個內(nèi)存區(qū)域通常被標記為只讀。2)數(shù)據(jù)(Data)段,保存初始化的全局靜態(tài)數(shù)據(jù)。3)BSS(BlockStartedbySymbol)段,保存未初始化的全局數(shù)據(jù)。4)堆棧(Stack),保存動態(tài)變量和函數(shù)調(diào)用的現(xiàn)場數(shù)據(jù)(主要包括函數(shù)的返回地址、函數(shù)參數(shù)、棧幀指針等),簡稱為“?!薄_M程剛啟動時,??臻g是空的,里面沒有實體。在進程運行期間,對具體實體的棧分配是進程自行生成(壓棧)和釋放(彈出)實體,系統(tǒng)并不參與。只要壓入的實體的總長度不超過棧空間尺寸,棧分配就與系統(tǒng)無關(guān)。如果超過了,就會引發(fā)棧異常。除了上述一次性分配的內(nèi)存外,進程還可以動態(tài)申請內(nèi)存,這就是堆(Heap)分配。當進程需要生成實體時,向系統(tǒng)申請分配空間;不再需要該實體時,可以向系統(tǒng)申請回收這塊空間。用戶進程使用特定的函數(shù),如malloc(),calloc(),realloc(),new()等申請堆塊。由于是按需分配,因此堆的空間利用率最高。緩沖區(qū)溢出攻擊一般包含兩個主要步驟。首先在程序中植入攻擊代碼或植入攻擊代碼所需的攻擊參數(shù)(如果攻擊代碼已存在于目標程序中),然后改變程序的執(zhí)行流程,轉(zhuǎn)去執(zhí)行攻擊代碼。根據(jù)是否需要植入攻擊代碼,可將緩沖區(qū)溢出攻擊分為兩種攻擊模式。第一種模式稱為代碼注入攻擊。在這種模式下,攻擊者向緩沖區(qū)寫入的數(shù)據(jù)包含了攻擊代碼(可執(zhí)行的二進制代碼,通常稱為“shellcode”),當發(fā)生緩沖區(qū)溢出時,溢出的數(shù)據(jù)覆蓋掉一個可執(zhí)行程序的入口地址(如函數(shù)的返回地址,函數(shù)指針變量等等),使得該地址指向shellcode,從而當程序試圖通過該入口地址執(zhí)行代碼時,就會執(zhí)行攻擊者的shellcode。第二種模式下,攻擊者想要的攻擊代碼已經(jīng)在被攻擊的程序中了,攻擊者所要做的只是為攻擊代碼傳遞它所需要的參數(shù),然后用一個系統(tǒng)函數(shù)的地址覆蓋可執(zhí)行代碼的入口地址,通過巧妙的構(gòu)造可以使程序用預(yù)設(shè)的參數(shù)調(diào)用系統(tǒng)函數(shù)。第二種攻擊模式的出現(xiàn)是因為第一種模式需要?;蚨褍?nèi)存具有可執(zhí)行屬性,而隨著緩沖區(qū)溢出攻擊日益猖獗,出現(xiàn)了不可執(zhí)行的堆或棧的概念,有些操作系統(tǒng)(比如Linux)采取了對應(yīng)的補丁策略使得代碼注入攻擊不可行,而第二種攻擊模式不受此限制。一般來說,根據(jù)緩沖區(qū)溢出發(fā)生的位置可以將緩沖區(qū)溢出漏洞分成:棧溢出,堆(Heap)溢出,靜態(tài)數(shù)據(jù)段(BSS)溢出。棧溢出一個堆棧包括:一塊連續(xù)的內(nèi)存塊,一個堆棧指針(SP)指向堆棧的棧頂,一個基址指針(BP)保存具有固定偏移的局部變量和函數(shù)參數(shù)的基地址。在Intel處理器中,SP保存在寄存器esp中,BP保存在寄存器ebp中。棧支持兩種操作,壓棧(PUSH)和彈出(POP)。PUSH是將數(shù)據(jù)放到棧的頂端,POP是將棧頂?shù)臄?shù)據(jù)取出。壓棧和彈出操作均會自動改變esp的值,即棧頂發(fā)生變化。在高級語言中,程序函數(shù)調(diào)用和函數(shù)中的臨時變量都用到棧,參數(shù)的傳遞和返回值也通過棧來實現(xiàn),通常對局部變量的引用是通過給出它們相對BP的偏移量來實現(xiàn)的。當程序中發(fā)生函數(shù)調(diào)用時,計算機做如下操作:首先把參數(shù)壓入堆棧;其次把指令寄存器(IP,在Intel處理器中稱為eip)中的內(nèi)容壓棧,作為返回地址(ret);第三個放入棧的是基址寄存器(BP);然后把當前的棧指針(SP)拷貝到BP,作為新的基地址;最后把SP減去適當?shù)臄?shù)值,為本地變量留出一定空間。調(diào)用者完成壓棧操作后,調(diào)用函數(shù)。函數(shù)被調(diào)用以后,在棧中取得數(shù)據(jù),并進行計算。函數(shù)計算結(jié)束以后,調(diào)用者或者函數(shù)本身修改棧,使?;謴?fù)平衡。一般來說,根據(jù)覆蓋數(shù)據(jù)的內(nèi)容不同,可能會導(dǎo)致以下幾種結(jié)果:(1)覆蓋了其他局部變量。如果被覆蓋的局部變量是條件變量,那么可能會改變函數(shù)原本的執(zhí)行流程,這種方式可以用于破解簡單的軟件驗證。(2)覆蓋了ebp的值。修改了函數(shù)執(zhí)行結(jié)束后要恢復(fù)的棧指針,將會導(dǎo)致棧幀失去平衡,即函數(shù)調(diào)用關(guān)系及相關(guān)現(xiàn)場信息被破壞,程序無法正常執(zhí)行下去。(3)覆蓋了返回地址。通過覆蓋的方式修改函數(shù)的返回地址,使程序代碼執(zhí)行“意外”的流程。如果用于溢出的數(shù)據(jù)內(nèi)保存了一系列指令的二進制代碼(shellcode),一旦棧溢出修改了函數(shù)的返回地址,并將該地址指向這段二進制代碼的起始位置,程序?qū)⑥D(zhuǎn)而執(zhí)行攻擊者植入的shellcode。這就是棧溢出攻擊原理的核心所在。(4)覆蓋參數(shù)變量。修改函數(shù)的參數(shù)變量可能改變當前函數(shù)的執(zhí)行結(jié)果和流程。(5)覆蓋上級函數(shù)的棧幀。這種情況與第(4)種情況類似,只不過影響的是上級函數(shù)的執(zhí)行。當然這里的前提是保證函數(shù)能正常返回,即函數(shù)地址不能被隨意修改,而要實現(xiàn)這一點就比較復(fù)雜了。對于第(3)種情況,理論上能完成棧溢出攻擊,但是實際利用過程很難直接跳轉(zhuǎn)到shellcode地址。操作系統(tǒng)每次運行程序分配的棧地址是不確定的,因此存放在棧上的shellcode地址也不確定,很難通過硬編碼的方式覆蓋新返回地址。為了能準確定位shellcode的地址,需要借助一些額外的操作,其中比較經(jīng)典的是借助跳板的棧溢出方式。緩沖區(qū)溢出攻擊最關(guān)鍵的步驟就是使目標程序執(zhí)行攻擊者植入的shellcode。其功能一般是在目標主機上為攻擊者提供遠程控制接口,如開放遠程shell(Unix系統(tǒng)中的命令解釋程序)或遠程命令行窗口(Windows系統(tǒng)中的cmd)。一般來說,shellcode應(yīng)滿足以下要求:(1)shellcode中可能不允許出現(xiàn)一些特殊字符。例如,對于針對strcpy類函數(shù)引起的緩沖區(qū)溢出攻擊,shellcode中不允許有任何的NULL字符(”\x0”),這是因為NULL字符是字符串的結(jié)束符。(2)shellcode應(yīng)短小精悍,這主要是由于緩沖區(qū)大小有限。(3)shellcode與操作系統(tǒng)有關(guān),Windows系統(tǒng)上的shellcode不能用于Linux系統(tǒng)。shellcode的編寫比較復(fù)雜,一般有兩種方法。一種是使用匯編語言編寫,用匯編編譯器編譯后得到二進制代碼;另外一種是在C語言中嵌入?yún)R編代碼,使用C語言編譯器編譯,然后從編譯過的可執(zhí)行文件中提取二進制可執(zhí)行代碼,得到shellcode。堆溢出堆是由進程動態(tài)分配的內(nèi)存區(qū)。進程通過malloc類函數(shù)分配堆內(nèi)存,通過free類函數(shù)釋放。如果進程沒有主動調(diào)用對應(yīng)的free類函數(shù)來釋放所申請的堆內(nèi)存空間,這些堆內(nèi)存空間會一直保留到進程終結(jié)才會由操作系統(tǒng)來執(zhí)行釋放操作(有些高級語言,如Java,有自動收集并釋放無用內(nèi)存機制,無需等到進程結(jié)束才釋放)。堆由很多內(nèi)存塊組成,其中一些已分配使用,一些是空閑的。與堆棧的增長方向相反,在大部分的系統(tǒng)(包括Linux系統(tǒng))中,堆是向上增長的(向高地址方向增長)。利用堆溢出漏洞實現(xiàn)攻擊的難點之一是不同的操作系統(tǒng)采用的堆內(nèi)存管理機制不同,甚至相同的操作系統(tǒng)如果版本不同也會有不同的堆內(nèi)存管理機制,這使得攻擊代碼的通用性比較差。攻擊者要利用堆緩沖區(qū)溢出漏洞進行攻擊,就需要針對不同的堆管理機制編寫不同的攻擊代碼和利用程序,但這僅僅是工作量的問題。BSS段溢出BSS用于存放未初始化的全局變量。在寫入數(shù)據(jù)前,它始終保持全零。由于在考慮緩沖區(qū)溢出攻擊時,堆和BSS段具有相近的特性,因此提到的“基于堆的溢出”既包含堆的溢出,也包含BSS段的溢出。在大部分系統(tǒng)(包括Linux系統(tǒng))中,BSS段也是向上增長的(向高地址方向增長)。BSS段存放全局和靜態(tài)的未初始化變量,變量與變量之間是連續(xù)存放的,沒有保留空間。這樣定義的兩個字符數(shù)組即是位于BSS段:staticcharbuf1[16],buf2[16];如果事先向buf2中寫入16個字符A,之后再往buf1中寫入24個B,由于變量之間是連續(xù)存放的,靜態(tài)字符數(shù)組buf1溢出后,就會覆蓋其相鄰區(qū)域字符數(shù)組buf2的值。利用這一點,攻擊者可以通過改寫B(tài)SS中的指針或函數(shù)指針等方式,改變程序原先的執(zhí)行流程,使指針跳轉(zhuǎn)到特定的內(nèi)存地址并執(zhí)行指定操作。(四)其他溢出整數(shù)類型規(guī)定了整型變量能存放的數(shù)值范圍是固定的,當試圖用一個大于或小于其取值范圍的數(shù)值對其進行賦值時,或者諸如加、減、乘、左移和類型轉(zhuǎn)換等操作使得其結(jié)果超出相應(yīng)的范圍,使得計算結(jié)果是期望值與相應(yīng)類型極值的取模,這類計算結(jié)果的失真稱為整數(shù)溢出。不同符號或?qū)挾乳g的類型轉(zhuǎn)換可能導(dǎo)致計算結(jié)果失真或數(shù)值被誤解,也會引發(fā)整數(shù)溢出。當溢出的整數(shù)變量用作其他類似于數(shù)組下標或者數(shù)組訪問的邊界控制時,它們就有可能被攻擊者間接利用實施諸如惡意代碼執(zhí)行、拒絕服務(wù)等攻擊行為。由于格式化字符串函數(shù)的參數(shù)個數(shù)的不確定性,使得攻擊者可以利用它來進行讀寫攻擊,改變或讀取指定內(nèi)存的內(nèi)容。函數(shù)sprintf(char*str,constchar*format,...)將格式化的數(shù)據(jù)寫入str所指的數(shù)組中,并添加‘\0’,如果格式化的數(shù)據(jù)長度超出了數(shù)組的容量就會溢出。緩沖區(qū)溢出攻擊的防護(一)基本思路攻擊者要利用緩沖區(qū)溢出漏洞進行攻擊,兩個必要條件必須滿足:第一,存在緩沖區(qū)溢出漏洞;第二,這個緩沖區(qū)溢出漏洞必須是可以利用的。防御者的目的就是破壞這兩個條件中的一個或者兩個。防御者可以通過某種手段,比如檢測,在程序發(fā)布之前找到其中的漏洞并給予修復(fù),從而使得第一個必要條件不成立。防御者也可以通過一定方式,比如修改堆棧機制,使得即使程序中存在緩沖區(qū)溢出漏洞,也無法利用這種漏洞(最多使程序出現(xiàn)內(nèi)存訪問錯誤,導(dǎo)致拒絕服務(wù)攻擊),使得第二個條件不成立。據(jù)此,可以將緩沖區(qū)溢出漏洞的防御方式分為兩種:主動式防御和被動式防御。(二)主動式防御解決緩沖區(qū)溢出攻擊最直接的方式是確保程序中不存在緩沖區(qū)溢出漏洞。為達到這一目的,主要有以下幾種措施。1)使用安全的編程語言絕大多數(shù)軟件中的緩沖區(qū)溢出漏洞源于C/C++語言的不安全性。C/C++語言本身不對緩沖區(qū)邊界進行限定,主要目的是提供最高的效率。程序員在編寫程序的時候,必須記住緩沖區(qū)是有邊界的,對緩沖區(qū)的讀寫不能超出其邊界。2)替換不安全函數(shù)將現(xiàn)存的代碼采用新的編程語言重寫是不現(xiàn)實的。一種可行的解決方案是,將程序中的一些不安全函數(shù)替換成安全的函數(shù),如用strncpy替換strcpy,用strncat替換strcat。這些安全的函數(shù)將對緩沖區(qū)讀寫進行嚴格的邊界檢查。3)養(yǎng)成良好的編程習(xí)慣如果采用C/C++語言進行程序開發(fā),避免緩沖區(qū)溢出漏洞的最根本的解決辦法是程序員加強安全意識,在每次進行緩沖區(qū)操作時一定要進行嚴格的邊界檢查。(三)被動式防御溢出漏洞不可避免,那么可采取措施使得漏洞不可用,這就是被動防御方法。以下是幾種著名的被動防御技術(shù)。1.棧和堆不可執(zhí)行大多數(shù)情況下,shellcode被注入到堆中或者棧中,如果使堆和棧不具有可執(zhí)行屬性,則可以防御代碼注入的攻擊。這種方法的優(yōu)點是對性能影響小,缺點是需要修改并重新編譯內(nèi)核。由于ret2libc的旁路攻擊不需要執(zhí)行堆和棧中的代碼,所以這種方法對非代碼注入型溢出攻擊無效。此外,有些程序本身可能被設(shè)計成需要執(zhí)行堆或者棧空間中的代碼,使得這種方式存在軟件兼容性問題。2.StackGuardStackGuard對編譯器進行擴展,調(diào)用函數(shù)時在堆棧的局部變量和函數(shù)地址之間存放隨機產(chǎn)生的4B的“canary”字,在函數(shù)返回之前檢查“canary”的完整性。這種方法的缺點是:需要源碼;由于每調(diào)用一次函數(shù)都要對“canary”進行一次校驗,程序效率會下降;不能保護函數(shù)參數(shù)、局部變量、棧指針及位于堆中的數(shù)據(jù);無法阻止堆溢出攻擊;通過破壞堆棧中舊幀指針或局部指針變量可以繞過這種安全機制。3.StackShieldStackShield是創(chuàng)建一個特別的堆棧用來存儲函數(shù)返回地址的一份拷貝。它在受保護的函數(shù)的開頭和結(jié)尾分別增加一段代碼,開頭處的代碼用來將函數(shù)返回地址拷貝到一個特殊的表中,而結(jié)尾處的代碼用來將返回地址從表中拷貝回堆棧。這種技術(shù)需要在編譯階段使用,需要源代碼;有效率損失;不能保護函數(shù)參數(shù)、局部變量、棧指針及位于堆中的數(shù)據(jù),不能抵抗基于堆溢出的攻擊。4.PointGuardPointGuard的基本思想是:攻擊者利用緩沖區(qū)溢出漏洞只會溢出修改堆、棧、數(shù)據(jù)段上的數(shù)據(jù),而不會修改存儲在寄存器中的數(shù)據(jù),內(nèi)存中如果存放的是加密后的數(shù)據(jù),攻擊者就無法隨心所欲地進行攻擊。PointGuard對指針型數(shù)據(jù)進行加密后再將其存放在內(nèi)存中,指針引用前再在寄存器中解密。5.ProPoliceProPolice使用一個修改過的編譯器在函數(shù)調(diào)用中插入一段檢測代碼以檢測堆棧溢出。不同的是,它對堆棧中的局部變量的位置進行重新排序,讓字符型緩沖區(qū)緊挨著舊基指針的棧底,并復(fù)制函數(shù)參數(shù)中的指針,以便它們排在任何數(shù)組之前,使得該緩沖區(qū)溢出時不會修改函數(shù)指針。但是,ProPolice不能保護位于堆中的數(shù)據(jù),也無法抵抗基于堆溢出的攻擊。6.攔截脆弱函數(shù)Libsafe重新編寫了C庫中不安全的函數(shù),先于C庫安裝。在運行時攔截所有對具有緩沖區(qū)溢出風(fēng)險的庫函數(shù)的調(diào)用,并調(diào)用具有邊界檢查功能的安全函數(shù)來完成原功能。如果邊界檢查不通過,就報警并終止進程。7.打亂和加密這種技術(shù)使得攻擊者的惡意代碼即使成功注入目標軟件,也不能運行,從而有效防止通過注入惡意代碼來實施破壞。很多攻擊都基于內(nèi)存分配的規(guī)律,一般需要知道攻擊代碼在內(nèi)存中的存儲位置或者將要覆蓋內(nèi)存的哪些區(qū)域。基于這個原因,改變傳統(tǒng)的內(nèi)存分配算法,在程序加載時,將內(nèi)存布局打亂,從而有效地防御緩沖區(qū)溢出的攻擊?;诙褩5木彌_區(qū)溢出攻擊一般需要了解系統(tǒng)調(diào)用映射或庫的入口點,通過隨機化堆棧起點、隨機化系統(tǒng)調(diào)用映射和改變庫的入口點可以防御緩沖區(qū)溢出攻擊。加密可執(zhí)行文件,在程序執(zhí)行前解密,同樣可以防御采用注入攻擊代碼的方式進行的緩沖區(qū)溢出攻擊。當運行到攻擊代碼時,因為攻擊代碼事先沒有加密,故采用解密操作對其進行處理后代碼不能正確運行。8.硬件增強方式硬件增強是最底層的技術(shù),如果能用于檢測和預(yù)防緩沖區(qū)溢出漏洞
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 會議后續(xù)跟蹤與效果評估制度
- 2026年浙江大學(xué)杭州國際科創(chuàng)中心吳新科教授課題組招聘備考題庫及答案詳解參考
- 2026年浙江大學(xué)愛丁堡大學(xué)聯(lián)合學(xué)院方兆元課題組科研助理招聘備考題庫及1套參考答案詳解
- 企業(yè)設(shè)備管理規(guī)范制度
- 中學(xué)學(xué)生社團活動經(jīng)費管理流程制度
- 2026年湘潭市九華中學(xué)(長沙市一中九華中學(xué))代課教師招聘備考題庫完整答案詳解
- 2026年榆林市第五幼兒園招聘備考題庫及參考答案詳解1套
- 2026年鐘祥市國有企業(yè)公開招聘工作人員16人備考題庫完整答案詳解
- 2026年玉環(huán)公證處招聘備考題庫及一套答案詳解
- 2026年河南姚孟能源投資有限公司招聘備考題庫及參考答案詳解一套
- 光環(huán)境對植物生長的優(yōu)化設(shè)計-全面剖析
- 資源循環(huán)科學(xué)與工程專業(yè)課程教學(xué)大綱匯編
- 裝飾裝修驗收方案
- 2024年中國燃氣具行業(yè)分析及2025年機會預(yù)測
- 七年級上冊語文人教版字詞帶拼音解釋(完整版)
- 環(huán)境監(jiān)測站電路安裝施工方案
- DB14∕T 1754-2018 保模一體板現(xiàn)澆混凝土復(fù)合保溫系統(tǒng)通.用技術(shù)條件
- DB13T 1264-2010 遠程射霧技術(shù)應(yīng)用規(guī)范
- 員工獎勵申請表格模板(可修改)
- 電梯安裝施工合同
- 3.2+細胞器之間的分工合作課件高一上學(xué)期生物人教版(2019)必修1
評論
0/150
提交評論