第7章:緩沖區(qū)溢出攻擊及防御技術(shù)_第1頁
第7章:緩沖區(qū)溢出攻擊及防御技術(shù)_第2頁
第7章:緩沖區(qū)溢出攻擊及防御技術(shù)_第3頁
第7章:緩沖區(qū)溢出攻擊及防御技術(shù)_第4頁
第7章:緩沖區(qū)溢出攻擊及防御技術(shù)_第5頁
已閱讀5頁,還剩129頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第第7 7章章 緩沖區(qū)溢出攻擊及防御技術(shù)緩沖區(qū)溢出攻擊及防御技術(shù)2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)2本章內(nèi)容安排本章內(nèi)容安排o 7.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述 o 7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理 o 7.3 緩沖區(qū)溢出的過程緩沖區(qū)溢出的過程 o 7.4 代碼植入技術(shù)代碼植入技術(shù)o 7.5 實例:實例:ida溢出漏洞攻擊溢出漏洞攻擊o 7.6 緩沖區(qū)溢出的防御緩沖區(qū)溢出的防御 o 7.7 小結(jié)小結(jié) 2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)37.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 什么是什么是緩沖區(qū)緩沖區(qū)?它是包含相同數(shù)據(jù)類型實例的一個?它是包含相同數(shù)據(jù)類型實例的一個連續(xù)的計算機內(nèi)存塊。

2、是程序運行期間在內(nèi)存中分連續(xù)的計算機內(nèi)存塊。是程序運行期間在內(nèi)存中分配的一個連續(xù)的區(qū)域,用于保存包括字符數(shù)組在內(nèi)配的一個連續(xù)的區(qū)域,用于保存包括字符數(shù)組在內(nèi)的各種數(shù)據(jù)類型。的各種數(shù)據(jù)類型。o 所謂所謂溢出溢出,其實就是所填充的數(shù)據(jù)超出了原有的緩,其實就是所填充的數(shù)據(jù)超出了原有的緩沖區(qū)邊界。沖區(qū)邊界。o 兩者結(jié)合進來,所謂兩者結(jié)合進來,所謂緩沖區(qū)溢出緩沖區(qū)溢出,就是向固定長度,就是向固定長度的緩沖區(qū)中寫入超出其預(yù)告分配長度的內(nèi)容,造成的緩沖區(qū)中寫入超出其預(yù)告分配長度的內(nèi)容,造成緩沖區(qū)中數(shù)據(jù)的溢出,從而覆蓋了緩沖區(qū)周圍的內(nèi)緩沖區(qū)中數(shù)據(jù)的溢出,從而覆蓋了緩沖區(qū)周圍的內(nèi)存空間。黑客借此精心構(gòu)造填充數(shù)據(jù)

3、,導(dǎo)致原有流存空間。黑客借此精心構(gòu)造填充數(shù)據(jù),導(dǎo)致原有流程的改變,讓程序轉(zhuǎn)而執(zhí)行特殊的代碼,最終獲取程的改變,讓程序轉(zhuǎn)而執(zhí)行特殊的代碼,最終獲取控制權(quán)??刂茩?quán)。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)47.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 利用緩沖區(qū)溢出漏洞進行攻擊最早可追溯到利用緩沖區(qū)溢出漏洞進行攻擊最早可追溯到1988年年Morris蠕蟲,它所利用的就是蠕蟲,它所利用的就是fingerd程序的緩沖區(qū)溢出程序的緩沖區(qū)溢出漏洞。漏洞。o 1989年,年,Spafford提交了一份分析報告,描述了提交了一份分析報告,描述了VAX機上機上BSD版版Unix的的Fingerd的緩沖區(qū)溢出程序的技術(shù)細的

4、緩沖區(qū)溢出程序的技術(shù)細節(jié),引起了一部分安全人士對這個研究領(lǐng)域的重視。節(jié),引起了一部分安全人士對這個研究領(lǐng)域的重視。o 1996年,年,Aleph One發(fā)表了題為發(fā)表了題為“Smashing the stack for fun and profit”的文章后,首次詳細地介紹的文章后,首次詳細地介紹了了Unix/Linux下棧溢出攻擊的原理、方法和步驟,揭示下棧溢出攻擊的原理、方法和步驟,揭示了緩沖區(qū)溢出攻擊中的技術(shù)細節(jié)。了緩沖區(qū)溢出攻擊中的技術(shù)細節(jié)。o 1999年年w00w00安全小組的安全小組的Matt Conover寫了基于寫了基于堆緩沖區(qū)溢出專著,對堆溢出的機理進行了探索。堆緩沖區(qū)溢出專

5、著,對堆溢出的機理進行了探索。7.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o Windows系統(tǒng)中緩沖區(qū)溢出的事例更是層出不窮。系統(tǒng)中緩沖區(qū)溢出的事例更是層出不窮。o 2001年年“紅色代碼紅色代碼”蠕蟲利用微軟蠕蟲利用微軟IIS Web Server中中的緩沖區(qū)溢出漏洞使的緩沖區(qū)溢出漏洞使300 000多臺計算機受到攻擊;多臺計算機受到攻擊;o 2003年年1月,月,Slammer蠕蟲爆發(fā),利用的是微軟蠕蟲爆發(fā),利用的是微軟SQL Server 2000中的缺陷;中的缺陷;o 2004年年5月爆發(fā)的月爆發(fā)的“振蕩波振蕩波”利用了利用了Windows系統(tǒng)的活系統(tǒng)的活動目錄服務(wù)緩沖區(qū)溢出漏洞;動目錄服務(wù)

6、緩沖區(qū)溢出漏洞;o 2005年年8月利用月利用Windows即插即用緩沖區(qū)溢出漏洞的即插即用緩沖區(qū)溢出漏洞的“狙擊波狙擊波”被稱為歷史上最快利用微軟漏洞進行攻擊的惡意代被稱為歷史上最快利用微軟漏洞進行攻擊的惡意代碼。碼。o 2008年底至年底至2009年的年的Conficker蠕蟲利用的是蠕蟲利用的是Windows處理遠程處理遠程RPC請求時的漏洞(請求時的漏洞(MS08-067)。)。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)67.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 目前,利用緩沖區(qū)溢出漏洞進行的攻擊已經(jīng)占所有系統(tǒng)目前,利用緩沖區(qū)溢出漏洞進行的攻擊已經(jīng)占所有系統(tǒng)攻擊總數(shù)的攻擊總數(shù)的80%以上。以上

7、。 o 緩沖區(qū)溢出攻擊之所以日益普遍,其原因在于各種操作緩沖區(qū)溢出攻擊之所以日益普遍,其原因在于各種操作系統(tǒng)和應(yīng)用軟件上存在的緩沖區(qū)溢出問題數(shù)不勝數(shù),而系統(tǒng)和應(yīng)用軟件上存在的緩沖區(qū)溢出問題數(shù)不勝數(shù),而其帶來的影響不容小覷。其帶來的影響不容小覷。o 對緩沖區(qū)溢出漏洞攻擊,可以導(dǎo)致程序運行失敗、系統(tǒng)對緩沖區(qū)溢出漏洞攻擊,可以導(dǎo)致程序運行失敗、系統(tǒng)崩潰以及重新啟動等后果。崩潰以及重新啟動等后果。o 更為嚴重的是,可以利用緩沖區(qū)溢出執(zhí)行非授權(quán)指令,更為嚴重的是,可以利用緩沖區(qū)溢出執(zhí)行非授權(quán)指令,甚至取得系統(tǒng)特權(quán),進而進行各種非法操作。甚至取得系統(tǒng)特權(quán),進而進行各種非法操作。o 如何防止和檢測出利用緩沖

