iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
1
Security

CTF 的三十道陰影系列 第 18

Day18: [Pwn] Educational Heap Exploitation - part 3

前言

今天會把 Educational Heap Exploitation 做個結尾,另外昨天的例題 plaiddb 做的時間比預期中的長.,加上這兩天難得出門到剛剛才回來......預期明天才會補上內容

Educational Heap Exploitation - part 3

1. house_of_lore.c

  • 這篇提到的 House of Lore 是進階版,跟最原始 Malloc Maleficarum 提出的 House of Lore 不同
    • Malloc Maleficarum 是在 2005 年提出,當時只要修改掉 freed chunk 的 bk 就可以在下兩次 malloc 得到任意 address,可以在 smallbin 和 largebin 使用
    • 但隨著加入 circular check 和一些保護機制之後,當時的手法已經不能使用
  • 現在的利用方式限制條件較多,需要以下條件以 bypass circular check:
    1. 要已知 libc 內 smallbin 的 address 和 heap 的 address
    2. 需要先能寫入目標 address 的內容,在上面偽造完整的 chunk,包含 header, fd 和 bk
    3. 需要利用 UAF 或 bof 將在 smallbin 內 freed chunk 的 fd 和 bk 指到偽造的 chunk 上
  • 範例 code 存在 UAF 的漏洞,並且直接取得 smallbin 的 address 放到偽造的 stack chunk 上
    • stack_buffer_1[2] = victim_chunk;

2. house_of_force.c

  • Malloc Maleficarum 在 2005 提出的利用方式之一,一直到 glibc 2.29 2019 年才被修正 XD
  • 利用條件有兩點:
    1. 要能 overflow 將 top chunk 的 size 改成一個很大的值
    2. 要已知 top chunk 的位置
    3. 要能在 malloc 時參數要能是任意大小
  • 原理為將 top chunk size 改大,避免 ptmalloc 觸發 mmap之後,我們可以在 malloc 時給很大的數字 nb (nb 要小於 top chunk 被篡改的 size),在這計算下一次 top chunk 的位置會是用 old top + nb + 8 去計算,因此我們可以把 top chunk 調整到任意的 buffer 上,下一次就可以拿到任意位置
  • 2.29 對 top chunk 的 size 加入檢查,如果是一個不合理的數字會直接 abort,因此目前已經無法使用
  • 範例 code 直接存取 top chunk 改掉 size,通常的情境會是用 bof 改 top chunk

3. house_of_einherjar.c

  • 算是 Poison Null Byte 的變形應用,透過 null byte off-by-one 蓋成 \x00 的特性來取消 chunk 的 PREV_INUSE,讓觸發 chunk 對上一塊 merge & unlink

    • 但比起 Poison Null Byte 的利用,多了需要已知 heap address 的前提條件
  • chunk 對上一塊 merge & unlink 時,會根據 prev_size 尋找上一塊 chunk 的位置

  • chunk 的 prev_size 會在記憶體的前一塊 chunk 視為 data 使用,而且 free 完之後不會清掉 heap data,因此可以留資料偽造 prev_size 讓 unlink 跟記憶體前一塊 chunk 做 unlink,這樣下次 malloc 就會把前面的 chunk 當 unsorted bin 來使用

    • prev_size 可以給很大的數字,讓他在找前一個 chunk 時發生 int overflow,這樣就可以對任意位置的 chunk 做 unlink
    • 偽造的 chunk 要能偽造 fd 和 bk 才能在 unlink 時 bypass circular check
  • 文件上寫可利用版本是 < 2.26,但避開觸發 tcache 之後應該還是能使用

  • 範例 code 利用 off-by-one 改掉 PREV_INUSE,也是真實漏洞常見的寫法

    • a[real_a_size] = 0;

4. house_of_orange.c

5. tcache_dup.c

  • 由於 tcache 對 chunk 的檢查非常不嚴謹,可以連續 free 兩次同一個 chunk,接下來兩次 malloc 就會拿到還在 freed list 的 chunk,造成 UAF 的問題
  • 2.29 已經在 free 時加入檢查機制,會遍歷所有 tcache 確認 chunk 不在 tcache linked list 裡面
  • 範例 code 存在 double free 的漏洞

