Pwn-Tcache bin dup Glibc 2.27
基本上跟Fastbin dup很像,但換成了Tcache
Glibc 2.27沒有檢查鍊表上第一個是不是現在要free掉的chunk,所以可以直接連續free兩次chunk不會有問題
另外注意,chunk fd指的是data
如果是glibc 2.28後加入了key會被寫成Tcache相關東西
流程
1 | Chunk 1(malloc) |
free掉chunk 1
1 | Tcache -> Chunk 1 |
再free一次
1 | Tcache -> Chunk 1 -> Chunk 1 -> Chunk 1 -> ... |
malloc拿到chunk 1並改寫fd
1 | Tcache -> Chunk 1 -> Pwn_chunk |
malloc兩次就可以拿到你要寫的東西了
demo
1 |
|
分析
這邊踩了一個坑,就是我們使用的的docker Glibc雖然是2.27,但是2.27保護機制跟裸奔一樣,所以有patch上保護,在2.27-3Ubuntu1.3加入key機制,所以我這邊找了比較舊的libc來patch上
1 | LD: |
首先先觀察一下,會發現這題跟原本很像,主要有兩個不同
第一個是這,這裡有BOF跟partial overwrite
1 | char name[100]; |
第二個不同是,原本的ptr array變成了變數,一次只能操作當前最新malloc的chunk
首先我們先leak libc,蓋0x78個a+一個\n會蓋到stack上的libc前面,printf會把它印出來,之後offset用動態抓扣出來
我們可以看到double free完後他變成了一個指向自己的循環
1 | tcache bin -> chunk 1 -> chunk 1 -> ... |
目前腳本
1 | from pwn import * |
接下來malloc會拿到chunk 1
之後我們先找兩個東西的offset,free hook(0x3ebc30)跟system(0x4f440)
我們把malloc的fd改成free hook,如圖已經改寫成功,所以tcache bin變成
1 | tcache bin -> chunk 1 -> free hook |
create兩次拿到free hook,寫入system,之後直接malloc一塊,把記憶體寫成/bin/sh,這樣就會有一個free(ptr)
,ptr->/bin/sh
1 | free("/bin/sh") -> (*__free_hook)("/bin/sh") -> system("/bin/sh") |
script
1 | from time import * |
備註: 可以加個sleep,這樣就不會送太快導致一些問題