我想通過控制堆棧來利用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執行該地址的內容。
當然你也需要知道編譯器在哪裏放置'buf'? – 2011-12-17 12:29:39
爲什麼我需要知道這個地方?這與它的大小有什麼關係? – curious 2011-12-17 12:41:17
因爲您需要知道堆棧上的哪個位置開始寫入。 – 2011-12-17 12:53:56