溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

緩沖區(qū)溢出的保護機制是什么

發(fā)布時間:2021-10-28 14:38:41 來源:億速云 閱讀:166 作者:iii 欄目:編程語言

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

緩沖區(qū)溢出原理

緩沖區(qū)是內(nèi)存中存放數(shù)據(jù)的地方。在程序試圖將數(shù)據(jù)放到機器內(nèi)存中的某一個位置的時候,因為沒有足夠的空間就會發(fā)生緩沖區(qū)溢出。而人為的溢出則是有一定企圖的,攻擊者寫一個超過緩沖區(qū)長度的字符串,植入到緩沖區(qū),然后再向一個有限空間的緩沖區(qū)中植入超長的字符串,這時可能會出現(xiàn)兩個結(jié)果:一是過長的字符串覆蓋了相鄰的存儲單元,引起程序運行失敗,嚴重的可導(dǎo)致系統(tǒng)崩潰;另一個結(jié)果就是利用這種漏洞可以執(zhí)行任意指令,甚至可以取得系統(tǒng)root特級權(quán)限。

緩沖區(qū)是程序運行的時候機器內(nèi)存中的一個連續(xù)塊,它保存了給定類型的數(shù)據(jù),隨著動態(tài)分配變量會出現(xiàn)問題。大多時為了不占用太多的內(nèi)存,一個有動態(tài)分配變量的程序在程序運行時才決定給它們分配多少內(nèi)存。如果程序在動態(tài)分配緩沖區(qū)放入超長的數(shù)據(jù),它就會溢出了。一個緩沖區(qū)溢出程序使用這個溢出的數(shù)據(jù)將匯編語言代碼放到機器的內(nèi)存里,通常是產(chǎn)生root權(quán)限的地方。僅僅單個的緩沖區(qū)溢出并不是問題的根本所在。但如果溢出送到能夠以root權(quán)限運行命令的區(qū)域,一旦運行這些命令,那可就等于把機器拱手相讓了。

造成緩沖區(qū)溢出的原因是程序中沒有仔細檢查用戶輸入的參數(shù)。例如下面程序:

void func1(char *input)
{
char buffer[16];
strcpy(buffer, input);
}

上面的strcpy()將直接吧input中的內(nèi)容copy到buffer中。這樣只要input的長度大于16,就會造成buffer的溢出,使程序運行出錯。存在像strcpy這樣的問題的標準函數(shù)還有strcat(),sprintf(),vsprintf(),gets(),scanf(),以及在循環(huán)內(nèi)的getc(),fgetc(),getchar()等。

當(dāng)然,隨便往緩沖區(qū)中填東西造成它溢出一般只會出現(xiàn)Segmentation fault 錯誤,而不能達到攻擊的目的。最常見的手段是通過制造緩沖區(qū)溢出使程序運行一個用戶shell,再通過shell執(zhí)行其他命令。如果該程序?qū)儆趓oot且有suid權(quán)限的話,攻擊者就獲得了一個有root權(quán)限的shell,便可以對系統(tǒng)進行任意操作了。

請注意,如果沒有特別說明,下面的內(nèi)容都假設(shè)用戶使用的平臺為基于Intel x86 CPU的Linux系統(tǒng)。對其他平臺來說,本文的概念同樣適用,但程序要做相應(yīng)修改。

CANNARY(棧保護)

這個選項表示棧保護功能有沒有開啟。

棧溢出保護是一種緩沖區(qū)溢出攻擊緩解手段,當(dāng)函數(shù)存在緩沖區(qū)溢出攻擊漏洞時,攻擊者可以覆蓋棧上的返回地址來讓shellcode能夠得到執(zhí)行。當(dāng)啟用棧保護后,函數(shù)開始執(zhí)行的時候會先往棧里插入cookie信息,當(dāng)函數(shù)真正返回的時候會驗證cookie信息是否合法,如果不合法就停止程序運行。攻擊者在覆蓋返回地址的時候往往也會將cookie信息給覆蓋掉,導(dǎo)致棧保護檢查失敗而阻止shellcode的執(zhí)行。在Linux中我們將cookie信息稱為canary。

