1. 程式人生 > 其它 >BBUCTF-ciscn_2019_es_2(一道題淺析棧遷移)

BBUCTF-ciscn_2019_es_2(一道題淺析棧遷移)

在遇到棧遷移前,我其實對棧的理解處於一個十分粗淺的境界,彷彿一片未經開墾的荒地。作一篇以記錄我的理解過程。
在之前的學習,我們可以通過棧遷移來讓函式返回到我們想要去的地址進而達到我們的目的,但是,如果我們覆蓋的空間有限,甚至除了垃圾資料我們只能填入函式地址和返回地址時,就可以採取棧遷移這一手法。
附上我覺得容易理解且講解清楚的連結https://bbs.pediy.com/thread-258030.htm
https://bbs.pediy.com/thread-266927.htm
棧遷移主要用的就是利用 leave;ret; 這樣的 gadgets。leave相當於 move exp,ebp(把ebp賦給esp);ret相當於pop eip(將esp指向的地址存放的值賦值給eip並且執行)。程式呼叫完成 call 返回的時候就會有這樣的指令mov esp,ebp;pop ebp;ret 如果之前我們通過棧溢位將ebp改成了我們想要遷移的地址即bss段,這時執行完pop ebp;之後就會使得ebp指向bss段的地址。之後執行ret指令也就是pop eip;如果我們之前把這裡的返回地址改成leave_ret這個gadget的話那麼他又會執行上面我說的這些過程leave指令會導致esp指向bss段也就是剛剛ebp所指的地址。然後ebp會被改成指向新的一個給定的地址,同時esp也會指向target function(一般為system函式,因為要取得控制權嘛)
再執行 ret 指令,這時候程式就會執行 target function。總的來說,我們用了很短的長度,可以成功構造一個完整長度的rop。
回到題目
check一下

ida檢視,emmvul函式有點東西

s的長度時0x28,但是兩次read可以進去0x30,但是實在是長度太短了,只夠我們覆蓋ebp和返回地址的值。存在system函式,但是引數不是/bin/sh,我們也無法棧溢位更改返回地址的同時填入引數,現在就試試棧遷移的舞臺了。
1.找到ebp和buf在棧上的位置
printf函式在輸出的時候遇到’\0‘會停止,如果我們將引數s全部填滿,這樣就沒法在末尾補上’\0‘,那樣就會將ebp連帶著輸出
之後我們輸入bbbb,然後看一下棧的情況,找到偏移
2.構造payload劫持棧
找一下leave指令

棧的執行情況



第二次執行後ebp裡面是aaaa,esp指向system的地址,成功執行system函式。多說一句那個ebp-0x28那裡的意思是在那個位置寫入/bin/sh
我們寫入的payload完成了他的使命!
附上payload和執行結果

多說一句廢話,我現在還不會除錯還有救嗎?