最近越來越排斥在medium上寫很技術性的東西,因為我發現自己點開medium也不想看太艱澀的內容,所以之後會考慮把這類內容移動到其
他地方,接下來進入本篇正題。
TCACHE(per-thread cache)是glibc 2.26約2017年中段才新增的優化技術,該優化能增快malloc速度,具體上是減少了_int_malloc()
的呼叫次數。
/* We overlay this structure on the user-data portion of a chunk when
the chunk is stored in the per-thread cache. */
typedef struct tcache_entry
{
struct tcache_entry *next;
} tcache_entry; /* There is one of these for each thread, which contains the
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */
typedef struct tcache_perthread_struct
{
char counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
static __thread char tcache_shutting_down = 0;
static __thread tcache_perthread_struct *tcache = NULL;
其實結構就和一般的bin差不多,但更像fastbin(FIFO、single linked-list),特別的是這個tcache_perthread_struct
是被分配在heap上的(而不像一般bins位於main_arena
),其中有三個重要的性質要注意:
tcache藉由tcache_put
、tcache_get
把chunk拿進拿出,細節不需要了解,只需要知道這兩個動作都沒有做security check。
前面提到TCACHE減少了_int_malloc()
的呼叫次數,換句話說就是TCACHE chunk不會去呼叫到_int_malloc()
,而大多數的security check卻都位於其中,再者TCACHE chunk本身的operation又不自帶檢查,其結果就是幾乎沒有security check存在。
所以現在要考慮的很簡單-什麼時候 chunk 會被放進 tcache /從 tcache取出?
_int_malloc()
之前,size對了就先從tcache拿。另外tcache chunk還有一個特性是free chunks不做合併,有了這些知識後,就能理解大部分的tcache exploitation了。
The House of Spirit變得更有威力了,原本要通過一些檢查像invalid next size (fast)
,現在不需要了,而以往通常只作用在fast chunk,現在small chunk也可行。
以下是執行結果,輕鬆的做到arbitrary allocation.
The House of Spirit with tcache
There’s no nextsize check (invalid next size (fast))
[Fastbin]
Evil chunk : 0x7ffde7de5a20
Next allocation : 0x7ffde7de5a20
Now it works in small chunk too
[Smallbin]
Evil chunk : 0x7ffde7de59a0
Next allocation : 0x7ffde7de59a0
這就很類似fastbin attack,tcache_entry
中有個next
指標存著下一塊chunk
,跟fast chunk上的fd
差不多,覆寫他達到下下次malloc能夠arbitrary alloc-
ation,不同的是做fastbin attack時會檢查chunk size是否符合bin index,且會做double free check,這些檢查在tcache中都沒有,非常強大。
Corrupt next of tcache_entry, it's simialr to fastbin attack but no size check corresponding to fastbin index need to be satisfied.Evil : 0x7ffff02157b0
1st allocation : 0x561ceee3b670
2nd allocation : 0x7ffff02157b0, content = hack!