8、區(qū)溢出漏洞進行的攻擊,就如何防止和檢測出利用緩沖區(qū)溢出漏洞進行的攻擊,就成為防御網(wǎng)絡(luò)入侵以及入侵檢測的重點之一。成為防御網(wǎng)絡(luò)入侵以及入侵檢測的重點之一。 7.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 與其他的攻擊類型相比,緩沖區(qū)溢出攻擊與其他的攻擊類型相比,緩沖區(qū)溢出攻擊n 不需要太多的先決條件n 殺傷力很強n 技術(shù)性強o 緩沖區(qū)溢出比其他一些黑客攻擊手段更具有緩沖區(qū)溢出比其他一些黑客攻擊手段更具有破壞力破壞力和和隱蔽性隱蔽性。這也是利用緩沖區(qū)溢出漏。這也是利用緩沖區(qū)溢出漏洞進行攻擊日益普遍的原因。洞進行攻擊日益普遍的原因。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)72022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)8

9、7.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 破壞性:破壞性:n 它極容易使服務(wù)程序停止運行,服務(wù)器死機甚至刪除服務(wù)器上的數(shù)據(jù)。o 隱蔽性:隱蔽性:n 首先,漏洞被發(fā)現(xiàn)之前,程序員一般是不會意識到自己的程序存在漏洞的(事實上,漏洞的發(fā)現(xiàn)者往往并非編寫者),于是疏于監(jiān)測;n 其次,被植入的攻擊代碼一般都很短,執(zhí)行時間也非常短,很難在執(zhí)行過程中被發(fā)現(xiàn),而且其執(zhí)行并不一定會使系統(tǒng)報告錯誤,并可能不影響正常程序的運行;7.1 緩沖區(qū)溢出概述緩沖區(qū)溢出概述o 隱蔽性:隱蔽性:n第三,由于漏洞存在于防火墻內(nèi)部的主機上,攻擊者可以在防火墻內(nèi)部堂而皇之地取得本來不被允許或沒有權(quán)限的控制權(quán);n第四,攻擊的隨機性和不可

10、預(yù)測性使得防御變得異常艱難,沒有攻擊時,被攻擊程序本身并不會有什么變化,也不會存在任何異常的表現(xiàn);n最后,緩沖區(qū)溢出漏洞的普遍存在,針對它的攻擊讓人防不勝防(各種補丁程序也可能存在著這種漏洞。7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 7.2.1 棧溢出棧溢出o 7.2.2 堆溢出堆溢出o 7.2.3 BSS溢出溢出o 7.2.4 格式化串溢出格式化串溢出2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)117.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 當程序運行時,計算機會在內(nèi)存區(qū)域中開當程序運行時,計算機會在內(nèi)存區(qū)域中開辟一段連續(xù)的內(nèi)存塊,包括代碼段、數(shù)據(jù)辟一段連續(xù)的內(nèi)存塊,包括代碼段、數(shù)據(jù)段和堆棧段三部分。段和

11、堆棧段三部分。7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 程序在內(nèi)存中的存放形式程序在內(nèi)存中的存放形式7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 代碼段代碼段(.text),也稱文本段,也稱文本段(Text Segment),存放著程序的機器碼和只讀數(shù)據(jù),可執(zhí)行指令就,存放著程序的機器碼和只讀數(shù)據(jù),可執(zhí)行指令就是從這里取得的。如果可能,系統(tǒng)會安排好相同程是從這里取得的。如果可能,系統(tǒng)會安排好相同程序的多個運行實體共享這些實例代碼。這個段在內(nèi)序的多個運行實體共享這些實例代碼。這個段在內(nèi)存中一般被標記為只讀,任何對該區(qū)的寫操作都會存中一般被標記為只讀,任何對該區(qū)的寫操作都會導(dǎo)致段錯誤(導(dǎo)致段錯誤(Segm

12、entation Fault)。)。o 數(shù)據(jù)段,包括已初始化的數(shù)據(jù)段數(shù)據(jù)段,包括已初始化的數(shù)據(jù)段(.data)和未初始和未初始化的數(shù)據(jù)段(化的數(shù)據(jù)段(.bss),前者用來存放保存全局的),前者用來存放保存全局的和靜態(tài)的已初始化變量,后者用來保存全局的和靜和靜態(tài)的已初始化變量,后者用來保存全局的和靜態(tài)的未初始化變量。數(shù)據(jù)段在編譯時分配。態(tài)的未初始化變量。數(shù)據(jù)段在編譯時分配。 7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 堆棧段分為堆和棧。堆棧段分為堆和棧。o 堆(堆(Heap):位于):位于BSS內(nèi)存段的上邊,用來存儲內(nèi)存段的上邊,用來存儲程序運行時分配的變量。程序運行時分配的變量。o 堆的堆的大小并

13、不固定,可動態(tài)擴張或縮減。大小并不固定,可動態(tài)擴張或縮減。其分配由其分配由malloc()、new()等這類實時內(nèi)存分配函數(shù)來等這類實時內(nèi)存分配函數(shù)來實現(xiàn)。實現(xiàn)。當進程調(diào)用當進程調(diào)用malloc等函數(shù)分配內(nèi)存時,新等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張);當分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張);當利用利用free等函數(shù)釋放內(nèi)存時,被釋放的內(nèi)存從堆等函數(shù)釋放內(nèi)存時,被釋放的內(nèi)存從堆中被剔除(堆被縮減)。中被剔除(堆被縮減)。o 堆的內(nèi)存釋放由應(yīng)用程序去控制,通常一個堆的內(nèi)存釋放由應(yīng)用程序去控制,通常一個new()就要對應(yīng)一個就要對應(yīng)一個delete(),如果程序員沒有,如

14、果程序員沒有釋放掉,那么在程序結(jié)束后操作系統(tǒng)會自動回收。釋放掉,那么在程序結(jié)束后操作系統(tǒng)會自動回收。7.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 棧(棧(Stack)是一種用來存儲函數(shù)調(diào)用時的臨時信)是一種用來存儲函數(shù)調(diào)用時的臨時信息的結(jié)構(gòu),如函數(shù)調(diào)用所傳遞的參數(shù)、函數(shù)的返回息的結(jié)構(gòu),如函數(shù)調(diào)用所傳遞的參數(shù)、函數(shù)的返回地址、函數(shù)的局部變量等。地址、函數(shù)的局部變量等。o 在程序運行時由編譯器在需要的時候分配,在不需在程序運行時由編譯器在需要的時候分配,在不需要的時候自動清除。要的時候自動清除。 o 棧的特性棧的特性: 最后一個放入棧中的物體總是被最先拿最后一個放入棧中的物體總是被最先拿出來,這個特性通

