2011-12-17 25 views
0

我想通過控制堆棧來利用C代碼的漏洞進行教育目的。一個簡單的基於堆棧的緩衝區溢出,用應該執行shellcode的地址覆蓋返回地址。該代碼是一個簡單的函數,它將緩衝區作爲參數,並嘗試將緩衝區設置爲固定大小。從main給出的參數是argv[1]。所以我認爲,如果我找到了必須覆蓋的確切內存量,那麼我可以簡單地給出一個由\x90(NOP指令)組成的字符串,後面跟着shellcode,最後是這個緩衝區的地址。由於這是第一個參數,所以它的地址是$ebp+8,你可以通過運行gdb來找到它,在函數的開頭設置一個斷點,只需輸入i args即可得到作爲參數傳遞的字符串地址。所以我發現如果我覆蓋n字節,然後給出地址的值,那麼這將完全覆蓋返回地址。所以我有這樣的輸入:爲什麼函數參數給出的字符串地址在溢出ret地址後發生了變化?

perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)' 

它沒有工作,我試圖理解爲什麼。用gdb我運行程序。我在strcpy()函數之前放置了一個斷點。在那一點上,我有一個參數,它是一個指向我的輸入的字符串指針,其地址與我的字符串輸入結尾的地址相同,我向前走了1條指令。我檢查了堆棧。我現在保存的eip$ebp + 4)與argv[1]末尾給出的地址的值,這是預期的行爲(這意味着它不會覆蓋ret地址上方的其他地址,即第一個參數的值)。奇怪的是,現在$ebp+8的內容不是「地址」,而是其他內容?但保存的eip的內容是指向我的字符串利用漏洞的地址。但似乎ret addr執行該地址的內容。

+1

當然你也需要知道編譯器在哪裏放置'buf'? – 2011-12-17 12:29:39

+0

爲什麼我需要知道這個地方?這與它的大小有什麼關係? – curious 2011-12-17 12:41:17

+0

因爲您需要知道堆棧上的哪個位置開始寫入。 – 2011-12-17 12:53:56

回答

1

如何組織堆棧框架是ABI的一部分。 Linux在x86-64上使用的ABI的描述是here。你會發現你需要的一切(然後更可能)。有關堆棧幀組織,請參見3.2節。