聊聊glibc 2.32 malloc新增的保護機制-Safe Linking
2020-07-22 18:33:19 Author: medium.com(查看原文) 阅读量:19 收藏

berming

Check Point的研究員@Eyal Itkin在今年向glibc提交了一個commit-其中針對malloc中的single-linked list結構(fastbin / tcache)設計了一種機制「Safe Linking」,很大程度上提升了heap結構的安全性,拉高了所有針對fastbin/tcache攻擊的難度,主要遏止了以下的手法:

  • 覆寫partial/full pointer
  • 偽造unaligned chunks

TL;DR

fastbin/tcache上的fd/next指標會先和heap ASLR random bytes做XOR後才儲存。

pointer XOR encoding

首先先把glibc 2.31 & 2.32拿來diff一下,開頭就看到了一段針對Safe-Linking新增的說明。

也就是說,現在fastbin/tcache上面的fd/next指標,會和和heap ASLR random bytes做XOR encoding,舉個例子

假設P為0x0000BA9876543210,而heap基底位址為0x0000BA9876543000
先做shift取得heap base random的部分:0x0000000BA9876543

最後得到0x0000BA93DFD35753。

看完上述例子會發現攻擊者如果沒有洩漏出heap ASLR的話,就不能將pointer改寫為想控制的值,算是很大程度提升攻擊的難度。

memory address aligned check

但到目前為止雖然能防止攻擊者,但我們自己同樣也不曉得這個pointer是否有被改寫過,這時候額外的aligned check機制就被引入了。

平常由於記憶體位址對齊的關係,chunk address的LSB都是0,但經過XOR之後就不是這樣了,0x0~0xf都有可能,但總歸最後XOR解碼回去時必須要是0才合理,所以這時額外引入對齊檢查機制,這導致了攻擊者:

  • 攻擊者不能再把偽造的chunk放在unaligned memory address(例如常見的改malloc hook, free hook)
  • 攻擊者必須要知道alignment byte (LSB),以前沒有XOR都是0、現在除非先leak不然只有1/16的機率能猜對。

Safe Linking作者用一個簡單對齊檢查就解決了很多問題,真的厲害。

tcache

  • 放進去(tcache_put)時先做encoding(PROTECT_PTR)
  • 拿出來(tcache_get)時做檢查(aligned_OK)

malloc

先檢查一下fastbin開頭

malloc(): 檢查fast開頭

再來要把chunk挑出來的時候也順便檢查

malloc(): 挑出可用chunk時邊檢查

最後最近用過的fastbin會被丟進tcache裡做快取,這時候把fastbin chunk拿到tcache時也會檢查。

malloc(): stash進tcache時檢查

free

當tcache偵測到double free的時候會順便檢查

free(): 檢查double free時順便檢查

首先,要記住一點是Safe Linking只保護next/fd指標,代表HEAD仍然可以利用。不過fastbin HEAD因為遠在libc裡面而不在heap上,所以重點放在tcache上。

由於所謂的tcache HEAD儲存在TPS(tcache_perthread_struct)裡面,而TPS結構位於heap,這就讓攻擊者還有機會做exploit,這時有兩種情境。

UAF (use-after-free)

複習一下,由於tcache為了消弭double free攻擊,chunk free掉之後會在chunk某欄位放上TPS位址(key),所以要丟進tcache之前檢查一下如果有這東西就代表double free發生(先不聊edge case),有點像是會場在手上蓋出入場印章的感覺(?。

But這個機制換句話說,就是讓攻擊者有免費方法可以生出沒有XOR過的heap address在chunk上,這時候配上UAF就有可能可以做exploit。

但由於key欄位記憶體位址前面放的是XOR過的next欄位,改到他就會觸發檢查機制,所以這個UAF必須稍微刁鑽一點,要能夠繞過前面存放next指標。

Underflow / Negative-relative-offset overwrite

這個就很直觀了,因為TPS位於heap前方,所以如果能夠直接往前覆寫到TPS結構體內的東西、例如index[-1]這類,就有很多操作空間了,但實際上面臨兩個問題:

  • underflow發生的頻率比overflow少很多
  • 在現實環境中(heap高度使用、比較雜亂)你不曉得到底TPS距離你多遠

有關於針對TPS的exploit

由於上述提到的攻擊都是針對TPS結構,為此我找到了作者在reddit討論串給出的想法。

作者也認為整個tcache上的設計是導致這些攻擊仍然存在的原因,他也再次強調Safe-Linking是針對”next”指標做保護,意旨在阻擋攻擊者:

  • heap上的線性buffer overflow/underflow
  • 相對位移的overwrite

關於encoding

如果稍微知道Windows NT Heap的機制就會知道,Windows使用了一個獨立的cookie來對heap entry做編碼,基於這項事實我向作者提問:

答案並不讓人意外,仍然是效能與實作的考量。

關於他牌malloc

有趣的是,作者也將這套Safe Linking保護機制發了PR提交給了google牌的tcmalloc,但遺憾的是google以效能考量reject掉了。

  1. Glibc 2.32以後要打fastbin/tcache需要先leak heap ASLR
  2. 但在特定狀況下可以針對TPS做攻擊而無需leak heap ASLR

文章来源: https://medium.com/@ktecv2000/%E8%81%8A%E8%81%8Aglibc-2-32-malloc%E6%96%B0%E5%A2%9E%E7%9A%84%E4%BF%9D%E8%AD%B7%E6%A9%9F%E5%88%B6-safe-linking-9fb763466773?source=rss-eb87faee21ca------2
如有侵权请联系:admin#unsafe.sh