15、常稱為出來,這個特性通常稱為先進后出先進后出(FILO)隊列。隊列。o 棧的基本操作:棧的基本操作: nPUSH操作:向棧中添加數(shù)據(jù),稱為壓棧,數(shù)據(jù)將放置在棧頂;nPOP操作:POP操作相反,在棧頂部移去一個元素,并將棧的大小減一,稱為彈棧。堆和棧的區(qū)別堆和棧的區(qū)別o分配和管理方式不同分配和管理方式不同n堆是動態(tài)分配的,其空間的分配和釋放都由程序員控制。n棧由編譯器自動管理。棧有兩種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配由編譯器完成,比如局部變量的分配。動態(tài)分配由alloca()函數(shù)進行分配,但是棧的動態(tài)分配和堆是不同的,它的動態(tài)分配是由編譯器進行釋放,無須手工控制。o產(chǎn)生碎片不同產(chǎn)生碎片不同

16、n對堆來說,頻繁的new/delete或者malloc/free勢必會造成內(nèi)存空間的不連續(xù),造成大量的碎片,使程序效率降低。n對棧而言,則不存在碎片問題,因為棧是先進后出的隊列,永遠不可能有一個內(nèi)存塊從棧中間彈出。o生長方向不同生長方向不同n堆是向著內(nèi)存地址增加的方向增長的,從內(nèi)存的低地址向高地址方向增長。n棧的生長方向與之相反,是向著內(nèi)存地址減小的方向增長,由內(nèi)存的高地址向低地址方向增長。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)177.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 在這里,我們假設(shè)現(xiàn)在有一個程序,在這里,我們假設(shè)現(xiàn)在有一個程序, 它的函數(shù)它的函數(shù)調(diào)用順序如下。調(diào)用順序如下。 main()

17、-; func_1() -; func_2() -; func_3() 即: 主函數(shù)main調(diào)用函數(shù)func_1; 函數(shù)func_1調(diào)用函數(shù)func_2; 函數(shù)func_2調(diào)用函數(shù)func_3。其詳細結(jié)構(gòu)圖如下頁圖所示。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)18程序在內(nèi)存中的影像程序在內(nèi)存中的影像o 隨著函數(shù)調(diào)用層數(shù)的增加,函數(shù)棧幀是一塊塊隨著函數(shù)調(diào)用層數(shù)的增加,函數(shù)棧幀是一塊塊地向內(nèi)存低地址方向延伸的。地向內(nèi)存低地址方向延伸的。 o 隨著進程中函數(shù)調(diào)用層數(shù)的減少,即各函數(shù)調(diào)隨著進程中函數(shù)調(diào)用層數(shù)的減少,即各函數(shù)調(diào)用的返回,棧幀會一塊塊地被遺棄而向內(nèi)存的用的返回,棧幀會一塊塊地被遺棄而向內(nèi)存的高

18、址方向回縮。高址方向回縮。 o 各函數(shù)的棧幀大小隨著函數(shù)的性質(zhì)的不同而不各函數(shù)的棧幀大小隨著函數(shù)的性質(zhì)的不同而不等,由函數(shù)的局部變量的數(shù)目決定。等,由函數(shù)的局部變量的數(shù)目決定。o 在緩沖區(qū)溢出中,在緩沖區(qū)溢出中,我們主要關(guān)注數(shù)據(jù)區(qū)和堆棧我們主要關(guān)注數(shù)據(jù)區(qū)和堆棧區(qū)區(qū)。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)192022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)20程序所使用的棧程序所使用的棧o 在使用棧時,引用棧幀需要借助兩個寄存器。在使用棧時,引用棧幀需要借助兩個寄存器。o 一個是一個是SP(ESP),即,即棧頂指針棧頂指針,它隨著數(shù)據(jù)入,它隨著數(shù)據(jù)入棧出棧而發(fā)生變化。棧出棧而發(fā)生變化。o 另一個是另一個是BP

19、(EBP),即,即基地址指針基地址指針,它用于標,它用于標識棧中一個相對穩(wěn)定的位置,通過識棧中一個相對穩(wěn)定的位置,通過BP,再加上,再加上偏移地址,可以方便地引用函數(shù)參數(shù)以及局部變偏移地址,可以方便地引用函數(shù)參數(shù)以及局部變量。量。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)21程序所使用的棧程序所使用的棧o 函數(shù)被調(diào)用的時候,棧中的壓入情況如下:函數(shù)被調(diào)用的時候,棧中的壓入情況如下:最先壓入棧最先壓入棧最后壓入棧最后壓入棧2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)22程序所使用的棧程序所使用的棧o 在局部變量的下面,是前一個調(diào)用函數(shù)的在局部變量的下面,是前一個調(diào)用函數(shù)的EBP,接下來就是返回地址。,接下來就

20、是返回地址。o 如果局部變量發(fā)生溢出,很有可能會覆蓋掉如果局部變量發(fā)生溢出,很有可能會覆蓋掉EBP甚至甚至RET(返回地址返回地址),這就是緩沖區(qū),這就是緩沖區(qū)溢出攻擊的溢出攻擊的“奧秘奧秘”所在。所在。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)237.2 緩沖區(qū)溢出原理緩沖區(qū)溢出原理o 如果在堆棧中壓入的數(shù)據(jù)超過預(yù)先給堆棧分如果在堆棧中壓入的數(shù)據(jù)超過預(yù)先給堆棧分配的容量時,就會出現(xiàn)堆棧溢出,從而使得配的容量時,就會出現(xiàn)堆棧溢出,從而使得程序運行失??;如果發(fā)生溢出的是大型程序程序運行失敗;如果發(fā)生溢出的是大型程序還有可能會導(dǎo)致系統(tǒng)崩潰。還有可能會導(dǎo)致系統(tǒng)崩潰。 7.2.1 棧溢出棧溢出o 程序中發(fā)生

21、函數(shù)調(diào)用時,計算機做如下操作:程序中發(fā)生函數(shù)調(diào)用時,計算機做如下操作:首先把指令寄存器首先把指令寄存器EIP(它指向當前(它指向當前CPU將要將要運行的下一條指令的地址)中的內(nèi)容壓入棧,運行的下一條指令的地址)中的內(nèi)容壓入棧,作為程序的返回地址(下文中用作為程序的返回地址(下文中用RET表示);表示);之后放入棧的是基址寄存器之后放入棧的是基址寄存器EBP,它指向當前,它指向當前函數(shù)棧幀(函數(shù)棧幀(stack frame)的底部;然后把)的底部;然后把當前的棧指針當前的棧指針ESP拷貝到拷貝到EBP,作為新的基地,作為新的基地址,最后為本地變量的動態(tài)存儲分配留出一定址,最后為本地變量的動態(tài)存儲