gcc在4.2版本中添加了-fstack-protector和-fstack-protector-all編譯參數(shù)以支持棧保護功能,4.9新增了-fstack-protector-strong編譯參數(shù)讓保護的范圍更廣。

因此在編譯時可以控制是否開啟棧保護以及程度,例如:

gcc -fno-stack-protector -o test test.c  //禁用棧保護
gcc -fstack-protector -o test test.c   //啟用堆棧保護,不過只為局部變量中含有 char 數(shù)組的函數(shù)插入保護代碼
gcc -fstack-protector-all -o test test.c //啟用堆棧保護,為所有函數(shù)插入保護代碼

FORTIFY

這個保護機制查了很久都沒有個很好的漢語形容,根據(jù)我的理解它其實和棧保護都是gcc的新的為了增強保護的一種機制,防止緩沖區(qū)溢出攻擊。由于并不是太常見,也沒有太多的了解。

舉個例子可能簡單明了一些:
一段簡單的存在緩沖區(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     ; 將目標參數(shù)載入eax
mov    %eax,0x4(%esp)     ; 保存目標參數(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)作目標參數(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ù)名,達到防止緩沖區(qū)溢出的作用。

NX(DEP)

NX即No-eXecute(不可執(zhí)行)的意思,NX(DEP)的基本原理是將數(shù)據(jù)所在內(nèi)存頁標識為不可執(zhí)行,當(dāng)程序溢出成功轉(zhuǎn)入shellcode時,程序會嘗試在數(shù)據(jù)頁面上執(zhí)行指令,此時CPU就會拋出異常,而不是去執(zhí)行惡意指令。
gcc編譯器默認開啟了NX選項,如果需要關(guān)閉NX選項,可以給gcc編譯器添加-z execstack參數(shù)。
例如:

gcc -z execstack -o test test.c

在Windows下,類似的概念為DEP(數(shù)據(jù)執(zhí)行保護),在最新版的Visual Studio中默認開啟了DEP編譯選項。

PIE(ASLR)

一般情況下NX(Windows平臺上稱其為DEP)和地址空間分布隨機化(ASLR)會同時工作。

內(nèi)存地址隨機化機制(address space layout randomization),有以下三種情況

0 - 表示關(guān)閉進程地址空間隨機化。
1 - 表示將mmap的基址,stack和vdso頁面隨機化。
2 - 表示在1的基礎(chǔ)上增加棧(heap)的隨機化。

可以防范基于Ret2libc方式的針對DEP的攻擊。ASLR和DEP配合使用,能有效阻止攻擊者在堆棧上運行惡意代碼。

Built as PIE:位置獨立的可執(zhí)行區(qū)域(position-independent executables)。這樣使得在利用緩沖溢出和移動操作系統(tǒng)中存在的其他內(nèi)存崩潰缺陷時采用面向返回的編程(return-oriented programming)方法變得難得多。

liunx下關(guān)閉PIE的命令如下:

sudo -s echo 0 > /proc/sys/kernel/randomize_va_space

ASLR效果

1、映像隨機化

映像隨機化是在PE文件映射到內(nèi)存時,對其加載的虛擬地址進行隨機化處理,這個地址是在系統(tǒng)啟動時確定的,系統(tǒng)重啟后這個地址會有變化。

2、堆棧隨機化

程序運行時隨機選擇堆棧的基址,與映像隨機化不同的是堆棧的基址不是在系統(tǒng)啟動時確定的,而是在程序打開時確定的,也就是說同一個程序任意兩次運行時的堆?;范疾幌嗤?/p>

3、PEB與TEB隨機化

微軟在XP SP2之后不再使用固定的PEB基址0x7FFDF000和TEB基址0x7FFDE000,而是使用具有一定隨機性的基址。

TEB存放在FS:0和FS:[0x18]處,PEB存放在TEB偏移0x30的位置

RELRO

設(shè)置符號重定向表格為只讀或在程序啟動時就解析并綁定所有動態(tài)符號,從而減少對GOT(Global Offset Table)攻擊。

“緩沖區(qū)溢出的保護機制是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI