整份報告是介紹什麼是 TCache ,並從 glibc 2.26 的 source code 觀察,從中看問題並延伸到針對 TCache 上面的攻擊,然後一一介紹這樣
===================================
那 TCache 是一個優化機制,用來增進記憶體的效能,具體更新是在 glibc 2.26
以 Ubuntu 版本來看要到 Ubuntu 17.10 後才會有,那以往常見 CTF 都是把 Pwn 題
放在 Ubuntu 16.04 上就不會有這個機制,因為 Ubuntu 16.04 的版本是 glibc 2.24
---
那這個優化機制具體有增加兩個結構,
第一個是 tcache_entry ,可以把它看成 fastbin ,基本都差不多,像是單鏈表啦和 FILO
不過有一個主要的差別在於,fastbin 的 fd 指向 chunk header ,但 tcache_entry 的
next pointer 指向的是 user data ,就是位址上面會差 0x10
那另一個結構是 tcache_perthread_struct,他是用來管理整個 TCache 的結構
從 source code 可以看到它裡面有兩個陣列,一個是 counts ,他用來紀錄當前 entries
裡面存了幾個 chunk ,另一個是 entries ,預設有 64 個。
其實從這邊可以看到 TCache 的優化機制的作法,就是對 64 個不同大小的 size 的 chunk
為他們做 cache ,預設做多每個 size 緩存 7 個 chunk
---
那因為他新增了新的結構,所以就要有新的操作,具體增加兩個函數
第一個是 tcache_get ,可以看成是用在 tcache 裡面的 malloc
另一個是 tcache_put ,可以看成是用在 tcache 裡面的 free
那這邊簡單介紹完 TCache ,就要去想一下怎麼攻擊這個新機制
TCache 是一個優化機制,那他的具體作法是在 malloc 和 free 的前面插入一段 code
如果 size 滿足的話就優先使用 TCache ,然後他就不會使用本來的 malloc 和 free 的 code
換句話說就是本來的 heap 上面的保護都不會使用到,而 TCache 的優化上的操作,也就是
tcache_get 和 tcache_put 是不帶保護的,換句話說就是 TCache 根本沒啥保護
所以就要開始思考什麼時候會用 TCache
---
使用到 TCache 的情況可以簡單分兩種:
- 什麼時候會把 chunk 從 TCache 中取出來
- 什麼時候會把 chunk 放到 TCache 中
那首先來看什麼時候會把 chunk 從 TCache 中取出來:
就是只要你 malloc 的 size 是 fastbin / smallbin 的,都會優先從 TCache 中取
那再來看什麼時候會把 chunk 放到 TCache 中:
- free 時,只要 size 是 fastbin / smallbin 的,會優先放到 TCache 中
- 如果 malloc 是從 fastbin/ smallbin 中取,那他會同時檢查底下有沒有其他的 chunk ,有的話會一併補到 TCache 中
那這邊順便講個題外話,就是程式剛開始執行,要先隨便做一次 malloc ,因為首次 malloc
會對 TCache 初始化,他會在 heap 段開一個空間來放 TCache_perthread_struct 並用其來管理
整個 TCache
---
上面是快速介紹完 TCache ,那這邊再來看 source code ,了解一下的內部是怎麼處理
這邊會看的是 malloc 和 free
首先看一下 malloc 的 source code,我們呼叫 malloc 具體是 call __libc_malloc()
可以看到他一開始會先判斷可不可以用 TCache
可以的話就直接使用 tcache_get ,然後直接回傳給使用者而不會往下執行
而如果不使用 TCache 的話,應該是會執行到下面的 __int_malloc() ,然後進去處理
所以以往的安全保護基本都是寫在 __int_malloc() 裡面,但如果用了 TCache 就不會走進來
換句話說就是以前的保護根本不會使用到,而 tcache_get 裡面的程式碼也沒帶保護
也就是 malloc 時,如果是用 TCache 就等於完全沒有任何的保護。
那這邊看完後,看一下 free ,基本其實就跟 malloc 情況一樣,但唯一一個差別在於
free 在判斷可不可以使用 TCache 前面,他還是有兩行程式碼,具體是檢查 size & ptr
是不是合法的和需要對齊這些,這檢查其實蠻弱的,然後之後如果可以使用 TCache 的話
也是直接進去 tcache_put 做處理,一樣就是她不會使用到以往 free 有的保護機制,而
tcache_put 也沒保護,所以 free 上面的保護就只有最一開始那兩行的檢查而已
---
那前面看完 src code 後,可以從這邊延伸出他會有哪些攻擊,或者說他會對以前就有
的攻擊又造成什麼樣的影響,我這邊介紹五個:
- tcache poison
- house of spirit
- overlapping chunk
- smallbin filling bck write
- tcache perthread corruption
那首先來看 tcache posion
其實他就是 fastbin corruption ,我們都知道 fastbin corruption 是如果可控 fd
則可以在下下次 malloc 時,取得任意記憶體位置,而這攻擊則是你控 next pointer
達到下下次 malloc 取得任意記憶體位置,只是因為 tcache 保護基本都沒有的關係
所以以往 free 時要繞過 double free 偵測,這已經不用了,
然後以往 malloc 時要偽造 chunk 結構也不再需要了,然後本來 fastbin corruption 僅侷限在
fastbin 上面,那因為 TCache 的範圍包含有 smallbin ,所以這攻擊也擴展到 smallbin 上面
那下一個來看 house of spirit ,這攻擊在 2005 年被提出來,簡單講攻擊方式是,如果今天
你可以偽造一個 chunk ,而且這個 chunk size 必須是 fastbin 的,然後你還要偽造 next chunk
的 prev_size 和 size ,然後你還要想辦法 free 掉你偽造的 chunk ,這樣在下次 malloc 可以取得
偽造 chunk 的地址,這整個過程在現代的保護下要做到其實還蠻難的,首先因為 TCache 把
保護都拔掉的關係,所以就也沒啥要繞過的,就只需要偽造一個 chunk 然後 free 掉後做
malloc 就好,那這攻擊本來僅能用在 fastbin 上面,現在也可以用到 smallbin 上面了
那下一個來看 overlapping chunk ,這攻擊在 heap 裡面算是很常見的攻擊,具體做法是
如果今天存在兩個相鄰的 chunk ,那你如果可以改掉第一個 chunk size 並改大,這樣你在
free 掉她,然後再次 malloc 一個你偽造 size 的 chunk ,這樣你就可以取得相同的位址,但
因為 size 變大的關係,所以整個 chunk 涵蓋範圍也變大,就可以包含有第二個 chunk 造成
overlapping ,這樣就可以去改第二個 chunk 這樣,那一樣在 TCache 把保護都拔掉下,使用
上會更為簡單和容易。
那下一個來看 smallbin filling bck write ,當你在 malloc 時,如果你取得的 chunk 是從 smallbin
裡面拿到的話,他會同時檢查底下還有沒有其他空閒的 chunk ,有的話會直接把他們補到
TCache 中,然後這個過程會觸發 unlink ,但這邊的 unlink 是最原始的 unlink ,也就是跟
unsorted bin 上面的 unlink 是一樣的,所以可以做到跟 unsorted bin attack 一樣的效果。
那最後一個是 tcache perthread corruption ,就是前面有說 tcache_perthread_struct 這個結構
管理了整個 TCache ,那你可以利用任意漏洞來控任意記憶體位置,那如果你把你要控制的
記憶體位置設為 tcache_perthread_struct 的話,你就可以去控制整個 TCache ,那就可以做到
任何你想要做的事情,比如 malloc 任何大小的 chunk 都要用 TCache 。
---
那最後總結就是 TCahce 讓 heap exploitation 變得更為簡單了 ~
沒有留言:
張貼留言