22、分配留出一定空間,并把空間,并把ESP減去適當?shù)臄?shù)值。減去適當?shù)臄?shù)值。7.2.1 棧溢出實例棧溢出實例o 我們來看一段簡單程序的執(zhí)行過程中對棧的操作和我們來看一段簡單程序的執(zhí)行過程中對棧的操作和溢出的產(chǎn)生過程。溢出的產(chǎn)生過程。#include int main()char name16;gets(name);for(int i=0;i16&namei;i+)printf(“%c”,namei); 2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)267.2.1 棧溢出實例棧溢出實例o 編譯上述代碼,輸入編譯上述代碼,輸入hello world! 結(jié)果會輸出結(jié)果會輸出hello world! o 在調(diào)

23、用在調(diào)用main()函數(shù)時,程序?qū)5牟僮骱瘮?shù)時,程序?qū)5牟僮魇沁@樣的:是這樣的:n 先在棧底壓入返回地址n 接著將棧指針EBP入棧,并把EBP修改為現(xiàn)在的ESPn 之后ESP減16,即向上增長16個字節(jié),用來存放name數(shù)組2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)277.2.1 棧溢出實例棧溢出實例o 現(xiàn)在棧的布局如圖所示?,F(xiàn)在棧的布局如圖所示。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)287.2.1 棧溢出實例棧溢出實例o 執(zhí)行完執(zhí)行完gets(name)之后,棧中的內(nèi)容如之后,棧中的內(nèi)容如下圖所示下圖所示2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)297.2.1 棧溢出實例棧溢出實例o 接著執(zhí)行接著執(zhí)行

24、for循環(huán),逐個打印循環(huán),逐個打印name數(shù)組中的字符,數(shù)組中的字符,直到碰到直到碰到0 x00字符字符o 最后,從最后,從main返回,將返回,將ESP增加增加16以回收以回收name數(shù)組占用的空間,此時數(shù)組占用的空間,此時ESP指向先前保存的指向先前保存的EBP值。值。程序?qū)⑦@個值彈出并賦給程序?qū)⑦@個值彈出并賦給EBP,使,使EBP重新指向重新指向main()函數(shù)調(diào)用者的棧的底部。然后再彈出現(xiàn)在位于函數(shù)調(diào)用者的棧的底部。然后再彈出現(xiàn)在位于棧頂?shù)姆祷氐刂窏m數(shù)姆祷氐刂稲ET,賦給,賦給EIP,CPU繼續(xù)執(zhí)行繼續(xù)執(zhí)行EIP所指向的命令。所指向的命令。 o 說明說明1:EIP寄存器的內(nèi)容表示將要

25、執(zhí)行的下一條指令寄存器的內(nèi)容表示將要執(zhí)行的下一條指令地址。地址。o 說明說明2:當調(diào)用函數(shù)時,:當調(diào)用函數(shù)時,nCall指令會將返回地址(Call指令下一條指令地址)壓入棧nRet指令會把壓棧的返回地址彈給EIP2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)307.2.1 棧溢出實例棧溢出實例o 如果輸入的字符串長度超過如果輸入的字符串長度超過16個字節(jié),例如輸個字節(jié),例如輸入:入:hello world!AAAAAAAA,則當執(zhí),則當執(zhí)行完行完gets(name)之后,棧的情況如圖所示。之后,棧的情況如圖所示。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)317.2.1 棧溢出實例棧溢出實例o 由于輸入的字符串

26、太長,由于輸入的字符串太長,name數(shù)組容納不數(shù)組容納不下,只好向棧的底部方向繼續(xù)寫下,只好向棧的底部方向繼續(xù)寫A。這些。這些A覆蓋了堆棧的老的元素,從上頁圖可以看覆蓋了堆棧的老的元素,從上頁圖可以看出,出,EBP,Ret 都已經(jīng)被都已經(jīng)被A覆蓋了。覆蓋了。o 從從main返回時,就必然會把返回時,就必然會把AAAA的的ASCII碼碼0 x41414141視作返回地址,視作返回地址,CPU會試圖執(zhí)行會試圖執(zhí)行0 x41414141處的指令,結(jié)處的指令,結(jié)果出現(xiàn)難以預(yù)料的后果,這樣就產(chǎn)生了一次堆果出現(xiàn)難以預(yù)料的后果,這樣就產(chǎn)生了一次堆棧溢出。棧溢出。o 在在Windows XP下用下用VC6.0

27、運行程序,結(jié)果運行程序,結(jié)果如下頁圖所示。如下頁圖所示。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)327.2.2 堆溢出堆溢出o 當我們需要較大的緩沖區(qū)或在寫代碼時不知道包含當我們需要較大的緩沖區(qū)或在寫代碼時不知道包含在緩沖區(qū)中對象的大小,常常要使用堆。在緩沖區(qū)中對象的大小,常常要使用堆。 o 堆溢出的工作方式幾乎與棧溢出的工作方式完全相堆溢出的工作方式幾乎與棧溢出的工作方式完全相同,唯一不同的是,堆沒有壓棧和入棧操作,而是同,唯一不同的是,堆沒有壓棧和入棧操作,而是分配和回收內(nèi)存。分配和回收內(nèi)存。o C語言中使用語言中使用malloc()和和free()函數(shù)實現(xiàn)內(nèi)存的函數(shù)實現(xiàn)內(nèi)存的動態(tài)分配和回收,

28、動態(tài)分配和回收,C+語言使用語言使用new()和和delete()函數(shù)來實現(xiàn)相同的功能。函數(shù)來實現(xiàn)相同的功能。 7.2.2 堆溢出實例堆溢出實例# include # include # include # include # define BUFFER-SIZE 16# define OVERLAYSIZE 8 /* 我們將覆蓋我們將覆蓋buf2 的前的前OVERLAYSIZE 個字節(jié)個字節(jié) */int main()u-long diff ;char * buf1 = (char * )malloc (BUFFER-SIZE) ;char * buf2 = (char * )malloc (

29、BUFFER-SIZE) ;diff = (u-long) buf2 - (u-long) buf1 ;printf (buf1 = %p , buf2 = %p , diff = 0 x %x ( %d) bytes n, buf1 , buf2 , diff , diff) ;/* 將將buf2 用用a填充填充 */memset (buf2 , a, BUFFER-SIZE - 1) , buf2BUFFER-SIZE - 1 = 0;printf (before overflow: buf2 = %s n, buf2) ;/* 用用diff + OVERLAYSIZE 個個b填充填充bu

30、f1 */memset (buf1 , b, (u-int) (diff + OVERLAYSIZE) ) ;printf (after overflow: buf2 = %s n, buf2) ;return 0 ; 7.2.2 堆溢出實例堆溢出實例o 運行結(jié)果:運行結(jié)果: / users/ test 41 % . / heap1 buf1 = 0 x8049858 , buf2 = 0 x8049870 , diff = 0 x18 (24) bytes before overflow: buf2 = aaaaaaaaaaaaaaa after overflow: buf2 = bbbbb

