bufbomb-緩沖區溢出攻擊實驗


緩沖區溢出攻擊

一、實驗目的:
加深對IA-32函數調用規則和棧幀結構的理解

二、實驗要求:

構造5個攻擊字符串,對目標程序實施緩沖區溢出攻擊。

5次攻擊難度遞增,分別命名為

Smoke    (讓目標程序調用smoke函數)

Fizz         (讓目標程序使用特定參數調用Fizz函數)

Bang       (讓目標程序調用Bang函數,並篡改全局變量)

Boom     (無感攻擊,並傳遞有效返回值)

Nitro      (棧幀地址變化時的有效攻擊)

需要調用的函數均在目標程序中存在

三、實驗內容:

getbuf函數:存在緩沖區溢出漏洞,buf只有0x28字節長度。

 

棧:

 

 

Smoke

任務是讓目標程序調用smoke函數,觀察這個棧,要想調用smoke函數就要把smoke函數的地址放到getbuf上面的返回地址處。

找到smoke函數的地址:0x8048c28

 

接下來,只要構造0x28+4+4=48字節長度的字節碼就可以將返回地址覆蓋,最后四個字節的內容放smoke函數的地址保證返回地址是被smoke函數的地址覆蓋,因為是小端存儲,也就是:28 8c 04 08,前面放一些00湊出44個字節。

 

用管道輸入,通過hex2raw之后輸入bufbomb程序。成功:

      

 

Fizz:

構造攻擊字串造成緩沖區溢出,使目標程序調用fizz函數,並將cookie值作為參數傳遞給fizz函數,使fizz函數中的判斷成功,需仔細考慮將cookie放置在棧中什么位置。

先找到cookie值:每次運行之后,都有cookie,所以cookie值可以確定是:0x4bbafd61。小段存儲:61 fd ba 4b

然后就是把這個值作為參數給fizz函數。觀察棧發現,參數是放到了返回地址的上面,並且和返回地址相鄰。先用fizz函數地址覆蓋掉返回地址,可以執行fizz函數,並且要將fizz函數的返回地址覆蓋掉,並用cookie覆蓋掉上面的參數。這樣就可以跳轉到fizz函數,並且在跳轉后自己取到cookie作為參數,fizz函數的返回地址就用00 00 00 00覆蓋掉。

Fizz函數的地址:0x08048c52 即( 52 8c 04 08

 

拼好后的樣子:

 

成功:  

    

 

  Bang:

  要求更改全局變量

  要自己寫一個惡意代碼,更改全局變量,賦值為cookie,更改完還要轉到bang函數繼續執行。

  先找到全局變量的位置:在bang函數里看到有兩個內存地址,正好和源程序里的判斷相等對應,接下來確定哪一個是全局變量。

    

 

    用gdb調試,在getbuf函數設斷點,運行,查看一下兩個地址的值,很明顯,0x804d100是全局變量。

    

 

    Mov指令賦值,之后要跳轉到bang函數——將0x08048cad壓棧,結合起來就是這樣:

    

 

    然后用gcc –m32 –c 編譯成.o可重定位目標文件,然后objdump –d 反編譯出機器碼。如如:

    

 

    這是惡意代碼,我們需要的是這些16進制的機器碼,我把它們放到buf區域里,然后執行就ok。

    要執行這些代碼就需要讓控制流可以跳到這,只要把這段惡意代碼的首地址放到getbuf函數的返回地址處就可以了,也就是buf緩沖區的首地址放到返回地址。接下來找buf緩沖區的首地址:

    看一下getbuf函數,發現,在圖中0x80491f7處,ebp減小 開辟了一段空間,也就是buf區域,eax寄存器中放的就是該空間的首地址,即buf首地址。

    

 

    用gdb調試,在下一行設置斷點,查看eax的值:

      

 

    也就是 38 35 68 55

    拼好的字節碼是:

    

 

    還是管道輸入。

    成功:

    

 

  Boom:

  要求被攻擊程序能返回到原調用函數test繼續執行——即調用函數感覺不到攻擊行為。也就是要恢復ebp的值。

  另外,構造攻擊字符串,使得getbuf都能將正確的cookie值返回給test函數,而不是返回值1

  設置返回值也就是更改eax的值,可以用mov指令設置eax存的為cookie值。

  更改完要進入test函數繼續執行下面的指令,也就是下圖中這個位置,將這個地址壓棧。

  

 

  綜合起來,代碼為:

  

 

  用同bang那關一樣的方法,得到字節碼:

  

 

  惡意代碼准備好了,將返回地址更改為指向這個代碼的位置,把惡意代碼放到buf緩沖區內,返回地址和bang一樣。

  接下來要恢復ebp的值,先得到ebp舊值。

  Gdb調試:在getbuf第一行,push ebp 設置斷點。查看ebp的值。

  

 

  ebp=0x55683590,即90 35 68 55

  用這個值覆蓋ebp值。ebp值在返回地址的低方位,放在返回地址前。

  綜合如下:

  

 

    同樣,管道輸入。

  成功: 

    

 

    Nitro:

    構造攻擊字符串使getbufn函數(注,在kaboom階段,bufbomb將調用testn函數和getbufn函數),返回cookie值至testn函數,而不是返回值1

    需要將cookie值設為函數返回值,復原被破壞的棧幀結構,並正確地返回到testn函數。

 

    這里和上一個的不同之處在於地址空間隨機化。還有這是在testn函數和getbufn函數里。

    

 

  ebp是隨機的,但是ebp相對esp是絕對的,根據上面的圖中結合棧結構得出

  ebp = esp + 0x24 + 4 = esp + 28

  getbufn函數返回后要從0x8048e4a開始執行,將這個地址壓棧。

  設置cookieeax。

  綜合得出惡意代碼為:

  

 

  轉換為字節碼。

  

 

  getbufn函數:

  

 

  要填入0x208+4+4=528字節。

  因為隨機,不知道程序會跳到哪里,所以把惡意代碼放到最后面,用nop滑行。

  (nop不會執行任何操作,只有PC加一,機器碼是90。)

  所以,前面塞滿90,最后面寫上惡意代碼程序,以及最后要跳的位置。

     尋找要跳的地址:

  由於隨機化,buf首地址不確定。用gdb調試:在0x8049218設斷點,看eax的值。(每執行一次,要用c命令繼續,進而執行下一次)

  例如:

  

    一共5次。

  

 

  

 

  

 

  

 

  

 

  buf首地址的取值范圍在0x55683328~0x556833c8

  取最高地址0x556833c8(c8 33 68 55)作為返回地址,這樣就會一路滑行到惡意代碼,執行惡意代碼。

  綜合上述:

  

 

  同上管道輸入。

  注意:hex2raw也要加-n!

  成功:

  

 

  有問題歡迎留言~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM