【CTF復現002】Libc2.32下的tcache attack

Ch33_1n'
Apr 5, 2021

環境:Libc2.32

漏洞:uaf

方法:double free檢測繞過&IOFILE

Libc2.32新增保護機制

先看看Libc2.31中的tcache_put函數。相比以往的libc版本新增了key值,指向tcache:

再看2020年8月的Libc2.32版本。很明顯 e->next 的值發生了變化,在2.32中通過 PROTECT_PTR 函數給它賦值。

該函數將next的地址右移12位,與 tcache->entries[tc_idx]作異或后返回結果。也就是最終chunk->fd中寫入的值。

相應地,在 tcache_get 中也加上了對應的 REVEAL_PTR 函數,跟加解密過程相似。

在free的時候會對tcache中的chunk進行檢查,檢查完key就檢查next,用的也是 REVEAL_PTR 函數。

如果next指針被我們修改成其他值,運算得到的結果就不相同。但是當tcache中只有1個bin時,tcache->entries[tc_idx]為0,異或結果等於其本身。

復現:ff - V&NCTF2021

程式分析

程式只能show一次,edit兩次。存在uaf漏洞。

圖上的idx是一個全局變量,導致每次只能操作最新malloc的chunk。并且申請的大小限制為0x7f。

libc版本是2.32,tcache新增的保護機制在前面已經提到過。

思路分析

當tcache中只有一個chunk時,將next和key改成任意值就能繞過double free檢測。但是之後tcache中的兩個chunk(實際上是同一個)的next又會被異或。因此需要在double free之前拿到heapbase地址,也就是chunk 0的key。與目標地址異或得到的值,就是chunk 1的next指針異或后正確的值。

爲了獲取這個值已經用了一次show函數:

之後不能再通過show泄露libc地址,但能實現任意地址讀寫(ptr^key寫入fd,劫持tcache)。

程式有調用puts函數,因此可利用_IO_2_1_stdout泄露。由於兩次edit到這一步的時候已經用完,需要在add的時候修改stdout結構躰。

由於爆破的時候需要前面8位的地址作基數,在修改fd之前需要一個放入unsorted bin 的chunk。這裏可以用heapbase,它的size有0x291.

exp

--

--