31、bbbaaaaaaao 我們看到,我們看到,buf2的前八個字節(jié)被覆蓋了,的前八個字節(jié)被覆蓋了,這是因為往這是因為往buf1中填寫的數(shù)據(jù)超出了它的中填寫的數(shù)據(jù)超出了它的邊界進入了邊界進入了buf2的范圍。由于的范圍。由于buf2的數(shù)據(jù)的數(shù)據(jù)仍然在有效的仍然在有效的Heap區(qū)內(nèi),程序仍然可以正區(qū)內(nèi),程序仍然可以正常結(jié)束。常結(jié)束。 7.2.2 堆溢出實例堆溢出實例o 雖然雖然buf1和和buf2是相繼分配的,但它們并是相繼分配的,但它們并不是緊挨著的,而是有八個字節(jié)的間距。這不是緊挨著的,而是有八個字節(jié)的間距。這是因為,使用是因為,使用malloc()動態(tài)分配內(nèi)存時,動態(tài)分配內(nèi)存時,系統(tǒng)向用戶返回

32、一個內(nèi)存地址,實際上在這系統(tǒng)向用戶返回一個內(nèi)存地址,實際上在這個地址前面通常還有個地址前面通常還有8字節(jié)的內(nèi)部結(jié)構(gòu),用字節(jié)的內(nèi)部結(jié)構(gòu),用來記錄分配的塊長度、上一個堆的字節(jié)數(shù)以來記錄分配的塊長度、上一個堆的字節(jié)數(shù)以及一些標志等。這個間距可能隨不同的系統(tǒng)及一些標志等。這個間距可能隨不同的系統(tǒng)環(huán)境而不同。環(huán)境而不同。buf1溢出后,溢出后,buf2的前的前8字字節(jié)也被改寫為節(jié)也被改寫為bbbbbbbb,buf2內(nèi)部的部內(nèi)部的部分內(nèi)容也被修改為分內(nèi)容也被修改為b。 7.2.2 堆溢出實例堆溢出實例o 示意圖:示意圖:7.2.2 堆溢出堆溢出o 堆溢出不如棧溢出流行,原因在于堆溢出不如棧溢出流行,原因在

33、于n 比棧溢出難度更大n 需要結(jié)合其他的技術(shù)n 對于內(nèi)存中變量的組織方式有一定的要求2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)387.2.3 BSS溢出溢出o .bss段存放全局和靜態(tài)的未初始化變量,其分配段存放全局和靜態(tài)的未初始化變量,其分配比較簡單,變量與變量之間是連續(xù)存放的,沒有保比較簡單,變量與變量之間是連續(xù)存放的,沒有保留空間。留空間。o 下面這樣定義的兩個字符數(shù)組即是位于下面這樣定義的兩個字符數(shù)組即是位于BSS段:段: static char buf116,buf216;o 如果事先向如果事先向buf2中寫入中寫入16個字符個字符A,之后再往,之后再往buf1中寫入中寫入24個個B,由于

34、變量之間是連續(xù)存放的,由于變量之間是連續(xù)存放的,靜態(tài)字符數(shù)組,靜態(tài)字符數(shù)組buf1溢出后,就會覆蓋其相鄰區(qū)溢出后,就會覆蓋其相鄰區(qū)域字符數(shù)組域字符數(shù)組buf2的值。利用這一點,攻擊者可以的值。利用這一點,攻擊者可以通過改寫通過改寫B(tài)SS中的指針或函數(shù)指針等方式,改變中的指針或函數(shù)指針等方式,改變程序原先的執(zhí)行流程,使指針跳轉(zhuǎn)到特定的內(nèi)存地程序原先的執(zhí)行流程,使指針跳轉(zhuǎn)到特定的內(nèi)存地址并執(zhí)行指定操作。址并執(zhí)行指定操作。 7.2.4 格式化串溢出格式化串溢出o 與前面三種溢出不同的是,這種溢出漏洞是利用了編程與前面三種溢出不同的是,這種溢出漏洞是利用了編程語言自身存在的安全問題。格式化串溢出源自語

35、言自身存在的安全問題。格式化串溢出源自*printf()類函數(shù)的參數(shù)格式問題(如類函數(shù)的參數(shù)格式問題(如printf、fprintf、sprintf等)。等)。oint printf (const char *format, arg1, arg2, ); 它們將根據(jù)它們將根據(jù)format的內(nèi)容(的內(nèi)容(%s,%d,%p,%x,%n,),將數(shù)據(jù)格式化后輸出。),將數(shù)據(jù)格式化后輸出。o 問題在于:問題在于:*printf()函數(shù)并不能確定數(shù)據(jù)參數(shù)函數(shù)并不能確定數(shù)據(jù)參數(shù)arg1,arg2,究竟在什么地方結(jié)束,即函數(shù)本身不知道究竟在什么地方結(jié)束,即函數(shù)本身不知道參數(shù)的個數(shù),而只會根據(jù)參數(shù)的個數(shù),而只會

36、根據(jù)format中打印格式的數(shù)目依中打印格式的數(shù)目依次打印堆棧中參數(shù)次打印堆棧中參數(shù)format后面地址的內(nèi)容。后面地址的內(nèi)容。 7.2.4 格式化串溢出實例格式化串溢出實例/*程序說明:程序說明:%#x:按:按16進制輸出,并在前面加上進制輸出,并在前面加上0 x%.20d:按:按10進制輸出,輸出進制輸出,輸出20位,并在前面補位,并在前面補0%n:將顯示內(nèi)容的長度輸出到一個變量中去:將顯示內(nèi)容的長度輸出到一個變量中去*/# include main()int num= 0 x61616161 ;printf (Before : num = %#x n, num) ;printf (%.2

37、0d %n n, num, &num) ;printf (After : num = %#x n, num) ; 7.2.4 格式化串溢出實例格式化串溢出實例o 當程序執(zhí)行第二個當程序執(zhí)行第二個printf語句時,參數(shù)壓棧語句時,參數(shù)壓棧之后的內(nèi)存布局如下:之后的內(nèi)存布局如下:7.2.4 格式化串溢出實例格式化串溢出實例o 根據(jù)根據(jù)C函數(shù)調(diào)用約定,參數(shù)從右向左依次壓棧,所以參函數(shù)調(diào)用約定,參數(shù)從右向左依次壓棧,所以參數(shù)數(shù)&num比參數(shù)比參數(shù)num先壓入棧中。也就是說,程序中先壓入棧中。也就是說,程序中將將&num (num的地址的地址)壓入棧作為壓入棧作為printf(

38、)的第三的第三個參數(shù),而使用打印格式個參數(shù),而使用打印格式%n會將打印總長度保存到對會將打印總長度保存到對應(yīng)參數(shù)應(yīng)參數(shù)(&num)的地址中去,從而改變了的地址中去,從而改變了num的值。的值。 o 整個程序的輸出結(jié)果為:整個程序的輸出結(jié)果為: Before : num = 0 x61616161 00000000001633771873 After : num = 0 x14o 變量變量num的值已經(jīng)變成了的值已經(jīng)變成了0 x14(20)。7.2.4 格式化串溢出實例格式化串溢出實例o 如果將第二個如果將第二個printf語句修改為:語句修改為: printf (%.20d %n n,

39、 num) ; /注意,這里沒有壓注意,這里沒有壓num的地址入棧的地址入棧 o 則運行的結(jié)果為則運行的結(jié)果為: Before : num= 0 x61616161 Segmentation fault (core dumped) /執(zhí)行第二個執(zhí)行第二個printf()時發(fā)生段錯誤了時發(fā)生段錯誤了o 原因:原因:printf()將堆棧中將堆棧中main()函數(shù)的變量函數(shù)的變量num當當作了作了%n所對應(yīng)的參數(shù),因此會將所對應(yīng)的參數(shù),因此會將0 x14保存到地址保存到地址0 x61616161中去,而中去,而0 x61616161是不能訪問是不能訪問的地址,因此系統(tǒng)提示發(fā)生段錯誤。如果可以控制的