6. tcache_poisoning.c

  • 類似 fastbin corruption attack 但更簡單,甚至不需要偽造 chunk header
  • 先 free 一塊 chunk 進 tcache 後,接著修改 chunk 的 fd,就可以在接下來的兩次 malloc 取得任意記憶體位置
  • 可以在最新版的 glibc 中利用
  • 範例 code 存在 UAF 的漏洞,如果前一塊記憶體上的 chunk 有 bof 的問題也可以利用此方式

7. tcache_house_of_spirit.c

  • 原理跟 House of Spirit 相同,但不是用在 fastbin 而是 tcache 上,由於 tcache 的檢查更少,甚至不需要偽造 next chunk
  • 在任意 segment 上偽造 chunk 之後丟進 freed list,之後 malloc 就會拿到偽造的 chunk
  • 可以在最新版的 glibc 中利用
  • 範例 code 存在 free 任意 chunk 的漏洞,如果前一塊記憶體上的 chunk 有 bof 的問題也可以利用此方式

0x11: SECCON CTF 2016 Exp300 tinypad

這題是考 House of Einherjar,會當成今天的例題是是因為 House of Einherjar 兩點原因:

  1. Malloc Maleficarum 之後第一個取名為 house of xxxx 的 heap 攻擊手法
    • House of Orange 只是 unsorted bin attack 的新用法,不完全是 heap 攻擊手法
    • 雖然 House of Einherja 也不算完全創新就是......
  2. 第一次有 CTFer 把 heap exploit skill 投稿到正式的 security conference 上

又是 heap 標準的選單題,除了 PIE 以外保護全開,程式有 create, delete, edit 三個功能

  • create 有個限制是同時只能存在 4 個 chunk,chunk 會存在 bss 上的 ptr array
  • 沒有 show 但每次操作前都會把所有的 create 的 heap 內容印出來
  • delete 的時候沒有清空 ptr,存在 UAF
  • edit 的部分會用 strcpy 從 bss 上的 buffer 複製 data 到 heap 上,存在 off-by-one 的漏洞

因為 delete 實際上不會清空 ptr,因此即使 delete 掉之後還是會印出 heap 上的 data,我們可以藉由 create 時分配 smallbin 和 fastbin 的 chunk 來 leak libc 和 heap

接著透過 edit 的 off-by-one 來 overwrite PREV_INUSE,因為可以 edit 多次,所以可以繞過用 strcpy\x00 截斷的問題,然後最後一次 edit 用來在 bss buffer 偽造 chunk,由於沒有開 PIE,因此可以簡單把 fd 和 bk 都設成自己來避開 circular check

最後 delete 掉 off-by-one 改掉的 chunk 觸發 unlink,unsorted bin 中就會多出剛才偽造在 bss 段上的 chunk,下次 malloc 就可以取得 bss 上的 buffer,並覆蓋掉其他 create 出來的指標,後續就能達成任意讀和任意寫入

  • 這邊還有個限制是,如果 unlink 完在 unsorted bin 的 chunk size 超過 0x21000,會被認為異常 abort 結束程式,印出 malloc(): memory corruption 的訊息,因此這邊要在 edit 一次修改 chunk size 讓他落在合理範圍
  • 這題剛好 edit 可以修改,如果不行,就要撞 ASLR 賭 heap 和 bss 段間隔不超過 0x21000 ...

最後提個兩點,這題無法用 unlink 的方式解的原因是,因為程式本身 edit 時能讀寫的長度取決於目前 strlen 的長度,因此 unlink 完將 ptr 變成 &p-0x18 之後就會因為可改的長度不夠無法進行後續利用,會需要從 create 的地方拿到 buffer 才能任意改值

前面提過 House of Einherjar 的原理其實就是 Poison Null Byte 的應用,因此這題其實也可以用 overlap + fastbin attack 解,可以參考原作者的 說明


上一篇
Day17: [Pwn] Educational Heap Exploitation - part 2
下一篇
Day19: [Misc] Balsn & Balsn CTF
系列文
CTF 的三十道陰影31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言