本文的**來自**於《computer systems a programmer's perspective》(深入理解計算機系統》一書中的bufbomb.c作業題。
實驗環境xp+vc6.0。
另:linux2.6+gcc4.x下目前碰到棧保護等措施,暫時還沒研究出結果。
問題描述如下:
分析下面程式,可以得知,正常情況下,這個函式會在getbuf中,調入getxs函式讀入數字對,然後不管任何情況下,
都會對test函式返回0x1,然後由test中的printf函式列印getbuf的返回值。 現在你的任務,就是,利用緩衝區溢位
的漏洞,輸入些特殊的數字,使得螢幕中列印的是0xdeadbeef。
bufbomb.c 源**:
解決方案一:
1,源**在vc的環境下需要額外新增
#include
#include
#include
2,先熟悉getbuf的幀棧結構,大致如下。
+-------------------------------+高位址
|return 返回位址 |
+-------------------------------+
|ebp指標入棧 |
+-------------------------------+
| buf[11] |
+-------------------------------+
3,接著看test的反彙編**。正常情況getbuf()返回後,肯定會接著執行0040116a。由於getbuf返回值0x1儲存在eax
暫存器中,0040116a行**把它賦值給變數val([ebp-4]的位置)。然後把eax壓棧,給後面的printf使用。
4,由此我們可以採用這種溢位方式:使getbuf返回之後能跳到00401171的**,
且test棧幀的棧頂值為deadbeef。這樣後面的printf時就能正常列印deadbeef。
5,那麼,我們就開始構造溢位後的getbuf棧幀,來實現上面說的方法。
4.1 ebp指標入棧:這裡保持不變,不然返回test之後就亂了。我機器上的值是0x0012efa0;
4.3 test棧幀的棧頂值為deadbeef,這個怎麼做? 事實上這種方法要破壞test的棧幀。
研究test的棧幀會發現它在getbuf棧幀的上面,且在getbuf返回時,test棧幀的空餘空間44-4=40h,
所以我們在getbuf執行時把test的棧頂4byte溢位成0xdeadbeef,這樣getbuf返回後會跳到00401171,
此時test棧幀已經符合我們要求了。
00000000 00000000 00000000 a0ef1200 71124000 efbeadde
7,該方案除錯時能列印efbeadde。不過從test**可以看到在呼叫printf之後,「add esp,8」來清空棧(printf用到的引數),而我們這種方式實際上efbeadde不是壓進棧的,所以這裡比原來的棧少4byte空間,這樣會導致後面在檢測esp時會出錯。
解決方案二:
1,源**在vc的環境下需要額外新增
#include
#include
#include
2, 修改getbuf的buf為16bytes,後面會說明為什麼要這麼做。
/* $begin getbuf-c */
int getbuf()
3,先熟悉getbuf的幀棧結構,大致如下。
+-------------------------------+高位址
|return 返回位址 |
+-------------------------------+
|ebp指標入棧 |
+-------------------------------+
| buf[15] |
+-------------------------------+
3,接著看getbuf的反彙編**。我們可以採用這種溢位方式:使getbuf返回之後能跳到buf的位址,buf裡面儲存的**負責儲存0xdeadbeef到eax,然後再跳回到test的**(0x40126a mov dword ptr [ebp-4],eax)。這樣只要溢位getbuf的棧幀
就可以了。
4,那麼,我們就開始構造溢位後的getbuf棧幀,來實現上面說的方法。
4.1 ebp指標入棧:這裡保持不變,不然返回test之後就亂了。我機器上的值是0x0012efa0;
4.3 buf中的12bytes(從buf[0]->buf[11])用來放機器**686a1240 00b8efbe addec390。
這段機器碼等價的彙編如下:
push 0x40126a
movl eax, 0xdeadbeef
retnop
4.4 buf中的12bytes(從buf[12]->buf[15])填充為:00000000。因為vc在我們執行完getxs達到溢位後,再跳到buf的位址之前還會呼叫__chkesp。這個函式很討厭,如果我們的buf為12位元組大小,它又會把我們好不容易構造的棧給破壞掉,所以我們為了實驗目的我們需要修改buf為16位元組,且把buf[12]->buf[15]留給它用。因為我們的溢位**不會用到buf[12]->buf[15]這個空間,就不會對我們有影響了。
5,綜上所述,我們可以輸入:
686a1240 00b8efbe addec390 00000000 a0ef1200 38ef1200
6,該方案能列印efbeadde,且程式能正常執行。
緩衝區溢位
緩衝區溢位是指當電腦程式向緩衝區內填充的資料位數超過了緩衝區本身的容量。溢位的資料覆蓋在合法資料上。理想情況是,程式檢查資料長度並且不允許輸入超過緩衝區長度的字串。但是絕大多數程式都會假設資料長度總是與所分配的儲存空間相匹配,這就為緩衝區溢位埋下隱患。作業系統所使用的緩衝區又被稱為堆疊,在各個操作程...
緩衝區溢位
緩衝區溢位,簡單的說就是計算機對接收的輸入資料沒有進行有效的檢測 理想的情況是程式檢查資料長度並不允許輸入超過緩衝區長度的字元 向緩衝區內填充資料時超過了緩衝區本身的容量,而導致資料溢位到被分配空間之外的記憶體空間,使得溢位的資料覆蓋了其他記憶體空間的資料。通過往程式的緩衝區寫超出其長度的內容,造成...
防禦緩衝區溢位攻擊的策略
了解了緩衝區溢位是如何發生的以後,如何防止黑客利用緩衝區溢位攻擊並控制你的本地應用程式就是乙個很重要的問題了。避免使用編譯器中自帶的庫檔案 程式語言通常都要帶有庫檔案。如果乙個庫檔案具有某些漏洞,任何包括該庫檔案的應用程式就都會有這些漏洞。因此,黑客往往會先試圖利用常用的庫檔案中已知的漏洞來達到攻擊...