40、地址,因此系統(tǒng)提示發(fā)生段錯誤。如果可以控制num的內(nèi)容,那么就意味著可以修改任意地址(當然的內(nèi)容,那么就意味著可以修改任意地址(當然是允許寫入的地址)的內(nèi)容。是允許寫入的地址)的內(nèi)容。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)457.2.4 格式化串溢出格式化串溢出o 在實際應(yīng)用中,如果遇到脆弱的程序,將用在實際應(yīng)用中,如果遇到脆弱的程序,將用戶的輸入錯誤地放在格式化串的位置,就會戶的輸入錯誤地放在格式化串的位置,就會造成緩沖區(qū)溢出的攻擊。造成緩沖區(qū)溢出的攻擊。o 如果攻擊者可以事先構(gòu)造好可以攻擊的代碼如果攻擊者可以事先構(gòu)造好可以攻擊的代碼shellcode,如果可以將返回地址覆蓋成,如果可以將返回

41、地址覆蓋成shellcode的起始地址,當緩沖區(qū)溢出發(fā)的起始地址,當緩沖區(qū)溢出發(fā)生后,程序就會跳到精心設(shè)計好的生后,程序就會跳到精心設(shè)計好的shellcode處執(zhí)行,達到攻擊的目的。處執(zhí)行,達到攻擊的目的。 7.3 緩沖區(qū)溢出攻擊的過程緩沖區(qū)溢出攻擊的過程o 7.3.1 在程序的地址空間安排適當代碼在程序的地址空間安排適當代碼o 7.3.2 使控制流跳轉(zhuǎn)到攻擊代碼使控制流跳轉(zhuǎn)到攻擊代碼7.3 緩沖區(qū)溢出攻擊的過程緩沖區(qū)溢出攻擊的過程o 緩沖區(qū)溢出攻擊的目的在于擾亂某些工作在緩沖區(qū)溢出攻擊的目的在于擾亂某些工作在特殊權(quán)限狀態(tài)下的程序,使攻擊者取得程序特殊權(quán)限狀態(tài)下的程序,使攻擊者取得程序的控制權(quán)

42、,借機提高自己的權(quán)限,控制整個的控制權(quán),借機提高自己的權(quán)限,控制整個主機。主機。o 一般來說,攻擊者要實現(xiàn)緩沖區(qū)溢出攻擊,一般來說,攻擊者要實現(xiàn)緩沖區(qū)溢出攻擊,必須完成兩個任務(wù),一是必須完成兩個任務(wù),一是在程序的地址空間在程序的地址空間里安排適當?shù)拇a里安排適當?shù)拇a;二是通過適當?shù)某跏蓟欢峭ㄟ^適當?shù)某跏蓟拇嫫骱痛鎯ζ?,讓寄存器和存儲器,讓程序跳轉(zhuǎn)程序跳轉(zhuǎn)到安排好的地到安排好的地址空間執(zhí)行。址空間執(zhí)行。 7.3.1 在程序地址空間安排適當代碼在程序地址空間安排適當代碼o 這一步驟也可以簡稱為植入代碼的過程。這一步驟也可以簡稱為植入代碼的過程。 o 如果所需要的代碼在被攻擊程序中已經(jīng)存在如

43、果所需要的代碼在被攻擊程序中已經(jīng)存在了,那么攻擊者所要做的只是向代碼傳遞一了,那么攻擊者所要做的只是向代碼傳遞一些參數(shù),然后使程序跳轉(zhuǎn)到目標。些參數(shù),然后使程序跳轉(zhuǎn)到目標。n 比如攻擊代碼要求執(zhí)行“exec(/bin/sh)”,而在libc庫中存在這樣的代碼“exec(arg)”,其中,arg是一個指向字符串的指針參數(shù),那么,攻擊者只要把傳入的參數(shù)指針指向字符串“/bin/sh”,然后跳轉(zhuǎn)到libc庫中的相應(yīng)的指令序列就OK了。7.3.1 在程序地址空間安排適當代碼在程序地址空間安排適當代碼o 很多時候所需要的代碼并不能從被攻擊程序很多時候所需要的代碼并不能從被攻擊程序中找到,這就得用中找到,

44、這就得用“植入法植入法”來完成了。來完成了。n 構(gòu)造一個字符串,它包含的數(shù)據(jù)是可以在被攻擊程序的硬件平臺上運行的指令序列,在被攻擊程序的緩沖區(qū)如棧、堆或靜態(tài)數(shù)據(jù)區(qū)等地方找到足夠的空間存放這個字符串。然后再尋找適當?shù)臋C會使程序跳轉(zhuǎn)到其所安排的這個地址空間中。 7.3.2 將控制流轉(zhuǎn)移到攻擊代碼將控制流轉(zhuǎn)移到攻擊代碼o緩沖區(qū)溢出最關(guān)鍵的步驟就是尋求改變程序執(zhí)行緩沖區(qū)溢出最關(guān)鍵的步驟就是尋求改變程序執(zhí)行流程的方法,擾亂程序的正常執(zhí)行次序,使之跳流程的方法,擾亂程序的正常執(zhí)行次序,使之跳轉(zhuǎn)到攻擊代碼。原則上來講,攻擊時所針對的緩轉(zhuǎn)到攻擊代碼。原則上來講,攻擊時所針對的緩沖區(qū)溢出的程序空間可以為任意空間

45、,但因不同沖區(qū)溢出的程序空間可以為任意空間,但因不同地方程序空間的突破方式和內(nèi)存空間的定位差異地方程序空間的突破方式和內(nèi)存空間的定位差異,也就產(chǎn)生了多種轉(zhuǎn)移方式。,也就產(chǎn)生了多種轉(zhuǎn)移方式。nFunction Pointers(函數(shù)指針)nActivation Records(激活記錄)nLongjmp buffers(長跳轉(zhuǎn)緩沖區(qū))Function Pointers(函數(shù)指針)(函數(shù)指針)o 函數(shù)指針:函數(shù)指針:void (* foo) ()聲明了一個返聲明了一個返回值為回值為void 類型的函數(shù)指針變量類型的函數(shù)指針變量foo。o 函數(shù)指針可以用來定位任意地址空間,攻擊函數(shù)指針可以用來定位任

46、意地址空間,攻擊時只需要在任意空間里的函數(shù)指針鄰近處找時只需要在任意空間里的函數(shù)指針鄰近處找到一個能夠溢出的緩沖區(qū),然后用溢出來的到一個能夠溢出的緩沖區(qū),然后用溢出來的數(shù)據(jù)改變函數(shù)指針的值。當程序使用函數(shù)指數(shù)據(jù)改變函數(shù)指針的值。當程序使用函數(shù)指針調(diào)用函數(shù)時,程序的流程就會指向攻擊者針調(diào)用函數(shù)時,程序的流程就會指向攻擊者定義的指令序列。定義的指令序列。 用函數(shù)指針控制程序流程圖示用函數(shù)指針控制程序流程圖示2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)52Activation Records(激活記錄)(激活記錄)o 當一個函數(shù)調(diào)用發(fā)生時,堆棧中會留駐一個當一個函數(shù)調(diào)用發(fā)生時,堆棧中會留駐一個Activat

