假unlink---pwnable.tw記錄之applestore

0x00 程序分析

主要功能函數handler:

create函數malloc一塊16字節的內存,分別存放:char* name,int price,struct * bk ,struct * fd ? ,由insert()函數將當前商品的結構體插入鏈表尾部。鏈表的起始位置記錄在全局變量 myCart(0x0804B068)中。

delete函數進行鏈表的拆卸:

一開始覺得可能是一道uaf加unlink的題,后來發現整個程序沒有出現過free應該是沒有uaf的,delete這里的拆卸動作只是檢查了目標地址必須指向有效的內存,可以利用。

最后是check out函數


0x01 利用點

通過cart函數結算總價,如果為7174就$1領iphone8,簡單的枚舉可以得到湊夠7174的選法。而利用點就在這里,iphone 8 的結構體不是在堆中而是在棧中,也許可以有棧溢出進行覆蓋的機會。

read讀的機制是遇到\x00是不會停止的,也就是說my_read()函數存在棧溢出可以覆蓋到iphone 8的結構體,從而覆蓋fd和bk指針實現DWORD SHOOT!


0x02 leak libc

一開始我用cart作leak libc的工作,也就是將結構體的char * name 指針修改為got表中write函數的地址,這樣打印時就會泄露出write實際的地址從而得到libc的基址

但是如果想繼續覆蓋fd和bk指針,在函數退出時執行到:

棧上本來保存一塊地址的地方被我們輸入的數據覆蓋,導致了內存訪問錯誤。

之后考慮在delete函數中搞事情:

首先泄露libc的原理與之前在cart中一樣,我們可以在read時輸入‘27’+payload,atoi函數進行解析時只會提取出27作為返回值,后面的payload由于不是ascii碼范圍所以不會影響其正常工作。

這里我選擇puts函數的實際加載地址進行泄露:


0x03 DWORD SHOOT

RELRO不是full說明GOT表還是可以修改的,思路是用unlink來修改got表

這里觸發了一個錯誤segment fault

重新分析unlink的過程,發現問題所在:

我們使用了第一次的來把bk寫入fd+0x8,但是同時也應該保證bk+0xc的位置是可寫入的,這里試圖想libc_system的位置寫入產生了錯誤。

參考別人的思路,大概有兩種。

第一種比較巧妙和優雅,也就是將ebp指向的4字節覆蓋為aoti GOT+0x22,這樣在delete函數退出執行到leave的時候,先mov esp ,ebp,再pop ebp的時候就會把atoi+0x22賦給handler的ebp

再重新my_read的時候就會變成向atoi在got表中的地址寫入數據,我們這時候就可以寫入system_addr,并且可以在system地址后面直接綴上’;/bin/bash',這樣等到執行下面的atoi時實際執行的就是system,而參數則是p32(system_addr)+’;/bin/bash’ 這樣截斷bin/bash的姿勢也用了好幾次了,類似的還有&&等方式。

這種方法優點在于巧妙優雅,但是可能相應的適用范圍比較小,所以還學習了一下另一種比較普適的思路,也就是覆蓋ebp然后通過leave來修改函數執行流程

一個簡單的例子是pwnable.kr上面的一道login,建議還是自己調試下跟一遍過程

思路就是用handler里面的nptr的地址覆蓋handler的ebp

這樣在退出handler函數時leave指令把ebp賦給esp,輸入的nptr就變成了棧頂一片內存,把0xdeadbeef pop給ebp后ret時,esp就指向我們的system函數了。

今天做swpu的ctf又被pwn題教育了><還是要繼續學習的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容