本篇內(nèi)容介紹了“緩沖區(qū)溢出的保護(hù)機(jī)制是什么”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都網(wǎng)站建設(shè)、做網(wǎng)站的關(guān)注點(diǎn)不是能為您做些什么網(wǎng)站,而是怎么做網(wǎng)站,有沒有做好網(wǎng)站,給創(chuàng)新互聯(lián)一個(gè)展示的機(jī)會來證明自己,這并不會花費(fèi)您太多時(shí)間,或許會給您帶來新的靈感和驚喜。面向用戶友好,注重用戶體驗(yàn),一切以用戶為中心。
緩沖區(qū)是內(nèi)存中存放數(shù)據(jù)的地方。在程序試圖將數(shù)據(jù)放到機(jī)器內(nèi)存中的某一個(gè)位置的時(shí)候,因?yàn)闆]有足夠的空間就會發(fā)生緩沖區(qū)溢出。而人為的溢出則是有一定企圖的,攻擊者寫一個(gè)超過緩沖區(qū)長度的字符串,植入到緩沖區(qū),然后再向一個(gè)有限空間的緩沖區(qū)中植入超長的字符串,這時(shí)可能會出現(xiàn)兩個(gè)結(jié)果:一是過長的字符串覆蓋了相鄰的存儲單元,引起程序運(yùn)行失敗,嚴(yán)重的可導(dǎo)致系統(tǒng)崩潰;另一個(gè)結(jié)果就是利用這種漏洞可以執(zhí)行任意指令,甚至可以取得系統(tǒng)root特級權(quán)限。
緩沖區(qū)是程序運(yùn)行的時(shí)候機(jī)器內(nèi)存中的一個(gè)連續(xù)塊,它保存了給定類型的數(shù)據(jù),隨著動態(tài)分配變量會出現(xiàn)問題。大多時(shí)為了不占用太多的內(nèi)存,一個(gè)有動態(tài)分配變量的程序在程序運(yùn)行時(shí)才決定給它們分配多少內(nèi)存。如果程序在動態(tài)分配緩沖區(qū)放入超長的數(shù)據(jù),它就會溢出了。一個(gè)緩沖區(qū)溢出程序使用這個(gè)溢出的數(shù)據(jù)將匯編語言代碼放到機(jī)器的內(nèi)存里,通常是產(chǎn)生root權(quán)限的地方。僅僅單個(gè)的緩沖區(qū)溢出并不是問題的根本所在。但如果溢出送到能夠以root權(quán)限運(yùn)行命令的區(qū)域,一旦運(yùn)行這些命令,那可就等于把機(jī)器拱手相讓了。
造成緩沖區(qū)溢出的原因是程序中沒有仔細(xì)檢查用戶輸入的參數(shù)。例如下面程序:
void func1(char *input)
{
char buffer[16];
strcpy(buffer, input);
}上面的strcpy()將直接吧input中的內(nèi)容copy到buffer中。這樣只要input的長度大于16,就會造成buffer的溢出,使程序運(yùn)行出錯。存在像strcpy這樣的問題的標(biāo)準(zhǔn)函數(shù)還有strcat(),sprintf(),vsprintf(),gets(),scanf(),以及在循環(huán)內(nèi)的getc(),fgetc(),getchar()等。
當(dāng)然,隨便往緩沖區(qū)中填東西造成它溢出一般只會出現(xiàn)Segmentation fault 錯誤,而不能達(dá)到攻擊的目的。最常見的手段是通過制造緩沖區(qū)溢出使程序運(yùn)行一個(gè)用戶shell,再通過shell執(zhí)行其他命令。如果該程序?qū)儆趓oot且有suid權(quán)限的話,攻擊者就獲得了一個(gè)有root權(quán)限的shell,便可以對系統(tǒng)進(jìn)行任意操作了。
請注意,如果沒有特別說明,下面的內(nèi)容都假設(shè)用戶使用的平臺為基于Intel x86 CPU的Linux系統(tǒng)。對其他平臺來說,本文的概念同樣適用,但程序要做相應(yīng)修改。
這個(gè)選項(xiàng)表示棧保護(hù)功能有沒有開啟。
棧溢出保護(hù)是一種緩沖區(qū)溢出攻擊緩解手段,當(dāng)函數(shù)存在緩沖區(qū)溢出攻擊漏洞時(shí),攻擊者可以覆蓋棧上的返回地址來讓shellcode能夠得到執(zhí)行。當(dāng)啟用棧保護(hù)后,函數(shù)開始執(zhí)行的時(shí)候會先往棧里插入cookie信息,當(dāng)函數(shù)真正返回的時(shí)候會驗(yàn)證cookie信息是否合法,如果不合法就停止程序運(yùn)行。攻擊者在覆蓋返回地址的時(shí)候往往也會將cookie信息給覆蓋掉,導(dǎo)致棧保護(hù)檢查失敗而阻止shellcode的執(zhí)行。在Linux中我們將cookie信息稱為canary。
gcc在4.2版本中添加了-fstack-protector和-fstack-protector-all編譯參數(shù)以支持棧保護(hù)功能,4.9新增了-fstack-protector-strong編譯參數(shù)讓保護(hù)的范圍更廣。
因此在編譯時(shí)可以控制是否開啟棧保護(hù)以及程度,例如:
gcc -fno-stack-protector -o test test.c //禁用棧保護(hù)
gcc -fstack-protector -o test test.c //啟用堆棧保護(hù),不過只為局部變量中含有 char 數(shù)組的函數(shù)插入保護(hù)代碼
gcc -fstack-protector-all -o test test.c //啟用堆棧保護(hù),為所有函數(shù)插入保護(hù)代碼
這個(gè)保護(hù)機(jī)制查了很久都沒有個(gè)很好的漢語形容,根據(jù)我的理解它其實(shí)和棧保護(hù)都是gcc的新的為了增強(qiáng)保護(hù)的一種機(jī)制,防止緩沖區(qū)溢出攻擊。由于并不是太常見,也沒有太多的了解。
舉個(gè)例子可能簡單明了一些:
一段簡單的存在緩沖區(qū)溢出的C代碼
void fun(char *s) {
char buf[0x100];
strcpy(buf, s);
/* Don't allow gcc to optimise away the buf */
asm volatile("" :: "m" (buf));
}用包含參數(shù)-UFORTIFYSOURCE編譯
08048450 <fun>: push %ebp ; mov %esp,%ebp sub $0x118,%esp ; 將0x118存儲到棧上 mov 0x8(%ebp),%eax ; 將目標(biāo)參數(shù)載入eax mov %eax,0x4(%esp) ; 保存目標(biāo)參數(shù) lea -0x108(%ebp),%eax ; 數(shù)組buf mov %eax,(%esp) ; 保存 call 8048320 <strcpy@plt> leave ; ret
用包含參數(shù)-DFORTIFYSOURCE=2編譯
08048470 <fun>: push %ebp ; mov %esp,%ebp sub $0x118,%esp ; movl $0x100,0x8(%esp) ; 把0x100當(dāng)作目標(biāo)參數(shù)保存 mov 0x8(%ebp),%eax ; mov %eax,0x4(%esp) ; lea -0x108(%ebp),%eax ; mov %eax,(%esp) ; call 8048370 <__strcpy_chk@plt> leave ; ret
我們可以看到gcc生成了一些附加代碼,通過對數(shù)組大小的判斷替換strcpy, memcpy, memset等函數(shù)名,達(dá)到防止緩沖區(qū)溢出的作用。
NX即No-eXecute(不可執(zhí)行)的意思,NX(DEP)的基本原理是將數(shù)據(jù)所在內(nèi)存頁標(biāo)識為不可執(zhí)行,當(dāng)程序溢出成功轉(zhuǎn)入shellcode時(shí),程序會嘗試在數(shù)據(jù)頁面上執(zhí)行指令,此時(shí)CPU就會拋出異常,而不是去執(zhí)行惡意指令。
gcc編譯器默認(rèn)開啟了NX選項(xiàng),如果需要關(guān)閉NX選項(xiàng),可以給gcc編譯器添加-z execstack參數(shù)。
例如:
gcc -z execstack -o test test.c
在Windows下,類似的概念為DEP(數(shù)據(jù)執(zhí)行保護(hù)),在最新版的Visual Studio中默認(rèn)開啟了DEP編譯選項(xiàng)。
一般情況下NX(Windows平臺上稱其為DEP)和地址空間分布隨機(jī)化(ASLR)會同時(shí)工作。
內(nèi)存地址隨機(jī)化機(jī)制(address space layout randomization),有以下三種情況
0 - 表示關(guān)閉進(jìn)程地址空間隨機(jī)化。
1 - 表示將mmap的基址,stack和vdso頁面隨機(jī)化。
2 - 表示在1的基礎(chǔ)上增加棧(heap)的隨機(jī)化。
可以防范基于Ret2libc方式的針對DEP的攻擊。ASLR和DEP配合使用,能有效阻止攻擊者在堆棧上運(yùn)行惡意代碼。
Built as PIE:位置獨(dú)立的可執(zhí)行區(qū)域(position-independent executables)。這樣使得在利用緩沖溢出和移動操作系統(tǒng)中存在的其他內(nèi)存崩潰缺陷時(shí)采用面向返回的編程(return-oriented programming)方法變得難得多。
liunx下關(guān)閉PIE的命令如下:
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
ASLR效果
1、映像隨機(jī)化
映像隨機(jī)化是在PE文件映射到內(nèi)存時(shí),對其加載的虛擬地址進(jìn)行隨機(jī)化處理,這個(gè)地址是在系統(tǒng)啟動時(shí)確定的,系統(tǒng)重啟后這個(gè)地址會有變化。
2、堆棧隨機(jī)化
程序運(yùn)行時(shí)隨機(jī)選擇堆棧的基址,與映像隨機(jī)化不同的是堆棧的基址不是在系統(tǒng)啟動時(shí)確定的,而是在程序打開時(shí)確定的,也就是說同一個(gè)程序任意兩次運(yùn)行時(shí)的堆棧基址都不相同。
3、PEB與TEB隨機(jī)化
微軟在XP SP2之后不再使用固定的PEB基址0x7FFDF000和TEB基址0x7FFDE000,而是使用具有一定隨機(jī)性的基址。
TEB存放在FS:0和FS:[0x18]處,PEB存放在TEB偏移0x30的位置
設(shè)置符號重定向表格為只讀或在程序啟動時(shí)就解析并綁定所有動態(tài)符號,從而減少對GOT(Global Offset Table)攻擊。
“緩沖區(qū)溢出的保護(hù)機(jī)制是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)站標(biāo)題:緩沖區(qū)溢出的保護(hù)機(jī)制是什么
文章網(wǎng)址:http://chinadenli.net/article6/jiepig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、建站公司、網(wǎng)站內(nèi)鏈、Google、搜索引擎優(yōu)化、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)