47、ion Record,它包含了函數(shù)結(jié)束,它包含了函數(shù)結(jié)束時返回的地址。溢出這一記錄,使這個返回時返回的地址。溢出這一記錄,使這個返回地址指向攻擊代碼,當函數(shù)調(diào)用結(jié)束時,程地址指向攻擊代碼,當函數(shù)調(diào)用結(jié)束時,程序就會跳轉(zhuǎn)到所設(shè)定的地址,而不是原來的序就會跳轉(zhuǎn)到所設(shè)定的地址,而不是原來的地址。地址。o 這樣的溢出方式比較常見。這樣的溢出方式比較常見。 用活動記錄控制程序流程圖示用活動記錄控制程序流程圖示2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)54Longjmp buffers(長跳轉(zhuǎn)緩沖區(qū))(長跳轉(zhuǎn)緩沖區(qū))o 在在C語言中包含了一個簡單的檢驗語言中包含了一個簡單的檢驗/恢復(fù)系統(tǒng),稱恢復(fù)系統(tǒng),稱為為se

48、tjmp/longjmp,在檢驗點設(shè)定,在檢驗點設(shè)定setjmp(buffer),用,用longjmp(buffer)來恢來恢復(fù)檢驗點。復(fù)檢驗點。o 和函數(shù)指針一樣,和函數(shù)指針一樣,longjmp(buffer)能夠跳轉(zhuǎn)到能夠跳轉(zhuǎn)到buffer中信息所指向的任何地方。如果攻擊者能中信息所指向的任何地方。如果攻擊者能夠修改夠修改buffer的內(nèi)容,使用的內(nèi)容,使用longjmp(buffer)就可以跳轉(zhuǎn)到攻擊代碼。就可以跳轉(zhuǎn)到攻擊代碼。o 使用這種方法,需要先找到一個可供溢出的緩沖區(qū)使用這種方法,需要先找到一個可供溢出的緩沖區(qū) 2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)56植入代碼和流程控制的綜合植入

49、代碼和流程控制的綜合o 常見的緩沖區(qū)溢出攻擊是溢出字符串綜合使用了常見的緩沖區(qū)溢出攻擊是溢出字符串綜合使用了代碼植入和代碼植入和Activation Records改寫技術(shù)。改寫技術(shù)。o 攻擊者定位在一個可供溢出的局部變量,然后向攻擊者定位在一個可供溢出的局部變量,然后向程序傳遞一個設(shè)計好的長字符串,在引發(fā)緩沖區(qū)程序傳遞一個設(shè)計好的長字符串,在引發(fā)緩沖區(qū)溢出改變溢出改變Activation Records的同時植入代碼。的同時植入代碼。o 即用一個長字符串完成代碼植入并覆蓋函數(shù)的返即用一個長字符串完成代碼植入并覆蓋函數(shù)的返回地址。回地址。o 示意圖見下面。示意圖見下面。植入代碼和流程控制的綜合

50、圖示植入代碼和流程控制的綜合圖示2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)577.4 代碼植入技術(shù)代碼植入技術(shù)o 7.4.1 shellcodeo 7.4.2 返回地址返回地址o 7.4.3 填充數(shù)據(jù)填充數(shù)據(jù)o 7.4.4 植入代碼的構(gòu)造類型植入代碼的構(gòu)造類型o 7.4.5 shellcode使用示例使用示例7.4 代碼植入技術(shù)代碼植入技術(shù)o 所植入的代碼一般由所植入的代碼一般由shellcode、返回地址、填、返回地址、填充數(shù)據(jù)這三種元素按照一定的結(jié)構(gòu)和構(gòu)造類型組成充數(shù)據(jù)這三種元素按照一定的結(jié)構(gòu)和構(gòu)造類型組成o 什么是什么是shellcoden是植入代碼的核心組成部分,是一段能完成特殊任務(wù)的自包含

51、的二進制代碼。n由于它最初是用來生成一個高權(quán)限的shell,因此而得名。雖然現(xiàn)在人們已經(jīng)遠遠不滿足于生成一個shell,但shellcode的“美名”一直延用至今。n攻擊者通過巧妙的編寫和設(shè)置,利用系統(tǒng)的漏洞將shellcode送入系統(tǒng)中使其得以執(zhí)行,從而獲取特殊權(quán)限的執(zhí)行環(huán)境,或給自己設(shè)立有特權(quán)的帳戶,取得目標機器的控制權(quán)。 7.4.1 shellcodeo 除了經(jīng)典的利用除了經(jīng)典的利用exec()系統(tǒng)調(diào)用執(zhí)行系統(tǒng)調(diào)用執(zhí)行/bin/sh獲獲取取shell之外,下表列出了之外,下表列出了Unix/Linux系統(tǒng)中的系統(tǒng)中的shellcode經(jīng)常用到的一些其它系統(tǒng)調(diào)用。經(jīng)常用到的一些其它系統(tǒng)調(diào)用

52、。 7.4.1 shellcodeo 在在linux中,為了獲得一個交互式中,為了獲得一個交互式shell,一般需要執(zhí),一般需要執(zhí)行代碼行代碼execve(“/bin/sh”, “/bin/sh”, NULL);o 對此代碼進行編譯后得到機器碼。對此代碼進行編譯后得到機器碼。 char shellcode = “xebx1fx5ex89x76x08x31xc0 x88x46x07x89x46x0cxb0 x0bx89xf3x8dx4ex08x8dx56x0cxcdx80 x31xdbx89xd8x40 xcdx80 xe8xdcxffxffxff/bin/sh”;o 注意:不同的操作系統(tǒng)、不同

53、的機器硬件產(chǎn)生系統(tǒng)調(diào)用注意:不同的操作系統(tǒng)、不同的機器硬件產(chǎn)生系統(tǒng)調(diào)用的方法和參數(shù)傳遞的方法也不盡相同。的方法和參數(shù)傳遞的方法也不盡相同。7.4.2 返回地址返回地址o 返回地址是指返回地址是指shellcode的入口地址。攻擊者如果希望目的入口地址。攻擊者如果希望目標程序改變其原來的執(zhí)行流程,轉(zhuǎn)而執(zhí)行標程序改變其原來的執(zhí)行流程,轉(zhuǎn)而執(zhí)行shellcode,則,則必須設(shè)法用必須設(shè)法用shellcode的入口地址覆蓋某個跳轉(zhuǎn)指令。的入口地址覆蓋某個跳轉(zhuǎn)指令。o 由于所植入的代碼是被復(fù)制到目標機器的緩沖區(qū)中,攻擊者由于所植入的代碼是被復(fù)制到目標機器的緩沖區(qū)中,攻擊者無法知道其進入到緩沖區(qū)后的確切地

