Pwn Heap Intro


  • 在 OS 中有學過,一個程式的變數,如果是一般的宣告變數會被放在 stack 中,而動態宣告的變數則會存放在 heap
  • heap 的 allocator 在不同 OS 或是 libc 中有不同的處理,以下是針對 glibc 的 ptmalloc 解釋

  • 宣告變數時,根據你請求的空間大小不同,會有不同的機制去處理
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • <128KB 會從 heap 拿空間
      • 空間不夠時使用 sys_brk 擴增區域
    • >=128KB 會從 mmap 拿空間
  • 一些相關的專有名詞
    • Arena
      • 管理 Heap 的資料結構
      • 通常 1 個 Thread 只有一個 Arena
    • Heap
      • 連續的記憶體空間
      • 一個 Heap 只會存在一個 Arena 中
    • Chunk
      • 分配給程式的記憶體
      • 一個 Heap 會有一堆 Chunk

Chunk

  • 可分成三種類型
    • in-use
    • free
    • top
      • heap 最後未使用的區域
  • 對齊 0x10,即使你要的空間不到也會補齊
  • Header
    • 前一個 Chunk 的 Size
    • 自己的 Size
      • 由於 Size 一定是 0x10 的倍數,後面 4bits 根本用不到,所以其中三個被拿去下面的用途
    • A: 是否在 main arena 裡面
      • 這邊只討論 single thread,所以假設都是 0
    • M: 是 mapp 出來的還是 heap
      • 這邊只討論 heap,所以假設都是 0
    • P: 前一個 chunk 是否被使用
      • top chunk 一定是 1,因為如果是 0 top chunk 就會跟前一個合併
  • Data 就接在 Header 後面

free

  • free 一個 chunk 之後,該 chunk 的 Data 區段會變成放
    • fd
    • bk
      • fd 和 bk 就是雙向 linked list 的兩個指標,用於回收桶 bin 中
  • 將下一個 chunk 的 header 中寫下 prev size 方便回收
  • 並且將 P 欄位改成 0,表示該 chunk 沒在用了

  • bin 分為五種
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • tcache 和 fast bin 其實只是 single linked-list,因此只有 fd 在使用,bk 作為其他用途
    • 一個 Thread 只有一個 tcache
    • unsorted bin 像是 small bin 和 large bin 的暫存空間
  • Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

GEF Commands

  • 在 CTF 實戰中,常常需要在 GDB 中印出 heap 資料來驗證想法
  • 在原生的 GDB 中沒辦法直接看到這些資訊
  • 裝了 GEF 插件後,使用 heap 就會提示能夠印出那些資料
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
  • 一個 Chunk 的例子
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
    • 第一個 0x190 為保留給 tcache 的空間
    • 我另外要了 0x10 0x10 0x10 0x20 等四個空間
    • 剩下的就是 Arena 的剩餘空間

UAF

  • Free 後如果沒有將 pointer 清空,可能造成不可預期的錯誤
  • 範例
...
b = malloc(0x10);
free(b);
*b = (long)&buf;
long* c = malloc(0x10);
long* d = malloc(0x10);
  • 假設本來就有一個 chunk A 位於 tcache 之中,我們 free 掉 b 之後,長這樣
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
  • b 又繼續被使用,而 fd 位於 chunk 的 data 區段,因此 fb 被指向了 buf 的位址
    • Image Not Showing Possible Reasons
      • The image was uploaded to a note which you don't have access to
      • The note which the image was originally uploaded to has been deleted
      Learn More →
  • 而我們 allocate 新的空間時,(如果條件是 tcache)是從 tcache 的 linked-list 依序抓進來
    • c 會拿到 b 的 chunk
    • d 則是拿到 buf 的位址