原創 緩衝區溢位

2022-05-13 14:39:49 字數 2300 閱讀 5302

主要原理就是通過往程式的緩衝區寫超出其長度的內容,造成緩衝區的溢位,從而破壞程式的堆疊,使程式轉而執行其它指令,以達到攻擊的目的。造成緩衝區溢位的原因是程式中沒有仔細檢查使用者輸入的引數。

拿個簡單的c/c++程式引入:

int main()

char name[10];

scanf("%s", name);

printf("輸入的是:%s\n", name);

system("pause");

return 0;

環境:win10+vs2013+vc6.0+od

實驗前關一下安全檢測。

先不說問題存在哪,編譯完我們直接執行。

我們連續輸入了9個字元後程式是正常執行流程的,最後列印出來了。

可當我們連續輸入11個字元後。

崩潰了。。。

我們知道scanf()當沒有對name進行長度檢驗的時候就會造成陣列溢位。

對程式下個斷點後跑起來看看問題。

在除錯前,建議大家把異常處理的忽略都關掉。

關掉後所有的錯誤都可以看到了,方便我們知道**的異常提示。

當call之後呢008f1bc8會被壓入堆疊,再call之後008f1bcd也會被壓入進去。

原因是當call執行完呼叫的函式後,eip指標能夠返回到call指令的下一跳執行的指令位址了。但是原來的返回ret eip位址被改了。

跟進main函式入口。

push ebp

mov ebp,esp

sub esp,0d4h

經典的main入口彙編**。

雖然偵錯程式不一樣彙編**也有區別,但結果是一樣的。

執行完後的樣子

套個此生大牛的圖就是這樣的,最原理的圖。

此圖讓剛入門的朋友更好理解。

不好意思,拿錯了。

上圖流程就是我們從scanf()讀取輸入的資料寫入到name的位址中,但是分配的只有10,超過10後的字元將被寫入到函式執行完後的eip位址(ret eip)

也就是說把正常程式執行的流程給覆蓋掉了,來張比較形象一些的圖。

攻擊**這裡所說的就是shell code的,通過上圖我們可以知道ret eip的位址了,也就是name+14的位址。

為了可觀一些我把該**轉用vc6.0編譯。

程式提示了616161就是a

我們的輸入的a把ret eip位址給覆蓋掉了,作業系統不明白aaaa是啥玩意兒,所以程式提示了不能讀。當程式發生異常後會優先發給偵錯程式,偵錯程式就中斷了。

斷在了異常處理函式

這裡不用管他了,我們使用windbg來找ret eip 的位址。

0012ff7d就是我們要的位址了,這裡我的作業系統並沒有kernel棧隨機化。

總結:在整個溢位過程中申明了空間,但是所操作的資料超過了buff空間,也就是操作越界,覆蓋了棧中的ret eip單元資料,把main函式的返回位址改了,這樣以來main操作結束後返回的就是這個位址作為返回位址執行。

可在實際情況中是沒有原始碼的,我們還需要對buff寫入多長後會發生溢位等進行逆向分析動態除錯,還需要考慮程式流及shellcode空間的存放(shellcode本質上就是一段機器碼)等以及aslr,以上所涉及知識也是最簡單同時最為核心的。

參考資料:

緩衝區溢位

緩衝區溢位是指當電腦程式向緩衝區內填充的資料位數超過了緩衝區本身的容量。溢位的資料覆蓋在合法資料上。理想情況是,程式檢查資料長度並且不允許輸入超過緩衝區長度的字串。但是絕大多數程式都會假設資料長度總是與所分配的儲存空間相匹配,這就為緩衝區溢位埋下隱患。作業系統所使用的緩衝區又被稱為堆疊,在各個操作程...

緩衝區溢位

緩衝區溢位,簡單的說就是計算機對接收的輸入資料沒有進行有效的檢測 理想的情況是程式檢查資料長度並不允許輸入超過緩衝區長度的字元 向緩衝區內填充資料時超過了緩衝區本身的容量,而導致資料溢位到被分配空間之外的記憶體空間,使得溢位的資料覆蓋了其他記憶體空間的資料。通過往程式的緩衝區寫超出其長度的內容,造成...

緩衝區溢位 棧溢位

1 緩衝區概念 緩衝區 buffer 又稱為快取,它是記憶體空間的一部分。也就是說,在記憶體空間中預留了一定的儲存空間,這些儲存空間用來緩衝輸入或輸出的資料,這部分預留的空間就叫做緩衝區。使用緩衝區有兩個好處 1 減少實際物理讀寫次數 2 緩衝區在建立時就被分配記憶體,這塊記憶體區域一直被重用,可以...