54、址。不過,內(nèi)存的分配無法知道其進入到緩沖區(qū)后的確切地址。不過,內(nèi)存的分配是有規(guī)律的,如是有規(guī)律的,如Linux系統(tǒng),當用戶程序運行時,棧是從系統(tǒng),當用戶程序運行時,棧是從0 xbfffffff開始向內(nèi)存低端生長的。如果攻擊者想通過改寫開始向內(nèi)存低端生長的。如果攻擊者想通過改寫函數(shù)返回地址的方式使程序指令發(fā)生跳轉(zhuǎn),則程序指令跳轉(zhuǎn)函數(shù)返回地址的方式使程序指令發(fā)生跳轉(zhuǎn),則程序指令跳轉(zhuǎn)后的指向也應(yīng)該在后的指向也應(yīng)該在0 xbfffffff附近。附近。o 事實上,雖然不同的緩沖區(qū)溢出漏洞,其植入代碼的返回地事實上,雖然不同的緩沖區(qū)溢出漏洞,其植入代碼的返回地址都不同,但均處于某個較小的地址區(qū)間內(nèi)。另外,

55、為了提址都不同,但均處于某個較小的地址區(qū)間內(nèi)。另外,為了提高覆蓋函數(shù)返回地址的成功率,往往在植入代碼中安排一段高覆蓋函數(shù)返回地址的成功率,往往在植入代碼中安排一段由重復(fù)的返回地址組成的內(nèi)容。由重復(fù)的返回地址組成的內(nèi)容。 7.4.3 填充數(shù)據(jù)填充數(shù)據(jù)o 由于攻擊者不能準確地判斷由于攻擊者不能準確地判斷shellcode的入口的入口地址,因此為了提高地址,因此為了提高shellcode的命中率,往的命中率,往往在往在shellcode的前面安排一定數(shù)量的填充數(shù)的前面安排一定數(shù)量的填充數(shù)據(jù)。據(jù)。o 填充數(shù)據(jù)必須對植入代碼的功能完成沒有影響填充數(shù)據(jù)必須對植入代碼的功能完成沒有影響,這樣只要返回地址指向

56、填充數(shù)據(jù)中的任何一,這樣只要返回地址指向填充數(shù)據(jù)中的任何一個位置,均可以確保個位置,均可以確保shellcode順利執(zhí)行。順利執(zhí)行。o 填充數(shù)據(jù)還可以起到一個作用,就是當植入代填充數(shù)據(jù)還可以起到一個作用,就是當植入代碼的長度夠不著覆蓋目標如函數(shù)返回地址時,碼的長度夠不著覆蓋目標如函數(shù)返回地址時,可以通過增加填充數(shù)據(jù)的數(shù)量,使植入代碼的可以通過增加填充數(shù)據(jù)的數(shù)量,使植入代碼的返回地址能夠覆蓋函數(shù)返回地址。返回地址能夠覆蓋函數(shù)返回地址。7.4.3 填充數(shù)據(jù)填充數(shù)據(jù)o 對于對于Intel CPU來說,填充數(shù)據(jù)實質(zhì)上是一種單字節(jié)來說,填充數(shù)據(jù)實質(zhì)上是一種單字節(jié)指令,使用得最多的是空操作指令指令,使用得

57、最多的是空操作指令NOP,其值為,其值為0 x90,該指令什么也不做,僅跳過一個,該指令什么也不做,僅跳過一個CPU周期。周期。除此之外,還有其他的單字節(jié)指令可以作為填充數(shù)據(jù)使除此之外,還有其他的單字節(jié)指令可以作為填充數(shù)據(jù)使用,如調(diào)整計算結(jié)果的用,如調(diào)整計算結(jié)果的AAA和和AAS、操作標志位的、操作標志位的CLC和和CLD等。等。o 在植入代碼中,往往安排比較長甚至幾百上千的填充數(shù)在植入代碼中,往往安排比較長甚至幾百上千的填充數(shù)據(jù),而一個有效的指令長度實際最大也不過據(jù),而一個有效的指令長度實際最大也不過10字節(jié)左字節(jié)左右,因此,也可以根據(jù)這一特點來判斷是否發(fā)生了緩沖右,因此,也可以根據(jù)這一特點

58、來判斷是否發(fā)生了緩沖區(qū)溢出攻擊。區(qū)溢出攻擊。7.4.4 植入代碼的構(gòu)造類型植入代碼的構(gòu)造類型o 所植入的代碼是由黑客精心構(gòu)造的,而由于緩沖區(qū)溢出所植入的代碼是由黑客精心構(gòu)造的,而由于緩沖區(qū)溢出自身的特性,它的結(jié)構(gòu)和構(gòu)造類型有一定的特性。自身的特性,它的結(jié)構(gòu)和構(gòu)造類型有一定的特性。nNSR模式nRNS模式nAR模式o 其中,其中,nS代表shellcode,nR代表返回地址,nN代表填充數(shù)據(jù),nA表示環(huán)境變量。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)66NSR模式模式ret shellcode大量的nops 要溢出的緩沖區(qū) 構(gòu)造的數(shù)組返回地址NSR模式模式o 在在shellcode的后面安排一定數(shù)量

59、的返回地址,的后面安排一定數(shù)量的返回地址,在前面安排一定數(shù)量的填充數(shù)據(jù),這種結(jié)構(gòu)稱為在前面安排一定數(shù)量的填充數(shù)據(jù),這種結(jié)構(gòu)稱為NSR型,或前端同步型。型,或前端同步型。o 原理是:只要全部的原理是:只要全部的N和和S都處于緩沖區(qū)內(nèi),并且都處于緩沖區(qū)內(nèi),并且不覆蓋不覆蓋RET,而使,而使R正好覆蓋存放正好覆蓋存放RET的??臻g,的??臻g,這樣只要將這樣只要將R的值設(shè)置為指向的值設(shè)置為指向N區(qū)中任一位置,就區(qū)中任一位置,就必然可以成功地跳轉(zhuǎn)到我們預(yù)先編寫的必然可以成功地跳轉(zhuǎn)到我們預(yù)先編寫的shellcode處執(zhí)行。處執(zhí)行。2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)672022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)

60、68NSR模式模式o 這是一種經(jīng)典結(jié)構(gòu),適合于溢出緩沖區(qū)較大、足夠這是一種經(jīng)典結(jié)構(gòu),適合于溢出緩沖區(qū)較大、足夠放下我們的放下我們的shellcode的情況。的情況。o 這是一種非精確定位的方法,這是一種非精確定位的方法,N元素越多成功率越元素越多成功率越大,其缺點是緩沖區(qū)必須足夠大,否則大,其缺點是緩沖區(qū)必須足夠大,否則shellcode放不下或者放不下或者N元素數(shù)量太少都會造成失元素數(shù)量太少都會造成失敗。敗。RNS模式模式2022-4-11網(wǎng)絡(luò)入侵與防范技術(shù)69ret大量的返回地址 shellcode大量的nops 要溢出的緩沖區(qū) 構(gòu)造的數(shù)組RNS模式模式o 其原理是:只要把整個緩沖區(qū)全部用大量的其原理是:只要把整個緩沖區(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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論