Pwn-Fastbin Dup 1(Glibc 2.23)
Author: 堇姬Naup
source code
1 |
|
分析
可以輸入1~5,分別對應
1 | void menu() |
create() -> 1
malloc一個chunk,並可以指定一個size
並且把東西存到這三個global variable
1 | char *g_ptrs[0x20]; |
get() -> 2
先確認該chunk存不存在,以及是否是allocated,你可以指定index,然後給你他的內容
set() -> 3
先確認該chunk存不存在,以及是否是allocated
指定index,並可以把內容寫進去chunk裡面
delete -> 4
輸入一個index,若該ptrs存在,則把它free掉,然後把used改成0
1 | if (g_ptrs[idx]) { |
觀察一下這裡,他是去找g_ptrs裡面有沒有然後再free掉,但很顯然的g_ptrs就算你free掉了,也不會把它清掉所以就可以double free
並且打這題目前要有一個先備知識,要怎麼leak libc,我們打算透過fastbin dup來改malloc_hook,那就必須要有libc base,這邊可以用unsorted bin來leak,因為當unsorted bin被free掉時候,fd、bk會指向一個libc address
像是這樣,我先malloc一個
然後free,就可以發現有了
接下來我透過在malloc一次一樣大小的來拿到同一塊,並且fd、bk沒有被清空,用get,就可以把它印出來了
拿offset
1 | >>> 0x72db424aab78-0x72db420e6000 |
目前這樣可以leak libc
1 | from pwn import * |
再來就是要寫malloc hook了,這邊先做一件事,我們先到malloc hook去看看
我們需要bypass一個安全機制,較chunk size要一樣
觀察一下會發現,他有很多0x7c之類的東西
如果能把它當header size(推到header最尾端)就可以bypass
推一下就可以把他推到後面了(malloc hook - 0x33)
所以我們應該跳到(malloc hook - 0x23)
跳到libc base + malloc hook offset - 0x23
bypass
接下來要做fastbin dup
1 | chunk 0 -> 0x440 |
free 1、2
1 | fastbin -> chunk 2 -> chunk 1 |
再free 1
1 | fastbin -> chunk 1 -> chunk 2 -> chunk 1 -> chunk 2 -> ... |
這邊再free 3
1 | fastbin -> chunk 3 -> chunk 1 -> chunk 2 -> chunk 1 -> chunk 2 -> ... |
這邊注意一點,我想把/bin/sh
寫進去到heap裡面,所以我要先leak heap的位置,這邊可以挑1 或 2,都沒差,反正到時候都用不到,我這邊挑chunk 1,因為我把chunk 3 free掉後fd指向chunk 1,所以我malloc回來get就可以拿到了
1 | from pwn import * |
現在fastbin chain
1 | fastbin -> chunk 1 -> chunk 2 -> chunk 1 -> chunk 2 -> ... |
先malloc 1(ptr index 6)
1 | fastbin -> chunk 2 -> chunk 1 -> chunk 2 -> ... |
把chunk 1 寫入 malloc_hook 位置
1 | fastbin -> chunk 2 -> chunk 1 -> malloc_hook |
現在
malloc三次,拿到了
1 | chunk 2(ptr index 7) |
把chunk 1寫入/bin/sh
,/bin/sh
位置就會在chunk 1 address + 0x10
那malloc hook現在到底在哪裡?
1 | header 0x10 |
所以你要先padding,0x13
個a在寫掉malloc hook成system
最後傳入/bin/sh
1 | malloc("/bin/sh") -> (*__malloc_hook)("/bin/sh") -> system("/bin/sh") |
script
1 | from pwn import * |