版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第七章緩沖區(qū)溢出攻擊及防御技術(shù)NetworkSecurityTechnology2014AutumnSemesterNetworkSecurityTechnology網(wǎng)絡(luò)安全技術(shù)本章內(nèi)容安排7.1緩沖區(qū)溢出概述7.2緩沖區(qū)溢出原理
7.3緩沖區(qū)溢出的過(guò)程7.4代碼植入技術(shù)7.5實(shí)例:ida溢出漏洞攻擊7.6緩沖區(qū)溢出的防御7.7小結(jié)NetworkSecurityTechnology2014AutumnSemester27.1緩沖區(qū)溢出概述什么是緩沖區(qū)?它是包含相同數(shù)據(jù)類型實(shí)例的一個(gè)連續(xù)的計(jì)算機(jī)內(nèi)存塊。是程序運(yùn)行期間在內(nèi)存中分配的一個(gè)連續(xù)的區(qū)域,用于保存包括字符數(shù)組在內(nèi)的各種數(shù)據(jù)類型。所謂溢出,其實(shí)就是所填充的數(shù)據(jù)超出了原有的緩沖區(qū)邊界。兩者結(jié)合進(jìn)來(lái),所謂緩沖區(qū)溢出,就是向固定長(zhǎng)度的緩沖區(qū)中寫(xiě)入超出其預(yù)告分配長(zhǎng)度的內(nèi)容,造成緩沖區(qū)中數(shù)據(jù)的溢出,從而覆蓋了緩沖區(qū)周?chē)膬?nèi)存空間。黑客借此精心構(gòu)造填充數(shù)據(jù),導(dǎo)致原有流程的改變,讓程序轉(zhuǎn)而執(zhí)行特殊的代碼,最終獲取控制權(quán)。NetworkSecurityTechnology2014AutumnSemester37.1緩沖區(qū)溢出概述利用緩沖區(qū)溢出漏洞進(jìn)行攻擊最早可追溯到1988年Morris蠕蟲(chóng),它所利用的就是fingerd程序的緩沖區(qū)溢出漏洞。1989年,Spafford提交了一份分析報(bào)告,描述了VAX機(jī)上BSD版Unix的Fingerd的緩沖區(qū)溢出程序的技術(shù)細(xì)節(jié),引起了一部分安全人士對(duì)這個(gè)研究領(lǐng)域的重視。1996年,AlephOne發(fā)表了題為“Smashingthestackforfunandprofit”的文章后,首次詳細(xì)地介紹了Unix/Linux下棧溢出攻擊的原理、方法和步驟,揭示了緩沖區(qū)溢出攻擊中的技術(shù)細(xì)節(jié)。1999年w00w00安全小組的MattConover寫(xiě)了基于堆緩沖區(qū)溢出專著,對(duì)堆溢出的機(jī)理進(jìn)行了探索。NetworkSecurityTechnology2014AutumnSemester47.1緩沖區(qū)溢出概述Windows系統(tǒng)中緩沖區(qū)溢出的事例更是層出不窮。2001年“紅色代碼”蠕蟲(chóng)利用微軟IISWebServer中的緩沖區(qū)溢出漏洞使300000多臺(tái)計(jì)算機(jī)受到攻擊;2003年1月,Slammer蠕蟲(chóng)爆發(fā),利用的是微軟SQLServer2000中的缺陷;2004年5月爆發(fā)的“振蕩波”利用了Windows系統(tǒng)的活動(dòng)目錄服務(wù)緩沖區(qū)溢出漏洞;2005年8月利用Windows即插即用緩沖區(qū)溢出漏洞的“狙擊波”被稱為歷史上最快利用微軟漏洞進(jìn)行攻擊的惡意代碼。2008年底至2009年的Conficker蠕蟲(chóng)利用的是Windows處理遠(yuǎn)程RPC請(qǐng)求時(shí)的漏洞(MS08-067)。NetworkSecurityTechnology2014AutumnSemester57.1緩沖區(qū)溢出概述目前,利用緩沖區(qū)溢出漏洞進(jìn)行的攻擊已經(jīng)占所有系統(tǒng)攻擊總數(shù)的80%以上。緩沖區(qū)溢出攻擊之所以日益普遍,其原因在于各種操作系統(tǒng)和應(yīng)用軟件上存在的緩沖區(qū)溢出問(wèn)題數(shù)不勝數(shù),而其帶來(lái)的影響不容小覷。對(duì)緩沖區(qū)溢出漏洞攻擊,可以導(dǎo)致程序運(yùn)行失敗、系統(tǒng)崩潰以及重新啟動(dòng)等后果。更為嚴(yán)重的是,可以利用緩沖區(qū)溢出執(zhí)行非授權(quán)指令,甚至取得系統(tǒng)特權(quán),進(jìn)而進(jìn)行各種非法操作。如何防止和檢測(cè)出利用緩沖區(qū)溢出漏洞進(jìn)行的攻擊,就成為防御網(wǎng)絡(luò)入侵以及入侵檢測(cè)的重點(diǎn)之一。NetworkSecurityTechnology2014AutumnSemester67.1緩沖區(qū)溢出概述與其他的攻擊類型相比,緩沖區(qū)溢出攻擊不需要太多的先決條件殺傷力很強(qiáng)技術(shù)性強(qiáng)緩沖區(qū)溢出比其他一些黑客攻擊手段更具有破壞力和隱蔽性。這也是利用緩沖區(qū)溢出漏洞進(jìn)行攻擊日益普遍的原因。NetworkSecurityTechnology2014AutumnSemester77.1緩沖區(qū)溢出概述破壞性:它極容易使服務(wù)程序停止運(yùn)行,服務(wù)器死機(jī)甚至刪除服務(wù)器上的數(shù)據(jù)。隱蔽性:首先,漏洞被發(fā)現(xiàn)之前,程序員一般是不會(huì)意識(shí)到自己的程序存在漏洞的(事實(shí)上,漏洞的發(fā)現(xiàn)者往往并非編寫(xiě)者),于是疏于監(jiān)測(cè);其次,被植入的攻擊代碼一般都很短,執(zhí)行時(shí)間也非常短,很難在執(zhí)行過(guò)程中被發(fā)現(xiàn),而且其執(zhí)行并不一定會(huì)使系統(tǒng)報(bào)告錯(cuò)誤,并可能不影響正常程序的運(yùn)行;NetworkSecurityTechnology2014AutumnSemester87.1緩沖區(qū)溢出概述隱蔽性:第三,由于漏洞存在于防火墻內(nèi)部的主機(jī)上,攻擊者可以在防火墻內(nèi)部堂而皇之地取得本來(lái)不被允許或沒(méi)有權(quán)限的控制權(quán);第四,攻擊的隨機(jī)性和不可預(yù)測(cè)性使得防御變得異常艱難,沒(méi)有攻擊時(shí),被攻擊程序本身并不會(huì)有什么變化,也不會(huì)存在任何異常的表現(xiàn);最后,緩沖區(qū)溢出漏洞的普遍存在,針對(duì)它的攻擊讓人防不勝防(各種補(bǔ)丁程序也可能存在著這種漏洞)。NetworkSecurityTechnology2014AutumnSemester97.2緩沖區(qū)溢出原理7.2.1棧溢出7.2.2堆溢出7.2.3BSS溢出7.2.4格式化串溢出NetworkSecurityTechnology2014AutumnSemester107.2緩沖區(qū)溢出原理當(dāng)程序運(yùn)行時(shí),計(jì)算機(jī)會(huì)在內(nèi)存區(qū)域中開(kāi)辟一段連續(xù)的內(nèi)存塊,包括代碼段、數(shù)據(jù)段和堆棧段三部分。NetworkSecurityTechnology2014AutumnSemester117.2緩沖區(qū)溢出原理程序在內(nèi)存中的存放形式NetworkSecurityTechnology2014AutumnSemester12NetworkSecurityTechnology2014AutumnSemester137.2緩沖區(qū)溢出原理代碼段(.text),也稱文本段(TextSegment),存放著程序的機(jī)器碼和只讀數(shù)據(jù),可執(zhí)行指令就是從這里取得的。如果可能,系統(tǒng)會(huì)安排好相同程序的多個(gè)運(yùn)行實(shí)體共享這些實(shí)例代碼。這個(gè)段在內(nèi)存中一般被標(biāo)記為只讀,任何對(duì)該區(qū)的寫(xiě)操作都會(huì)導(dǎo)致段錯(cuò)誤(SegmentationFault)。數(shù)據(jù)段,包括已初始化的數(shù)據(jù)段(.data)和未初始化的數(shù)據(jù)段(.bss),前者用來(lái)存放保存全局的和靜態(tài)的已初始化變量,后者用來(lái)保存全局的和靜態(tài)的未初始化變量。數(shù)據(jù)段在編譯時(shí)分配。NetworkSecurityTechnology2014AutumnSemester147.2緩沖區(qū)溢出原理堆棧段分為堆和棧堆(Heap):位于BSS內(nèi)存段的上邊,用來(lái)存儲(chǔ)程序運(yùn)行時(shí)分配的變量。堆的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。其分配由malloc()、new()等這類實(shí)時(shí)內(nèi)存分配函數(shù)來(lái)實(shí)現(xiàn)。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)。堆的內(nèi)存釋放由應(yīng)用程序去控制,通常一個(gè)new()就要對(duì)應(yīng)一個(gè)delete(),如果程序員沒(méi)有釋放掉,那么在程序結(jié)束后操作系統(tǒng)會(huì)自動(dòng)回收。NetworkSecurityTechnology2014AutumnSemester157.2緩沖區(qū)溢出原理?xiàng)#⊿tack)是一種用來(lái)存儲(chǔ)函數(shù)調(diào)用時(shí)的臨時(shí)信息的結(jié)構(gòu),如函數(shù)調(diào)用所傳遞的參數(shù)、函數(shù)的返回地址、函數(shù)的局部變量等。在程序運(yùn)行時(shí)由編譯器在需要的時(shí)候分配,在不需要的時(shí)候自動(dòng)清除。棧的特性:最后一個(gè)放入棧中的物體總是被最先拿出來(lái),這個(gè)特性通常稱為先進(jìn)后出(FILO)隊(duì)列。棧的基本操作:PUSH操作:向棧中添加數(shù)據(jù),稱為壓棧,數(shù)據(jù)將放置在棧頂;POP操作:POP操作相反,在棧頂部移去一個(gè)元素,并將棧的大小減一,稱為彈棧。NetworkSecurityTechnology2014AutumnSemester16堆和棧的區(qū)別分配和管理方式不同堆是動(dòng)態(tài)分配的,其空間的分配和釋放都由程序員控制。棧由編譯器自動(dòng)管理。棧有兩種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配由編譯器完成,比如局部變量的分配。動(dòng)態(tài)分配由alloca()函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,它的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無(wú)須手工控制。產(chǎn)生碎片不同對(duì)堆來(lái)說(shuō),頻繁的new/delete或者malloc/free勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),造成大量的碎片,使程序效率降低。對(duì)棧而言,則不存在碎片問(wèn)題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,永遠(yuǎn)不可能有一個(gè)內(nèi)存塊從棧中間彈出。生長(zhǎng)方向不同堆是向著內(nèi)存地址增加的方向增長(zhǎng)的,從內(nèi)存的低地址向高地址方向增長(zhǎng)。棧的生長(zhǎng)方向與之相反,是向著內(nèi)存地址減小的方向增長(zhǎng),由內(nèi)存的高地址向低地址方向增長(zhǎng)。NetworkSecurityTechnology2014AutumnSemester17NetworkSecurityTechnology2014AutumnSemester187.2緩沖區(qū)溢出原理在這里,我們假設(shè)現(xiàn)在有一個(gè)程序,它的函數(shù)調(diào)用順序如下。main()->;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。其詳細(xì)結(jié)構(gòu)圖如下頁(yè)圖所示。NetworkSecurityTechnology2014AutumnSemester19NetworkSecurityTechnology2014AutumnSemester20程序在內(nèi)存中的影像隨著函數(shù)調(diào)用層數(shù)的增加,函數(shù)棧幀是一塊塊地向內(nèi)存低地址方向延伸的。隨著進(jìn)程中函數(shù)調(diào)用層數(shù)的減少,即各函數(shù)調(diào)用的返回,棧幀會(huì)一塊塊地被遺棄而向內(nèi)存的高址方向回縮。各函數(shù)的棧幀大小隨著函數(shù)的性質(zhì)的不同而不等,由函數(shù)的局部變量的數(shù)目決定。在緩沖區(qū)溢出中,我們主要關(guān)注數(shù)據(jù)區(qū)和堆棧區(qū)。NetworkSecurityTechnology2014AutumnSemester21程序所使用的棧在使用棧時(shí),引用棧幀需要借助兩個(gè)寄存器。一個(gè)是SP(ESP),即棧頂指針,它隨著數(shù)據(jù)入棧出棧而發(fā)生變化。另一個(gè)是BP(EBP),即基地址指針,它用于標(biāo)識(shí)棧中一個(gè)相對(duì)穩(wěn)定的位置,通過(guò)BP,再加上偏移地址,可以方便地引用函數(shù)參數(shù)以及局部變量。NetworkSecurityTechnology2014AutumnSemester22程序所使用的棧函數(shù)被調(diào)用的時(shí)候,棧中的壓入情況如下:Func函數(shù)中的局部變量調(diào)用Func函數(shù)前的EBP退出Func函數(shù)后的返回地址傳遞給Func的實(shí)參內(nèi)存低地址內(nèi)存高地址最先壓入棧最后壓入棧NetworkSecurityTechnology2014AutumnSemester23程序所使用的棧在局部變量的下面,是前一個(gè)調(diào)用函數(shù)的EBP,接下來(lái)就是返回地址。如果局部變量發(fā)生溢出,很有可能會(huì)覆蓋掉EBP甚至RET(返回地址),這就是緩沖區(qū)溢出攻擊的“奧秘”所在。NetworkSecurityTechnology2014AutumnSemester247.2緩沖區(qū)溢出原理如果在堆棧中壓入的數(shù)據(jù)超過(guò)預(yù)先給堆棧分配的容量時(shí),就會(huì)出現(xiàn)堆棧溢出,從而使得程序運(yùn)行失??;如果發(fā)生溢出的是大型程序還有可能會(huì)導(dǎo)致系統(tǒng)崩潰。NetworkSecurityTechnology2014AutumnSemester257.2.1棧溢出程序中發(fā)生函數(shù)調(diào)用時(shí),計(jì)算機(jī)做如下操作:首先把指令寄存器EIP(它指向當(dāng)前CPU將要運(yùn)行的下一條指令的地址)中的內(nèi)容壓入棧,作為程序的返回地址(下文中用RET表示);之后放入棧的是基址寄存器EBP,它指向當(dāng)前函數(shù)棧幀(stackframe)的底部;然后把當(dāng)前的棧指針ESP拷貝到EBP,作為新的基地址,最后為本地變量的動(dòng)態(tài)存儲(chǔ)分配留出一定空間,并把ESP減去適當(dāng)?shù)臄?shù)值。NetworkSecurityTechnology2014AutumnSemester267.2.1棧溢出實(shí)例我們來(lái)看一段簡(jiǎn)單程序的執(zhí)行過(guò)程中對(duì)棧的操作和溢出的產(chǎn)生過(guò)程。
#include<stdio.h> intmain(){ charname[16]; gets(name); for(inti=0;i<16&&name[i];i++) printf(“%c”,name[i]); }NetworkSecurityTechnology2014AutumnSemester277.2.1棧溢出實(shí)例編譯上述代碼,輸入helloworld!結(jié)果會(huì)輸出helloworld!在調(diào)用main()函數(shù)時(shí),程序?qū)5牟僮魇沁@樣的:先在棧底壓入返回地址接著將棧指針EBP入棧,并把EBP修改為現(xiàn)在的ESP之后ESP減16,即向上增長(zhǎng)16個(gè)字節(jié),用來(lái)存放name[]數(shù)組NetworkSecurityTechnology2014AutumnSemester287.2.1棧溢出實(shí)例現(xiàn)在棧的布局如圖所示。NetworkSecurityTechnology2014AutumnSemester297.2.1棧溢出實(shí)例執(zhí)行完gets(name)之后,棧中的內(nèi)容如下圖所示NetworkSecurityTechnology2014AutumnSemester307.2.1棧溢出實(shí)例接著執(zhí)行for循環(huán),逐個(gè)打印name[]數(shù)組中的字符,直到碰到0x00字符最后,從main返回,將ESP增加16以回收name[]數(shù)組占用的空間,此時(shí)ESP指向先前保存的EBP值。程序?qū)⑦@個(gè)值彈出并賦給EBP,使EBP重新指向main()函數(shù)調(diào)用者的棧的底部。然后再?gòu)棾霈F(xiàn)在位于棧頂?shù)姆祷氐刂稲ET,賦給EIP,CPU繼續(xù)執(zhí)行EIP所指向的命令。說(shuō)明1:EIP寄存器的內(nèi)容表示將要執(zhí)行的下一條指令地址。說(shuō)明2:當(dāng)調(diào)用函數(shù)時(shí),Call指令會(huì)將返回地址(Call指令下一條指令地址)壓入棧Ret指令會(huì)把壓棧的返回地址彈給EIPNetworkSecurityTechnology2014AutumnSemester317.2.1棧溢出實(shí)例如果輸入的字符串長(zhǎng)度超過(guò)16個(gè)字節(jié),例如輸入:helloworld!AAAAAAAA……,則當(dāng)執(zhí)行完gets(name)之后,棧的情況如圖所示。NetworkSecurityTechnology2014AutumnSemester327.2.1棧溢出實(shí)例由于輸入的字符串太長(zhǎng),name[]數(shù)組容納不下,只好向棧的底部方向繼續(xù)寫(xiě)‘A’。這些‘A’覆蓋了堆棧的老的元素,從上頁(yè)圖可以看出,EBP,Ret都已經(jīng)被‘A’覆蓋了。從main返回時(shí),就必然會(huì)把‘AAAA’的ASCII碼——0x41414141視作返回地址,CPU會(huì)試圖執(zhí)行0x41414141處的指令,結(jié)果出現(xiàn)難以預(yù)料的后果,這樣就產(chǎn)生了一次堆棧溢出。在Windows
XP下用VC6.0運(yùn)行程序,結(jié)果如下頁(yè)圖所示。NetworkSecurityTechnology2014AutumnSemester33NetworkSecurityTechnology2014AutumnSemester347.2.2堆溢出當(dāng)我們需要較大的緩沖區(qū)或在寫(xiě)代碼時(shí)不知道包含在緩沖區(qū)中對(duì)象的大小,常常要使用堆。堆溢出的工作方式幾乎與棧溢出的工作方式完全相同,唯一不同的是,堆沒(méi)有壓棧和入棧操作,而是分配和回收內(nèi)存。C語(yǔ)言中使用malloc()和free()函數(shù)實(shí)現(xiàn)內(nèi)存的動(dòng)態(tài)分配和回收,C++語(yǔ)言使用new()和delete()函數(shù)來(lái)實(shí)現(xiàn)相同的功能。NetworkSecurityTechnology2014AutumnSemester357.2.2堆溢出實(shí)例#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#defineBUFFER-SIZE16#defineOVERLAYSIZE8/*我們將覆蓋buf2的前OVERLAYSIZE個(gè)字節(jié)*/intmain(){ u-longdiff; char*buf1=(char*)malloc(BUFFER-SIZE); char*buf2=(char*)malloc(BUFFER-SIZE); diff=(u-long)buf2-(u-long)buf1; printf(″buf1=%p,buf2=%p,diff=0x%x(%d)bytes\n″,buf1,buf2,diff,diff); /*將buf2用’a’填充*/ memset(buf2,’a’,BUFFER-SIZE-1),buf2[BUFFER-SIZE-1]=’\0’; printf(″beforeoverflow:buf2=%s\n″,buf2); /*用diff+OVERLAYSIZE個(gè)’b’填充buf1*/ memset(buf1,’b’,(u-int)(diff+OVERLAYSIZE)); printf(″afteroverflow:buf2=%s\n″,buf2); return0;}NetworkSecurityTechnology2014AutumnSemester367.2.2堆溢出實(shí)例運(yùn)行結(jié)果:/users/test41%./heap1buf1=0x8049858,buf2=0x8049870,diff=0x18(24)bytesbeforeoverflow:buf2=aaaaaaaaaaaaaaaafteroverflow:buf2=bbbbbbbbaaaaaaa我們看到,buf2的前八個(gè)字節(jié)被覆蓋了,這是因?yàn)橥鵥uf1中填寫(xiě)的數(shù)據(jù)超出了它的邊界進(jìn)入了buf2的范圍。由于buf2的數(shù)據(jù)仍然在有效的Heap區(qū)內(nèi),程序仍然可以正常結(jié)束。
NetworkSecurityTechnology2014AutumnSemester377.2.2堆溢出實(shí)例雖然buf1和buf2是相繼分配的,但它們并不是緊挨著的,而是有八個(gè)字節(jié)的間距。這是因?yàn)椋褂胢alloc()動(dòng)態(tài)分配內(nèi)存時(shí),系統(tǒng)向用戶返回一個(gè)內(nèi)存地址,實(shí)際上在這個(gè)地址前面通常還有8字節(jié)的內(nèi)部結(jié)構(gòu),用來(lái)記錄分配的塊長(zhǎng)度、上一個(gè)堆的字節(jié)數(shù)以及一些標(biāo)志等。這個(gè)間距可能隨不同的系統(tǒng)環(huán)境而不同。buf1溢出后,buf2的前8字節(jié)也被改寫(xiě)為bbbbbbbb,buf2內(nèi)部的部分內(nèi)容也被修改為b。NetworkSecurityTechnology2014AutumnSemester387.2.2堆溢出實(shí)例示意圖:NetworkSecurityTechnology2014AutumnSemester397.2.2堆溢出堆溢出不如棧溢出流行,原因在于比棧溢出難度更大需要結(jié)合其他的技術(shù)對(duì)于內(nèi)存中變量的組織方式有一定的要求NetworkSecurityTechnology2014AutumnSemester407.2.3BSS溢出.bss段存放全局和靜態(tài)的未初始化變量,其分配比較簡(jiǎn)單,變量與變量之間是連續(xù)存放的,沒(méi)有保留空間。下面這樣定義的兩個(gè)字符數(shù)組即是位于BSS段:staticcharbuf1[16],buf2[16];如果事先向buf2中寫(xiě)入16個(gè)字符A,之后再往buf1中寫(xiě)入24個(gè)B,由于變量之間是連續(xù)存放的,靜態(tài)字符數(shù)組buf1溢出后,就會(huì)覆蓋其相鄰區(qū)域字符數(shù)組buf2的值。利用這一點(diǎn),攻擊者可以通過(guò)改寫(xiě)B(tài)SS中的指針或函數(shù)指針等方式,改變程序原先的執(zhí)行流程,使指針跳轉(zhuǎn)到特定的內(nèi)存地址并執(zhí)行指定操作。NetworkSecurityTechnology2014AutumnSemester417.2.4格式化串溢出與前面三種溢出不同的是,這種溢出漏洞是利用了編程語(yǔ)言自身存在的安全問(wèn)題。格式化串溢出源自*printf()類函數(shù)的參數(shù)格式問(wèn)題(如printf、fprintf、sprintf等)。intprintf(constchar*format,arg1,arg2,…);它們將根據(jù)format的內(nèi)容(%s,%d,%p,%x,%n,…),將數(shù)據(jù)格式化后輸出。問(wèn)題在于:*printf()函數(shù)并不能確定數(shù)據(jù)參數(shù)arg1,arg2,…究竟在什么地方結(jié)束,即函數(shù)本身不知道參數(shù)的個(gè)數(shù),而只會(huì)根據(jù)format中打印格式的數(shù)目依次打印堆棧中參數(shù)format后面地址的內(nèi)容。NetworkSecurityTechnology2014AutumnSemester427.2.4格式化串溢出實(shí)例/*程序說(shuō)明: %#x:按16進(jìn)制輸出,并在前面加上0x %.20d:按10進(jìn)制輸出,輸出20位,并在前面補(bǔ)0 %n:將顯示內(nèi)容的長(zhǎng)度輸出到一個(gè)變量中去*/#include<stdio.h>main(){ intnum=0x61616161; printf(″Before:num=%#x\n″,num); printf(″%.20d%n\n″,num,&num); printf(″After:num=%#x\n″,num);}NetworkSecurityTechnology2014AutumnSemester437.2.4格式化串溢出實(shí)例當(dāng)程序執(zhí)行第二個(gè)printf語(yǔ)句時(shí),參數(shù)壓棧之后的內(nèi)存布局如下:NetworkSecurityTechnology2014AutumnSemester447.2.4格式化串溢出實(shí)例根據(jù)C函數(shù)調(diào)用約定,參數(shù)從右向左依次壓棧,所以參數(shù)&num比參數(shù)num先壓入棧中。也就是說(shuō),程序中將&num(num的地址)壓入棧作為printf()的第三個(gè)參數(shù),而使用打印格式%n會(huì)將打印總長(zhǎng)度保存到對(duì)應(yīng)參數(shù)(&num)的地址中去,從而改變了num的值。整個(gè)程序的輸出結(jié)果為:
Before:num=0x6161616100000000001633771873After:num=0x14變量num的值已經(jīng)變成了0x14(20)。NetworkSecurityTechnology2014AutumnSemester457.2.4格式化串溢出實(shí)例如果將第二個(gè)printf語(yǔ)句修改為:printf(″%.20d%n\n″,num);//注意,這里沒(méi)有壓num的地址入棧則運(yùn)行的結(jié)果為:Before:num=0x61616161Segmentationfault(coredumped)//執(zhí)行第二個(gè)printf()時(shí)發(fā)生段錯(cuò)誤了原因:printf()將堆棧中main()函數(shù)的變量num當(dāng)作了%n所對(duì)應(yīng)的參數(shù),因此會(huì)將0x14保存到地址0x61616161中去,而0x61616161是不能訪問(wèn)的地址,因此系統(tǒng)提示發(fā)生段錯(cuò)誤。如果可以控制num的內(nèi)容,那么就意味著可以修改任意地址(當(dāng)然是允許寫(xiě)入的地址)的內(nèi)容。NetworkSecurityTechnology2014AutumnSemester467.2.4格式化串溢出在實(shí)際應(yīng)用中,如果遇到脆弱的程序,將用戶的輸入錯(cuò)誤地放在格式化串的位置,就會(huì)造成緩沖區(qū)溢出的攻擊。如果攻擊者可以事先構(gòu)造好可以攻擊的代碼shellcode,如果可以將返回地址覆蓋成shellcode的起始地址,當(dāng)緩沖區(qū)溢出發(fā)生后,程序就會(huì)跳到精心設(shè)計(jì)好的shellcode處執(zhí)行,達(dá)到攻擊的目的。NetworkSecurityTechnology2014AutumnSemester477.3緩沖區(qū)溢出攻擊的過(guò)程7.3.1在程序的地址空間安排適當(dāng)代碼7.3.2使控制流跳轉(zhuǎn)到攻擊代碼NetworkSecurityTechnology2014AutumnSemester487.3緩沖區(qū)溢出攻擊的過(guò)程緩沖區(qū)溢出攻擊的目的在于擾亂某些工作在特殊權(quán)限狀態(tài)下的程序,使攻擊者取得程序的控制權(quán),借機(jī)提高自己的權(quán)限,控制整個(gè)主機(jī)。一般來(lái)說(shuō),攻擊者要實(shí)現(xiàn)緩沖區(qū)溢出攻擊,必須完成兩個(gè)任務(wù),一是在程序的地址空間里安排適當(dāng)?shù)拇a;二是通過(guò)適當(dāng)?shù)某跏蓟拇嫫骱痛鎯?chǔ)器,讓程序跳轉(zhuǎn)到安排好的地址空間執(zhí)行。NetworkSecurityTechnology2014AutumnSemester497.3.1在程序地址空間安排適當(dāng)代碼這一步驟也可以簡(jiǎn)稱為植入代碼的過(guò)程。如果所需要的代碼在被攻擊程序中已經(jīng)存在了,那么攻擊者所要做的只是向代碼傳遞一些參數(shù),然后使程序跳轉(zhuǎn)到目標(biāo)。比如攻擊代碼要求執(zhí)行“exec(‘/bin/sh’)”,而在libc庫(kù)中存在這樣的代碼“exec(arg)”,其中,arg是一個(gè)指向字符串的指針參數(shù),那么,攻擊者只要把傳入的參數(shù)指針指向字符串“/bin/sh”,然后跳轉(zhuǎn)到libc庫(kù)中的相應(yīng)的指令序列就OK了。NetworkSecurityTechnology2014AutumnSemester507.3.1在程序地址空間安排適當(dāng)代碼很多時(shí)候所需要的代碼并不能從被攻擊程序中找到,這就得用“植入法”來(lái)完成了。構(gòu)造一個(gè)字符串,它包含的數(shù)據(jù)是可以在被攻擊程序的硬件平臺(tái)上運(yùn)行的指令序列,在被攻擊程序的緩沖區(qū)如棧、堆或靜態(tài)數(shù)據(jù)區(qū)等地方找到足夠的空間存放這個(gè)字符串。然后再尋找適當(dāng)?shù)臋C(jī)會(huì)使程序跳轉(zhuǎn)到其所安排的這個(gè)地址空間中。NetworkSecurityTechnology2014AutumnSemester517.3.2將控制流轉(zhuǎn)移到攻擊代碼緩沖區(qū)溢出最關(guān)鍵的步驟就是尋求改變程序執(zhí)行流程的方法,擾亂程序的正常執(zhí)行次序,使之跳轉(zhuǎn)到攻擊代碼。原則上來(lái)講,攻擊時(shí)所針對(duì)的緩沖區(qū)溢出的程序空間可以為任意空間,但因不同地方程序空間的突破方式和內(nèi)存空間的定位差異,也就產(chǎn)生了多種轉(zhuǎn)移方式。FunctionPointers(函數(shù)指針)ActivationRecords(激活記錄)Longjmpbuffers(長(zhǎng)跳轉(zhuǎn)緩沖區(qū))NetworkSecurityTechnology2014AutumnSemester52FunctionPointers(函數(shù)指針)函數(shù)指針:void(*foo)()聲明了一個(gè)返回值為void類型的函數(shù)指針變量foo。函數(shù)指針可以用來(lái)定位任意地址空間,攻擊時(shí)只需要在任意空間里的函數(shù)指針鄰近處找到一個(gè)能夠溢出的緩沖區(qū),然后用溢出來(lái)的數(shù)據(jù)改變函數(shù)指針的值。當(dāng)程序使用函數(shù)指針調(diào)用函數(shù)時(shí),程序的流程就會(huì)指向攻擊者定義的指令序列。NetworkSecurityTechnology2014AutumnSemester53用函數(shù)指針控制程序流程圖示NetworkSecurityTechnology2014AutumnSemester54ActivationRecords(激活記錄)當(dāng)一個(gè)函數(shù)調(diào)用發(fā)生時(shí),堆棧中會(huì)留駐一個(gè)ActivationRecord,它包含了函數(shù)結(jié)束時(shí)返回的地址。溢出這一記錄,使這個(gè)返回地址指向攻擊代碼,當(dāng)函數(shù)調(diào)用結(jié)束時(shí),程序就會(huì)跳轉(zhuǎn)到所設(shè)定的地址,而不是原來(lái)的地址。這樣的溢出方式比較常見(jiàn)。NetworkSecurityTechnology2014AutumnSemester55用活動(dòng)記錄控制程序流程圖示NetworkSecurityTechnology2014AutumnSemester56Longjmpbuffers(長(zhǎng)跳轉(zhuǎn)緩沖區(qū))在C語(yǔ)言中包含了一個(gè)簡(jiǎn)單的檢驗(yàn)/恢復(fù)系統(tǒng),稱為setjmp/longjmp,在檢驗(yàn)點(diǎn)設(shè)定setjmp(buffer),用longjmp(buffer)來(lái)恢復(fù)檢驗(yàn)點(diǎn)。和函數(shù)指針一樣,longjmp(buffer)能夠跳轉(zhuǎn)到buffer中信息所指向的任何地方。如果攻擊者能夠修改buffer的內(nèi)容,使用longjmp(buffer)就可以跳轉(zhuǎn)到攻擊代碼。使用這種方法,需要先找到一個(gè)可供溢出的緩沖區(qū)NetworkSecurityTechnology2014AutumnSemester57植入代碼和流程控制的綜合常見(jiàn)的緩沖區(qū)溢出攻擊是溢出字符串綜合使用了代碼植入和ActivationRecords改寫(xiě)技術(shù)。攻擊者定位在一個(gè)可供溢出的局部變量,然后向程序傳遞一個(gè)設(shè)計(jì)好的長(zhǎng)字符串,在引發(fā)緩沖區(qū)溢出改變ActivationRecords的同時(shí)植入代碼。即用一個(gè)長(zhǎng)字符串完成代碼植入并覆蓋函數(shù)的返回地址。示意圖見(jiàn)下面。NetworkSecurityTechnology2014AutumnSemester58植入代碼和流程控制的綜合圖示NetworkSecurityTechnology2014AutumnSemester597.4代碼植入技術(shù)7.4.1shellcode7.4.2返回地址7.4.3填充數(shù)據(jù)7.4.4植入代碼的構(gòu)造類型7.4.5shellcode使用示例NetworkSecurityTechnology2014AutumnSemester607.4代碼植入技術(shù)所植入的代碼一般由shellcode、返回地址、填充數(shù)據(jù)這三種元素按照一定的結(jié)構(gòu)和構(gòu)造類型組成什么是shellcode是植入代碼的核心組成部分,是一段能完成特殊任務(wù)的自包含的二進(jìn)制代碼。由于它最初是用來(lái)生成一個(gè)高權(quán)限的shell,因此而得名。雖然現(xiàn)在人們已經(jīng)遠(yuǎn)遠(yuǎn)不滿足于生成一個(gè)shell,但shellcode的“美名”一直延用至今。攻擊者通過(guò)巧妙的編寫(xiě)和設(shè)置,利用系統(tǒng)的漏洞將shellcode送入系統(tǒng)中使其得以執(zhí)行,從而獲取特殊權(quán)限的執(zhí)行環(huán)境,或給自己設(shè)立有特權(quán)的帳戶,取得目標(biāo)機(jī)器的控制權(quán)。NetworkSecurityTechnology2014AutumnSemester617.4.1shellcode除了經(jīng)典的利用exec()系統(tǒng)調(diào)用執(zhí)行/bin/sh獲取shell之外,下表列出了Unix/Linux系統(tǒng)中的shellcode經(jīng)常用到的一些其它系統(tǒng)調(diào)用。NetworkSecurityTechnology2014AutumnSemester627.4.1shellcode在linux中,為了獲得一個(gè)交互式shell,一般需要執(zhí)行代碼execve(“/bin/sh”,“/bin/sh”,NULL);對(duì)此代碼進(jìn)行編譯后得到機(jī)器碼。charshellcode[]=“\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh”;注意:不同的操作系統(tǒng)、不同的機(jī)器硬件產(chǎn)生系統(tǒng)調(diào)用的方法和參數(shù)傳遞的方法也不盡相同。NetworkSecurityTechnology2014AutumnSemester637.4.2返回地址返回地址是指shellcode的入口地址。攻擊者如果希望目標(biāo)程序改變其原來(lái)的執(zhí)行流程,轉(zhuǎn)而執(zhí)行shellcode,則必須設(shè)法用shellcode的入口地址覆蓋某個(gè)跳轉(zhuǎn)指令。由于所植入的代碼是被復(fù)制到目標(biāo)機(jī)器的緩沖區(qū)中,攻擊者無(wú)法知道其進(jìn)入到緩沖區(qū)后的確切地址。不過(guò),內(nèi)存的分配是有規(guī)律的,如Linux系統(tǒng),當(dāng)用戶程序運(yùn)行時(shí),棧是從0xbfffffff開(kāi)始向內(nèi)存低端生長(zhǎng)的。如果攻擊者想通過(guò)改寫(xiě)函數(shù)返回地址的方式使程序指令發(fā)生跳轉(zhuǎn),則程序指令跳轉(zhuǎn)后的指向也應(yīng)該在0xbfffffff附近。事實(shí)上,雖然不同的緩沖區(qū)溢出漏洞,其植入代碼的返回地址都不同,但均處于某個(gè)較小的地址區(qū)間內(nèi)。另外,為了提高覆蓋函數(shù)返回地址的成功率,往往在植入代碼中安排一段由重復(fù)的返回地址組成的內(nèi)容。NetworkSecurityTechnology2014AutumnSemester647.4.3填充數(shù)據(jù)由于攻擊者不能準(zhǔn)確地判斷shellcode的入口地址,因此為了提高shellcode的命中率,往往在shellcode的前面安排一定數(shù)量的填充數(shù)據(jù)。填充數(shù)據(jù)必須對(duì)植入代碼的功能完成沒(méi)有影響,這樣只要返回地址指向填充數(shù)據(jù)中的任何一個(gè)位置,均可以確保shellcode順利執(zhí)行。填充數(shù)據(jù)還可以起到一個(gè)作用,就是當(dāng)植入代碼的長(zhǎng)度夠不著覆蓋目標(biāo)如函數(shù)返回地址時(shí),可以通過(guò)增加填充數(shù)據(jù)的數(shù)量,使植入代碼的返回地址能夠覆蓋函數(shù)返回地址。NetworkSecurityTechnology2014AutumnSemester657.4.3填充數(shù)據(jù)對(duì)于IntelCPU來(lái)說(shuō),填充數(shù)據(jù)實(shí)質(zhì)上是一種單字節(jié)指令,使用得最多的是空操作指令NOP,其值為0x90,該指令什么也不做,僅跳過(guò)一個(gè)CPU周期。除此之外,還有其他的單字節(jié)指令可以作為填充數(shù)據(jù)使用,如調(diào)整計(jì)算結(jié)果的AAA和AAS、操作標(biāo)志位的CLC和CLD等。在植入代碼中,往往安排比較長(zhǎng)甚至幾百上千的填充數(shù)據(jù),而一個(gè)有效的指令長(zhǎng)度實(shí)際最大也不過(guò)10字節(jié)左右,因此,也可以根據(jù)這一特點(diǎn)來(lái)判斷是否發(fā)生了緩沖區(qū)溢出攻擊。NetworkSecurityTechnology2014AutumnSemester667.4.4植入代碼的構(gòu)造類型所植入的代碼是由黑客精心構(gòu)造的,而由于緩沖區(qū)溢出自身的特性,它的結(jié)構(gòu)和構(gòu)造類型有一定的特性。NSR模式RNS模式AR模式其中,S代表shellcode,R代表返回地址,N代表填充數(shù)據(jù),A表示環(huán)境變量。NetworkSecurityTechnology2014AutumnSemester67NSR模式NetworkSecurityTechnology2014AutumnSemester68NSR模式在shellcode的后面安排一定數(shù)量的返回地址,在前面安排一定數(shù)量的填充數(shù)據(jù),這種結(jié)構(gòu)稱為NSR型,或前端同步型。原理是:只要全部的N和S都處于緩沖區(qū)內(nèi),并且不覆蓋RET,而使R正好覆蓋存放RET的??臻g,這樣只要將R的值設(shè)置為指向N區(qū)中任一位置,就必然可以成功地跳轉(zhuǎn)到我們預(yù)先編寫(xiě)的shellcode處執(zhí)行。NetworkSecurityTechnology2014AutumnSemester69NSR模式這是一種經(jīng)典結(jié)構(gòu),適合于溢出緩沖區(qū)較大、足夠放下我們的shellcode的情況。這是一種非精確定位的方法,N元素越多成功率越大,其缺點(diǎn)是緩沖區(qū)必須足夠大,否則shellcode放不下或者N元素?cái)?shù)量太少都會(huì)造成失敗。NetworkSecurityTechnology2014AutumnSemester70RNS模式NetworkSecurityTechnology2014AutumnSemester71RNS模式其原理是:只要把整個(gè)緩沖區(qū)全部用大量的返回地址填滿,并且保證會(huì)覆蓋存放RET的棧空間,再在后面緊接N元素和shellcode,這樣就可以很容易地確定返回地址R的值,并在植入代碼中進(jìn)行設(shè)置。這里填充的R的數(shù)目必須能夠覆蓋ret,R的值必須指向大量N中的任何一個(gè)。這種方法對(duì)大的和小的緩沖區(qū)都有效。而且RET地址較容易計(jì)算。NetworkSecurityTechnology2014AutumnSemester72AR模式NetworkSecurityTechnology2014AutumnSemester73AR模式又稱環(huán)境變量型。這種構(gòu)造類型不同于NSR型和RNS型,它必須事先將shellcode放置在環(huán)境變量中,然后將shellcode的入口地址和填充數(shù)據(jù)構(gòu)成植入代碼進(jìn)行溢出攻擊。這種構(gòu)造類型對(duì)于大、小溢出緩沖區(qū)都適合。但由于必須事先將shellcode放置到環(huán)境變量中,故其應(yīng)用受到了限制,只能用于本地而不能用于遠(yuǎn)程攻擊。NetworkSecurityTechnology2014AutumnSemester74緩沖區(qū)溢出攻擊的三步曲從上面的分析可知,不管哪種類型的緩沖區(qū)溢出攻擊,一般都存在下面三個(gè)步驟:構(gòu)造需要執(zhí)行的代碼shellcode,并將其放到目標(biāo)系統(tǒng)的內(nèi)存。獲得緩沖區(qū)的大小和定位溢出點(diǎn)ret的位置??刂瞥绦蛱D(zhuǎn),改變程序流程。具體如何完成這三個(gè)攻擊步驟將在實(shí)驗(yàn)課中介紹。NetworkSecurityTechnology2014AutumnSemester757.4.5shellcode使用示例下面通過(guò)一個(gè)例子說(shuō)明棧溢出是如何產(chǎn)生的、以及如何利用它來(lái)執(zhí)行精心安排的shellcode:Vul-func(char*buf-src){
charbuf-dest[16];
strcpy(buf-dest,buf-src);}main(){
inti;
charstr[256];
for(i=0;i<256;i++) str[i]=’a’;
Vul-func(str);}NetworkSecurityTechnology2014AutumnSemester767.4.5shellcode使用示例顯然,數(shù)組str的大小(256字節(jié))遠(yuǎn)遠(yuǎn)超過(guò)了目的緩沖區(qū)buf-dest的大小(16字節(jié)),發(fā)生了緩沖區(qū)溢出。調(diào)用函數(shù)Vul-func前后,堆棧使用情況如下頁(yè)圖所示。NetworkSecurityTechnology2014AutumnSemester777.4.5shellcode使用示例
NetworkSecurityTechnology2014AutumnSemester787.4.5shellcode使用示例從上頁(yè)圖可以看出,Vul-func函數(shù)調(diào)用完成后,str數(shù)組的內(nèi)容(256個(gè)字母‘a(chǎn)’即0x616161?)已經(jīng)覆蓋了從地址buf-dest到地址buf-dest+256內(nèi)存空間原來(lái)所有的內(nèi)容,包括調(diào)用函數(shù)Vul-func時(shí)保存的EBP和返回地址RET。這樣,函數(shù)返回時(shí)就返回到地址0x61616161,發(fā)生錯(cuò)誤。緩沖區(qū)溢出使得程序執(zhí)行的流程發(fā)生了變化。NetworkSecurityTechnology2014AutumnSemester797.4.5shellcode使用示例如果能在返回地址RET處寫(xiě)入一段精心設(shè)計(jì)好的攻擊代碼的首地址,系統(tǒng)就會(huì)轉(zhuǎn)去執(zhí)行攻擊代碼,從而被攻破。如要獲得一個(gè)shell,可以安排執(zhí)行如下代碼:execve(“/bin/sh”,“/bin/sh”,NULL)NetworkSecurityTechnology2014AutumnSemester807.4.5shellcode使用示例將這段代碼進(jìn)行反匯編,就獲得了一個(gè)交互式shell的shellcode。只需將函數(shù)的返回地址RET覆蓋為此shellcode的首地址即可獲得一個(gè)shell:charshellcode[]=
“\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b”
“\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\”
“\x80\xe8\xdc\xff\xff\xff/bin/sh”;NetworkSecurityTechnology2014AutumnSemester817.4.5shellcode使用示例為了說(shuō)明如何使用shellcode以及如何精心安排溢出字符串,下面舉個(gè)例子來(lái)說(shuō)明。通過(guò)運(yùn)行下面的代碼,就能獲得一個(gè)shell,當(dāng)然,這個(gè)程序只具有實(shí)驗(yàn)?zāi)康?,不具有攻擊性。詳?xì)的攻擊實(shí)例將在實(shí)驗(yàn)課中介紹。NetworkSecurityTechnology2014AutumnSemester827.4.5shellcode使用示例ReturnaddBuffer(96bytes)ilong_ptr高地址低地址Para2Para1EBPBufferaddBufferaddBufferadd…Bufferadd…charshellcode[]=(前面的shellcode)charlarge-string[128];voidmain(intargc,char**argv){charbuffer[96];inti;long*long-ptr=(long*)large-string;/*用buffer的首地址填滿large-string*/for(i=0;i<32;i++)*(long-ptr+i)=(int)buffer;/*將shellcode填入large-string的前面部分*/for(i=0;i<strlen(shellcode);i++)
large-string[i]=shellcode[i];strcpy(buffer,large-string);}shellcodeNetworkSecurityTechnology2014AutumnSemester837.4.5shellcode使用示例這是一個(gè)利用棧溢出的程序。當(dāng)strcpy函數(shù)調(diào)用返回時(shí),其返回地址RET已被修改為buffer的首地址,而該地址正好存放的是shellcode。于是,shellcode被執(zhí)行,成功獲得一個(gè)交互式shell。這是由于strcpy執(zhí)行時(shí)不進(jìn)行邊界檢查所致。NetworkSecurityTechnology2014AutumnSemester847.4.5shellcode使用示例以上說(shuō)明的是攻擊我們自己的程序的原理。實(shí)際上,被攻擊程序的代碼及其緩沖區(qū)地址對(duì)攻擊者來(lái)說(shuō)是未知的,這就增加了攻擊的難度。一個(gè)有效地解決這個(gè)問(wèn)題的辦法是使用NSR模式,下面介紹NSR模式在此例中的應(yīng)用。NetworkSecurityTechnology2014AutumnSemester857.4.5shellcode使用示例首先,用猜測(cè)的buffer地址填充整個(gè)large-string;然后,把shellcode放置在large-string的中部,前部用空指令NOP填充;再將large-string的內(nèi)容放入注入到帶有緩沖區(qū)溢出隱患的程序,就可能獲得一個(gè)shell。前部填充的NOP是為了增加函數(shù)調(diào)用返回命中shellcode的命中率,只要返回地址指向其中一個(gè)NOP,shellcode將最終會(huì)被執(zhí)行,從而獲得shell。NetworkSecurityTechnology2014AutumnSemester867.5實(shí)例:ida溢出漏洞攻擊Ida漏洞判斷:Windows2Kserver或NT的IIS服務(wù)器的沒(méi)有打servicepark(補(bǔ)丁包,簡(jiǎn)稱SP),那么它就存在一個(gè)ida漏洞,我們?cè)跒g覽器里輸入一個(gè)不存在的.ida文件,如:http://xxx.xxx.xxx.xxx/Nature.ida
如果瀏覽器就會(huì)返回如下的提示:找不到IDA文件在……則說(shuō)明該WEB服務(wù)器存在IDA溢出漏洞。NetworkSecurityTechnology2014AutumnSemester87ida溢出漏洞攻擊工具:ofscan:IIS遠(yuǎn)程溢出漏洞掃描工具Idahack:ida漏洞利用工具Nc:瑞士軍刀NetworkSecurityTechnology2014AutumnSemester88Ofscan使用方法NetworkSecurityTechnology2014AutumnSemester89用ofscan掃描存在ida漏洞的主機(jī)掃描到6臺(tái)有可能有漏洞。NetworkSecurityTechnology2014AutumnSemester90Idahack使用方法NetworkSecurityTechnology2014AutumnSemester91用idahack進(jìn)行攻擊—失敗后的結(jié)果NetworkSecurityTechnology2014AutumnSemester92用idahack進(jìn)行攻擊—成功后的結(jié)果NetworkSecurityTechnology2014AutumnSemester93用nc獲得一個(gè)shell
NetworkSecurityTechnology2014AutumnSemester94獲得shell后可以查看對(duì)方的信息NetworkSecurityTechnology2014AutumnSemester95在shell中運(yùn)行命令:添加用戶NetworkSecurityTechnology2014AutumnSemester967.6緩沖區(qū)溢出的防御7.6.1緩沖區(qū)溢出防御概述7.6.2源碼級(jí)保護(hù)方法7.6.3運(yùn)行期保護(hù)方法7.6.4阻止攻擊代碼執(zhí)行7.6.5加強(qiáng)系統(tǒng)保護(hù)NetworkSecurityTechnology2014AutumnSemester977.6.1緩沖區(qū)溢出防御概述從前面我們可以看出,緩沖區(qū)溢出的真正原因在于某些編程語(yǔ)言缺乏類型安全,程序缺少邊界檢查。這一方面是源于編程語(yǔ)言和庫(kù)函數(shù)本身的弱點(diǎn),如C語(yǔ)言中對(duì)數(shù)組和指針引用不自動(dòng)進(jìn)行邊界檢查,一些字符串處理函數(shù)如strcpy、sprintf等存在著嚴(yán)重的安全問(wèn)題。另一方面是程序員進(jìn)行程序編寫(xiě)時(shí),由于經(jīng)驗(yàn)不足或粗心大意,沒(méi)有進(jìn)行或忽略了邊界檢查,使得緩沖區(qū)溢出漏洞幾乎無(wú)處不在,為緩沖區(qū)溢出攻擊留下了隱患。NetworkSecurityTechnology2014AutumnSemester987.6.1緩沖區(qū)溢出防御概述這樣要么放棄使用這類語(yǔ)言中的不安全類型,放棄不安全的類型就等于放棄這類語(yǔ)言的精華;要么使用其它的類型安全語(yǔ)言,如JAVA等。而放棄C/C++語(yǔ)言等這樣高效易用的編程語(yǔ)言對(duì)于大部分程序員又是不能接受的,所以只能采取其它的防護(hù)措施。NetworkSecurityTechnology2014AutumnSemester997.6.1緩沖區(qū)溢出防御概述首先,可以考慮在一般的攻擊防護(hù)產(chǎn)品中加入針對(duì)緩沖區(qū)溢出攻擊的防護(hù)功能,如防火墻和IDS等??梢詮膬煞矫嬷?一是可以提取用于攻擊的shellcode的普遍特征作為攻擊特征,過(guò)濾掉這樣的數(shù)據(jù)包或者觸發(fā)報(bào)警。二是對(duì)特定的服務(wù)限定請(qǐng)求數(shù)據(jù)的值的范圍,比如,某一服務(wù)要求請(qǐng)求數(shù)據(jù)為可打印字符串,如果發(fā)現(xiàn)對(duì)這一服務(wù)的請(qǐng)求存在不可打印字符則認(rèn)為發(fā)生攻擊。NetworkSecurityTechnology2014AutumnSemester1007.6.1緩沖區(qū)溢出防御概述其次,通過(guò)分析緩沖區(qū)溢出攻擊的原理,可以發(fā)現(xiàn)緩沖區(qū)溢出能夠成功的幾個(gè)條件:編譯器本身或庫(kù)函數(shù)沒(méi)有對(duì)數(shù)組類型的數(shù)據(jù)結(jié)構(gòu)做嚴(yán)格的邊界檢查,這是溢出的首要原因;返回地址放在堆棧的底部,使得通過(guò)溢出可以覆蓋返回地址;堆棧的屬性一般是可執(zhí)行的,使得惡意代碼得以執(zhí)行。NetworkSecurityTechnology2014AutumnSemester1017.6.2源碼級(jí)保護(hù)方法避免源碼中的相關(guān)bug源碼中溢出bug的查找數(shù)組邊界檢查編譯器NetworkSecurityTechnology2014AutumnSemester102(1)避免源碼中的相關(guān)bug防患于未然。在軟件開(kāi)發(fā)過(guò)程中,對(duì)涉及到緩沖區(qū)的操作,做嚴(yán)格的邊界檢查,從代碼編寫(xiě)層防止緩沖區(qū)溢出。C語(yǔ)言是其中最具代表性的一種,由于只追求性能的傳統(tǒng)認(rèn)識(shí),它具有容易出錯(cuò)的傾向,有許多字符串處理函數(shù)存在未檢查輸入?yún)?shù)長(zhǎng)度和邊界問(wèn)題、字符串以零結(jié)尾而不是用下標(biāo)管理等。對(duì)使用C語(yǔ)言的開(kāi)發(fā)人員來(lái)說(shuō),放棄這種高效易用的編程語(yǔ)言是不能接受的,因此,只能要求程序員提高自身編程水平,在編寫(xiě)程序時(shí)盡量避免有錯(cuò)誤傾向的代碼出現(xiàn)。不過(guò),保證代碼的正確性和安全性是一個(gè)非常復(fù)雜的問(wèn)題,這也將使開(kāi)發(fā)人員的工作效率大大降低。在現(xiàn)代的程序開(kāi)發(fā)中,應(yīng)用程序往往十分龐大,加之程序員的經(jīng)驗(yàn)有限,要想徹底避免此類問(wèn)題,在實(shí)際應(yīng)用中往往是很難做到的。NetworkSecurityTechnology2014AutumnSemester103(1)避免源碼中的相關(guān)bug這里列出了一些編寫(xiě)程序時(shí)應(yīng)該盡量避免使用的C庫(kù)函數(shù)。使用時(shí)程序員要注意自行檢查邊界,或者盡可能使用其對(duì)應(yīng)的替代函數(shù)。NetworkSecurityTechnology2014AutumnSemester104(2)源碼中溢出bug的查找人們嘗試開(kāi)發(fā)一些工具進(jìn)行針對(duì)程序溢出漏洞的代碼審計(jì)工作。也就是利用工具對(duì)源碼中可能存在溢出bug的部分代碼進(jìn)行分析以發(fā)現(xiàn)bug。最簡(jiǎn)單的方法就是搜索源碼中容易產(chǎn)生漏洞的庫(kù)函數(shù)調(diào)用,如典型的strcpy和sprintf這兩個(gè)函數(shù)調(diào)用,它們都沒(méi)有檢查輸入?yún)?shù)的長(zhǎng)度。如利用grep來(lái)查找和搜索。這種方法雖然可以提高查找的效率,但是它需要較多的專業(yè)知識(shí),要求安全審計(jì)人員對(duì)語(yǔ)言本身非常熟悉。同時(shí)由于grep只是簡(jiǎn)單的對(duì)字符串進(jìn)行匹配,只能發(fā)現(xiàn)眾多問(wèn)題中的很小的一部分,通常只是被作為輔助的工具使用。
NetworkSecurityTechnology2014AutumnSemester105(2)源碼中溢出bug的查找一些組織和實(shí)驗(yàn)室開(kāi)發(fā)了一些高級(jí)的查錯(cuò)工具,如faultinjection、ITS4等。ITS4是針對(duì)C/C++設(shè)計(jì)的靜態(tài)分析工具,可以在Windows、Unix/Linux環(huán)境下使用。它通過(guò)掃描源代碼、對(duì)源代碼執(zhí)行模式匹配來(lái)進(jìn)行工作,對(duì)可能危險(xiǎn)的模式(如特定的函數(shù)調(diào)用)進(jìn)行提取和分析,確定危險(xiǎn)的程度,對(duì)危險(xiǎn)的函數(shù)調(diào)用提供問(wèn)題的說(shuō)明和如何修復(fù)源代碼的建議。NetworkSecurityTechnology2014AutumnSemester1067.6.3運(yùn)行期保護(hù)方法運(yùn)行期保護(hù)方法概述插入目標(biāo)代碼進(jìn)行數(shù)組邊界檢查返回指針的完整性檢查NetworkSecurityTechnology2014AutumnSemester107(1)運(yùn)行期保護(hù)方法概述運(yùn)行期保護(hù)方法主要研究如何在程序運(yùn)行的過(guò)程中發(fā)現(xiàn)或阻止緩沖區(qū)溢出攻擊。這種方法具有簡(jiǎn)潔、方便的特點(diǎn),而且對(duì)相關(guān)知識(shí)要求不高,因而更為實(shí)用。目前,動(dòng)態(tài)保護(hù)研究的主要方面是數(shù)組邊界檢查和如何保證返回指針的完整性。NetworkSecurityTechnology2014AutumnSemester108(2)插入目標(biāo)代碼進(jìn)行數(shù)組邊界檢查只要數(shù)組不能被溢出,溢出攻擊也就無(wú)從談起。數(shù)組邊界檢查就是檢查數(shù)組實(shí)際長(zhǎng)度是否超過(guò)了分配的長(zhǎng)度。如果超過(guò),立即進(jìn)行相應(yīng)的處理,如:舍去超出分配長(zhǎng)度的部分。NetworkSecurityTechnology2014AutumnSemester109(2)插入目標(biāo)代碼進(jìn)行數(shù)組邊界檢查為了實(shí)現(xiàn)數(shù)組邊界檢查,則所有的對(duì)數(shù)組的讀寫(xiě)操作都應(yīng)當(dāng)被檢查以確保對(duì)數(shù)組的操作在正確的范圍內(nèi)。最直接的方法是檢查所有的數(shù)組操作,但是通??梢圆捎靡恍﹥?yōu)化的技術(shù)來(lái)減少檢查的次數(shù)。NetworkSecurityTechnology2014AutumnSemester110(2)插入目標(biāo)代碼進(jìn)行數(shù)組邊界檢查目前有以下的幾種檢查方法:
CompaqC編譯器Jones&Kelly:C的數(shù)組邊界檢查Purify:存儲(chǔ)器存取檢查類型-安全語(yǔ)言NetworkSecurityTechnology2014AutumnSemester111CompaqC編譯器Compaq公司為AlphaCPU開(kāi)發(fā)的C編譯器支持有限度的邊界檢查(使用-check_bounds參數(shù))。這些限制是:只有顯示的數(shù)組引用才被檢查,比如“a[3]”會(huì)被檢查,而“*(a+3)”則不會(huì)。由于所有的C數(shù)組在傳送的時(shí)候是指針傳遞的,所以傳遞給函數(shù)的的數(shù)組不會(huì)被檢查。帶有危險(xiǎn)性的庫(kù)函數(shù)如strcpy不會(huì)在編譯的時(shí)候進(jìn)行邊界檢查,即便是指定了邊界檢查。NetworkSecurityTechnology2014AutumnSemester112CompaqC編譯器(2)由于在C語(yǔ)言中利用指針進(jìn)行數(shù)組操作和傳遞是如此的頻繁,因此這種局限性是非常嚴(yán)重的。通常這種邊界檢查用來(lái)程序的查錯(cuò),而且不能保證不發(fā)生緩沖區(qū)溢出的漏洞。NetworkSecurityTechnology2014AutumnSemester113Jones&Kelly:C的數(shù)組邊界檢查
RichardJones和PaulKelly開(kāi)發(fā)了一個(gè)gcc的補(bǔ)丁,用來(lái)實(shí)現(xiàn)對(duì)C程序完全的數(shù)組邊界檢查。由于沒(méi)有改變指針的含義,所以被編譯的程序和其他的gcc模塊具有很好的兼容性。更進(jìn)一步的是,他們由此從沒(méi)有指針的表達(dá)式中導(dǎo)出了一個(gè)“基”指針,然后通過(guò)檢查這個(gè)基指針來(lái)偵測(cè)表達(dá)式的結(jié)果是否在容許的范圍之內(nèi)。NetworkSecurityTechnology2014AutumnSemester114Jones&Kelly:C的數(shù)組邊界檢查(2)
當(dāng)然,這樣付出的性能上的代價(jià)是巨大的:對(duì)于一個(gè)頻繁使用指針的程序如向量乘法,將由于指針的頻繁使用而使速度比本來(lái)慢30倍。這個(gè)編譯器目前還很不成熟;一些復(fù)雜的程序還不能在這個(gè)上面編譯。NetworkSecurityTechnology2014AutumnSemester115Purify:存儲(chǔ)器存取檢查Purify是C程序調(diào)試時(shí)查看存儲(chǔ)器使用的工具而不是專用的安全工具。Purify使用“目標(biāo)代碼插入”技術(shù)來(lái)檢查所有的存儲(chǔ)器存取。通過(guò)用Purify連接工具連接,可執(zhí)行代碼在執(zhí)行的時(shí)候帶來(lái)的性能上的損失要下降3-5倍。NetworkSecurityTechnology2014AutumnSemester116類型-安全語(yǔ)言所有的緩沖區(qū)溢出漏洞都源于語(yǔ)言缺乏類型安全。如果只有類型-安全的操作才可以被允許執(zhí)行,這樣就不可能出現(xiàn)對(duì)變量的強(qiáng)制操作。如果作為新手,可以推薦使用具有類型-安全的語(yǔ)言如Java和C#。NetworkSecurityTechnology2014AutumnSemester117類型-安全語(yǔ)言(2)但是作為Java執(zhí)行平臺(tái)的Java虛擬機(jī)是C程序,因此通過(guò)攻擊JVM的一條途徑是使JVM的緩沖區(qū)溢出。NetworkSecurityTechnology2014AutumnSemester118(3)返回指針的完整性檢查程序指針完整性檢查和邊界檢查的思路不同。它不是防止程序指針被改變,而是在程序指針被引用之前檢測(cè)它是否被改變。因此,即便一個(gè)攻擊者成功地改變了程序的指針,系統(tǒng)會(huì)事先檢測(cè)到指針的改變,而廢棄這個(gè)指針。NetworkSecurityTechnology2014AutumnSemester119(3)返回指針的完整性檢查返回指針的完整性檢查主要采用了如下幾種手段:堆棧監(jiān)測(cè)StackGuardStackShieldNetworkSecurityTechnology2014AutumnSemester120堆棧監(jiān)測(cè)堆棧監(jiān)測(cè)是一種提供程序指針完整性檢查的編譯器技術(shù),通過(guò)檢查函數(shù)活動(dòng)記錄中的返回地址來(lái)實(shí)現(xiàn)。它在每個(gè)函數(shù)中,加入了函數(shù)建立和銷(xiāo)毀的代碼,加入的函數(shù)建立代碼實(shí)際上在堆棧中的函數(shù)返回地址前面加了一些附加的字節(jié),而在函數(shù)返回時(shí),首先檢查這個(gè)附加的字節(jié)是否被改動(dòng)過(guò),如果發(fā)生過(guò)緩沖區(qū)溢出,那么就很容易在函數(shù)返回前被檢測(cè)到。NetworkSecurityTechnology2014AutumnSemester121StackGuardStackGuard是標(biāo)準(zhǔn)GNU的C編譯器gcc的一個(gè)修改版。它通過(guò)在函數(shù)返回地址之前插入一個(gè)“守衛(wèi)”值(canary值),在函數(shù)返回前檢查canary值是否被修改,來(lái)保證返回地址的完整性。StackGuard作為gcc的一個(gè)補(bǔ)丁,修改了函數(shù)建立和銷(xiāo)毀部分的代碼,由
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 員工聘用協(xié)議書(shū)2023
- 個(gè)人租房的合同協(xié)議書(shū)范本10篇
- 再婚離婚協(xié)議書(shū)2025年
- 重癥肌無(wú)力樣綜合征病因介紹
- T-CIECCPA 011-2024 高雜貴金屬冶煉渣資源化處理技術(shù)規(guī)范
- 中考?xì)v史復(fù)習(xí)第一部分教材知識(shí)速查模塊2中國(guó)近代史第1講列強(qiáng)的侵略與中國(guó)人民的抗?fàn)幑_(kāi)課一等獎(jiǎng)省
- (2024)汽車(chē)內(nèi)飾用品項(xiàng)目可行性研究報(bào)告寫(xiě)作范本(一)
- 2023年金屬門(mén)窗及類似制品項(xiàng)目融資計(jì)劃書(shū)
- 2023年紡織產(chǎn)品項(xiàng)目籌資方案
- 《開(kāi)環(huán)伯德圖的繪制》課件
- 人工智能智慧樹(shù)知到答案章節(jié)測(cè)試2023年復(fù)旦大學(xué)
- 中小學(xué)學(xué)校固定資產(chǎn)教育分類代碼財(cái)政部2021
- 中國(guó)108種烹飪技法名稱
- 統(tǒng)編版六年級(jí)下冊(cè)語(yǔ)文詞句段運(yùn)用及仿寫(xiě)
- GB/T 18103-2022實(shí)木復(fù)合地板
- 地下礦山掘進(jìn)施工現(xiàn)場(chǎng)應(yīng)急處置方案
- 現(xiàn)代高層寫(xiě)字樓的創(chuàng)新管理和增值服務(wù)
- 2023年吉大考博英語(yǔ)真題
- GB/T 35792-2018風(fēng)力發(fā)電機(jī)組合格測(cè)試及認(rèn)證
- GB/T 29240-2012信息安全技術(shù)終端計(jì)算機(jī)通用安全技術(shù)要求與測(cè)試評(píng)價(jià)方法
- GB/T 22085.2-2008電子束及激光焊接接頭缺欠質(zhì)量分級(jí)指南第2部分:鋁及鋁合金
評(píng)論
0/150
提交評(píng)論