O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

MacOS memory allocator (libmalloc) Exploitation - Chinese Version

MacOS memory allocator (libmalloc) Exploitation - Chinese Version

  • Seja o primeiro a comentar

MacOS memory allocator (libmalloc) Exploitation - Chinese Version

  1. 1. libmalloc exploitation MacOS memory allocator (Chinese version) angelboy@chroot.org @scwuaptx
  2. 2. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  3. 3. OSX memory allocator • 使⽤用的是 libmalloc • 基本上依照⼤大⼩小可分為 • Tiny ( <=1008 ) • Small ( <=128k ) • Large
  4. 4. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  5. 5. Tiny • block • Malloc 所能分配出去的最⼩小單位 • 在 tiny 中 block ⼤大⼩小為 0x10 • 其單位⼜又稱為 quantum block Block 0x10 block block block
  6. 6. Tiny • chunk (inused) • Malloc 所使⽤用的記憶體區塊 • 由眾多的 block 所構成 • 在 inused 情況下 chunk 中沒有任何 的 metadata block 0x10 block block block Chunk
  7. 7. block 0x10 block block block Tiny • chunk (freed) • Previous • 指向上⼀一塊 freed chunk • Next • 指向下⼀一塊 freed chunk Previous Next Msize Chunk … Msize …
  8. 8. Tiny • chunk (freed) • Previous 與 Next 並非單純存 pointer ⽽而是會加上 checksum 後再 存起來來 • Checksum 為 ptr ^ cookie 後的值 每個 byte 相加取最低 4 bit Previous Next Msize Chunk … Msize Previous >> 4 Checksum (4 bit)
  9. 9. Tiny • chunk (freed) • msize • 該 freed chunk 的⼤大⼩小,除了了 next 後 ⾯面有存外,最後兩兩 byte 也會存⼀一份 • 其 size 是以 quantum 為單位 • 例例如該 0x40 的 chunk 其 msize 為 0x4 (1 quantum 為 0x10 所以 msize = 0x40 >> 4) Previous Next Msize Chunk … Msize
  10. 10. Tiny • tiny_region • libmalloc 的記憶體分配池 • 主要都由眾多的 block 構成 • Default 情況下 • Region ⼤大⼩小 : 0x100000 • block 數量量 : 64520 • 其尾端有該 region 的 metadata Region block (inuse) Block (freed) … tiny_region_end tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (freed) previous next msize …… msize
  11. 11. Tiny • tiny_header_inuse_pair_t • 兩兩欄欄位皆為 bitmap • 位於 region 最尾端,⽤用於表⽰示該 region 中的 chunk 狀狀態 • Header ⽤用來來表⽰示對應到的 block 是 否為 chunk 開頭 • Inuse ⽤用來來表⽰示該 chunk 是否為 inused header inuse tiny_header_inuse_pair_t 0x0 0x4
  12. 12. Tiny Region block (inuse) Block (freed) … tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (freed) previous next msize …… msize ……001011 ……001001 Header inuse chunk tiny_region_end
  13. 13. Tiny • magazine • ⽤用來來管理理 tiny 跟 small 中 region 的 chunk 的結構 • mag_last 系列列 • libmalloc 在 free (size <= 0x100) 時 實際上並不會去 free ⽽而是記錄在 magazine 中,等下⼀一次互叫 free 時,才會真正去處理理這塊,類似 cache magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  14. 14. Tiny • magazine • mag_last_free • 上⼀一次要 free 的 chunk • mag_last_free_msize • 上⼀一次要 free 的 chunk ⼤大⼩小 • mag_last_free_rgn • 上⼀一次要 free 的 chunk 所在的 region magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  15. 15. Tiny • free_list • 管理理 free chunk 的 linked-list • 每 0x10 個為⼀一區間 • Tiny 中共有 64 個 free_list • 超過 tiny ⼤大⼩小的會放最後⼀一個 free_list • Double linked list • 第⼀一個 node 不指回 magazine magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  16. 16. Tinymagazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine previous next 6 …… 6 previous next 6 …… 6 previous next 6 …… 6
  17. 17. Tiny • magazine • mag_bitmap • ⽤用來來表⽰示 free_list 的 bitmap • mag_bytes_free_at_end • 該 region 剩下可分配空間剩餘⼤大 ⼩小 magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  18. 18. Tiny • magazine • mag_num_bytes_in_objects • 剛 region 分配出去 chunk 的數量量 • mag_bytes_in_magazine • 該 region 分配出去的⼤大⼩小 magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  19. 19. Tiny magazine Region block (inuse) Block (freed) … tiny_header_inuse_pair_t header (bitmap) inuse (bitmap) previous next msize …… msize magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] Chunk mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine region_trailer tiny_header_inuse_pair_t tiny_header_inuse_pair_t tiny_region_end
  20. 20. Tiny • tiny rack • ⽤用來來管理理 magazine 的結構 • Types • 判別該 rack 是屬於 tiny or small • num_regions • 該 rack 所管理理的 region 數量量 Types … num_regions num_regions_deaclloc region_hash_generation initial_regions[64] num_magazines *magazines cookie last_madvise tiny_rack
  21. 21. Tiny • tiny rack • num_magazines • 該 rack 中 magazines 的數量量 • magazines • 該 rack 的 magazines • cookie • 對該 rack 中 ptr 做 check 要⽤用的 cookie Types … num_regions num_regions_deaclloc region_hash_generation initial_regions[64] num_magazines *magazines cookie last_madvise tiny_rack
  22. 22. Tiny • szone • 整個記憶體管理理核⼼心,該結構會紀錄系統各 項 memory 資訊,各種 threshold 等資訊 • malloc_zone_t • 為 virtual function table 結構,有關記憶 體分配函式都會在這 • Cookie • 與 rack 中的 cookie 相同 szone malloc_zone_t … debug_flag … tiny_rack small_rack … cookie
  23. 23. szone szone malloc_zone_t size() malloc() calloc() valloc() free() … debug_flag … tiny_rack small_rack … cookie malloc_zone_t
  24. 24. tiny rack szone malloc_zone_t … debug_flag … tiny_rack small_rack … cookie Types … num_regions num_regions_deaclloc region_hash_generation initial_regions[64] num_magazines *magazines cookie last_madvise magazinetiny_rack padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  25. 25. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  26. 26. • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear) • ⼀一開始會先去看 cache 中有沒有剛好⼤大⼩小的 chunk • tiny_mag_ptr->mag_last_free_msize == msize • 這邊並不會對 chunk 做 unlink ,實際上這 chunk 在 cache 中,並沒有 真正 free 掉 Tiny mechanism
  27. 27. Tiny mechanism • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 0x1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear) • 如果沒有則會從剛好⼤大⼩小的 free_list 中找 (tiny_malloc_from_free_list) • 這時會從 free_list 中的第⼀一個拿,並對 next 做 unchecksum • 如果 unchecksum 驗證失敗就會 abort • 並把下⼀一塊的 previous 指到該 chunk 的 previous
  28. 28. Tiny mechanism • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 0x1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear)
  29. 29. Tiny mechanism • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 0x1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear) • 如果找不到則會最⼩小適合的 free_list 中拿 • 此時會做切割,並把剩下的 chunk 重新依據⼤大⼩小加入 free_list 中 • 如果都找不到則會從最後⼀一個 free_list 中找 • 因為最後⼀一個 free_list 不⼀一定是固定⼤大⼩小,可能會有⼀一些因為合併關係 的⼤大 chunk 會放到最後⼀一個 free_list
  30. 30. Tiny mechanism • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 0x1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear) • 找到適合的 chunk 後 • 會先把在 region 尾端的 metadata (tiny_header_inuse_pair) 設置好,再 返回給使⽤用者
  31. 31. Tiny mechanism Region block (inuse) Block (freed) … tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (freed) previous next msize …… msize ……001011 ……001001 chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine malloc(0x20) chunk tiny_region_end
  32. 32. Tiny mechanism Region block (inuse) Block (inuse) … tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (inuse) User data ……001011 ……001011 chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk tiny_region_end 從 free_list 分配
  33. 33. Tiny mechanism • 當呼叫 malloc 時會根據⼤大⼩小走不同流程,在 size <= 0x1008 時,會進入 tiny_malloc (實作在 tiny_malloc_should_clear) • 如果 free_list 中完全沒有可⽤用的 chunk,如果 region 的 tiny_region_end 夠⼤大,則會從 tiny_region_end 分配
  34. 34. Tiny mechanism Region block (inuse) Block (freed) … tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (freed) previous next msize …… msize ……001011 ……001001 chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine malloc(0x40) chunk tiny_region_end
  35. 35. Tiny mechanism Region block (inuse) Block (freed) … tiny_header_inuse_pair_t region_trailer tiny_header_inuse_pair_t Block (freed) previous next msize …… msize …1…001011 …1…001001 chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk tiny_region_end 從 tiny_region_end 分配 block (inuse) …
  36. 36. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size <= 1008 時,會進入 free_tiny • Size 取得⽅方式 (szone_size) • 依序⽤用 tiny、small、large ⽅方式嘗試取得 size • tiny_size • 會先驗證是否為 header 及 inused 狀狀態 • 接著⽤用 header 的 bitmap 算出 size Tiny mechanism
  37. 37. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size <= 1008 時,會進入 free_tiny • free_tiny • 如果 msize < 0x10 將正要 free 的 chunk 與 cache 中的 chunk 對換 • 接著進入 free 的核⼼心 tiny_free_no_lock Tiny mechanism
  38. 38. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size <= 1008 時,會進入 free_tiny • tiny_free_no_lock • 這邊就跟⼀一般 glibc ⼀一樣處理理合併問題後加入 free_list ,並清除 inuse • 尋找前⼀一塊 chunk ⽅方式是⽤用前⼀一塊 chunk 尾端的 msize 來來找到前⼀一塊 • 後⼀一塊則是利利⽤用本⾝身位置加上 size • 前後⼀一塊⼀一樣會先 unlink 後再合併 Tiny mechanism
  39. 39. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size <= 1008 時,會 進入 free_tiny • unlink (tiny_free_list_remove_ptr) • 會先 unchecksum • next & previous • previous_next & next_previous ( next or previous 非 NULL) • 驗證 prev_next == next_prev == ptr • 其中⼀一個沒過都會 abort Tiny mechanism
  40. 40. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache free(P)
  41. 41. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache Get size
  42. 42. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding P P_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache free(Q)
  43. 43. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache check prev chunk
  44. 44. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache check prev 
 header & inuse
  45. 45. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……001011 ……001001 … Q Cache clear header of P
  46. 46. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……000011 ……000001 … Q Cache unlink previous of P
  47. 47. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……000011 ……000001 … Q Cache merge
  48. 48. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……000011 ……000001 … Q Cache check next
  49. 49. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……000011 ……000001 … Q Cache Add to free_list
  50. 50. Tiny mechanism Region block (inuse) … tiny_header_inuse_pair_t tiny_header_inuse_pair_t magazine padding Q mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine cksum | NULL cksum | NULL 0x2 0x2 P ……000011 ……000001 … Q Cache
  51. 51. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  52. 52. Small • block • Malloc 所能分配出去的最⼩小單位 • 在 small 中 block ⼤大⼩小為 0x200 • 其單位⼜又稱為 quantum block Block 0x200 block block block
  53. 53. Small • chunk (inused) • Malloc 所使⽤用的記憶體區塊 • 與 tiny 相同由眾多的 block 所構成 • 在 inused 情況下 chunk 中沒有任何 的 metadata block 0x200 block block block Chunk
  54. 54. block block block Small • chunk (freed) • Previous • 指向上⼀一塊 freed chunk • Next • 指向下⼀一塊 freed chunk • 這邊 ptr 存的是 raw pointer Previous checksum (1 byte) Next Chunk checksum (1 byte) …
  55. 55. block block block Small • chunk (freed) • checksum • 與 tiny 不同,這邊另外存⼀一個 byte (但會 padding 到 8 byte) • 算法也與 tiny 不同 • ptr ^ rack->cookie ^ rack Previous checksum (1 byte) Next Chunk checksum (1 byte) …
  56. 56. block block block Small • chunk (out-of-band freed) • 如果 chunk address 是 page alignment 則會歸類為 oob free chunk • 該 chunk 中不會有任何 metadata … … … Chunk … …
  57. 57. Small • oob_free_entry_s • 管理理 oob chunk 的結構 • Prev • 指向上⼀一個相同⼤大⼩小的 free chunk • next • 指向下⼀一個相同⼤大⼩小的 free chunk • 這邊的 next & prev 也是 raw pointer Prev Next Ptr 0x0 0x8 0x10 oob free entry
  58. 58. Small • oob_free_entry_s • Ptr • 該結構所管理理的 oob chunk 在 region 中所在的 index • 同時最⾼高 1 bit 表⽰示是否為 oob free chunk Prev Next Ptr 0x0 0x8 0x10 oob free entry
  59. 59. Small • small_region • libmalloc 的 small 記憶體分配池 • 基本上與 tiny 類似,但 block ⼤大⼩小變 為 0x200 • Default 情況下 • Region ⼤大⼩小 : 0x800000 • block 數量量 : 16319 • 其尾端亦有該 region 的 metadata Region block (inuse) Block (freed) … small_region_end small_meta_words[] region_trailer Block (freed) small_oob_free_entries[] Previous checksum (1 byte) Next checksum (1byte) …
  60. 60. Small • small_region • small_meta_words[] • msize_t array • 每個 element 對應到每個 block • 存放 chunk size 及 inuse Region block (inuse) Block (freed) … small_region_end small_meta_words[] region_trailer Block (freed) small_oob_free_entries[] Previous checksum (1 byte) Next checksum (1byte) …
  61. 61. Small • small_region • small_meta_words[] • 對應到 chunk(inuse) 的開頭的 block 會存該 chunk 的 size • 對應到 chunk(freed) 的開頭和結 尾的 block 會存該 chunk 的 size 及 flag • 最⾼高 1 bit ⽤用來來表⽰示是否為 freed Region block (inuse) Block (freed) … small_region_end small_meta_words[] region_trailer Block (freed) small_oob_free_entries[] Previous checksum (1 byte) Next checksum (1byte) …
  62. 62. Small Region … Block (freed) … small_region_end small_meta_words[] region_trailer Block (freed) small_oob_free_entries[] Previous checksum (1 byte) Next checksum (1byte) … flag|msize Block (freed) flag|msize msize
  63. 63. Small • small_region • small_oob_free_entries[] • 存放 oob_free_entry 的 array • 共有 32 個 • 只要 free 完 chunk 是屬於 oob chunk 就會放這邊 Region block (inuse) Block (freed) … small_region_end small_meta_words[] region_trailer Block (freed) small_oob_free_entries[] Previous checksum (1 byte) Next checksum (1byte) …
  64. 64. Small Prev Next Ptr oob free entry free_list[x] Region block (…) Block (freed) … small_meta_words[] region_trailer Block (freed) small_oob_free_entries[0] small_oob_free_entries[…] Block (freed) oob chunk
  65. 65. Small • magazine • ⽤用來來管理理 tiny 跟 small 中 region 的 chunk 的結構 • mag_last 系列列 • libmalloc 在 free 時實際上並不會 去 free ⽽而是記錄在 magazine 中,等下⼀一次互叫 free 時,才會 真正去處理理這塊,類似 cache magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine
  66. 66. Smallmagazine padding mag_last_free mag_last_free_msize mag_last_free_rgn free_list[0] … … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine • free_list • 管理理 free chunk 的 linked-list • 每 0x200 個為⼀一區間 • 超過 small ⼤大⼩小的會放最後⼀一個 free_list • Double linked list • 第⼀一個 node 不指回 magazine • 其餘皆與 tiny 相同
  67. 67. Small magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[1] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine NULL Next Ptr oob free entry Region block (…) Block (freed) … small_meta_words[] region_trailer Block (freed) small_oob_free_entries[0] small_oob_free_entries[…] Block (freed) oob chunk Block (free)
  68. 68. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  69. 69. • 當呼叫 malloc 時根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時, 會進入 small_malloc (實作在 small_malloc_should_clear) • ⼀一開始會先去看 cache 中有沒有剛好⼤大⼩小的 chunk • small_mag_ptr->mag_last_free_msize == msize • 這邊並不會對 chunk 做 unlink ,實際上這 chunk 在 cache 中,並沒有 真正 free 掉 Small mechanism
  70. 70. Small mechanism • 當呼叫 malloc 時根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時,會進入 small_malloc (實作在 small_malloc_should_clear) • 如果沒有則會從剛好⼤大⼩小的 free_list 中找 (small_malloc_from_free_list) • 這時會從 free_list 中的第⼀一個拿,看看是否為 oob chunk • ⼀一般 chunk : 對 next 做 unchecksum • Oob chunk : 直接拿 next • 並把下⼀一塊的 previous 指到該 chunk 的 previous • 這邊會對 double linked list 做檢查 next_prev == ptr
  71. 71. Small mechanism • 當呼叫 malloc 時根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時, 會進入 small_malloc (實作在 small_malloc_should_clear) • 除了了 oob chunk 不會做 checksum 外接下來來都與 tiny 類似
  72. 72. Small mechanism Region block (inuse) Block (freed) … region_trailer Block (freed) chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine malloc(0x600) chunk small_region_end small_meta_words[] small_oob_free_entries[] flag|msize flag|msize msize Block (freed) Previous checksum (1 byte) Next checksum (1byte) …
  73. 73. Small mechanism Region block (inuse) Block (inuse) … region_trailer Block (inuse) chunk magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x3 0 msize Block (inuse) Previous checksum (1 byte) Next checksum (1byte) …
  74. 74. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時,會進入 free_small • free_small • 會先將正要 free 的 chunk 與 cache 中的 chunk 對換 • 接著進入 free 的核⼼心 small_free_no_lock Small mechanism
  75. 75. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時,會進入 free_small • small_free_no_lock • 這邊與 tiny 類似,⼀一樣會有合併⾏行行為,最後在加入 free_list • 尋找前⼀一塊 chunk ⽅方式是⽤用對應到前⼀一塊 chunk 尾端的 small meta word 來來判斷前⼀一 塊是否為 freed 以及取得前⼀一塊 size 及位置 • 後⼀一塊則取得對應到下⼀一塊 chunk 的 small meta word 來來判斷下⼀一塊是否為 freed 以 及取得下⼀一塊 size 及位置 • 前後⼀一塊如果是 freed ⼀一樣會先 unlink 後再合併 Tiny mechanism
  76. 76. • 當呼叫 free 時會先取得 free chunk 的 size 在根據⼤大⼩小走不同流程,在 size > 1008 且 size < 128k 時,會進入 free_small • unlink (small_free_list_remove_ptr) • 非 oob chunk 會先 unchecksum , oob chunk 則會直接取得 ptr • next & previous • previous_next & next_previous ( next or previous 非 NULL) • 驗證 prev_next == next_prev == ptr • 其中⼀一個沒過都會 abort Tiny mechanism
  77. 77. Small mechanism Region block (inuse) Block (inuse) … region_trailer Block (inuse) P magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x3 0 msize Block (inuse) … … … … … free(P)
  78. 78. Small mechanism Region block (inuse) Block (inuse) … region_trailer Block (inuse) P magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x3 0 msize Block (inuse) … … … … … Check prev chunk
  79. 79. Small mechanism Region block (inuse) Block (inuse) … region_trailer Block (inuse) P magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x3 0 msize Block (inuse) … … … … … Check next chunk
  80. 80. Small mechanism Region block (inuse) Block (inuse) … region_trailer Block (inuse) P magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x3 0 msize Block (inuse) … … … … … Set header & add to free list
  81. 81. Small mechanism Region block (inuse) Block (freed) … region_trailer Block (freed) P magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine chunk small_region_end small_meta_words[] small_oob_free_entries[] 0x8003 0x8003 msize Block (freed) Previous checksum (1 byte) Next checksum (1byte) …
  82. 82. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  83. 83. Outline • Exploitation • Tiny • Overlap chunk attack • free_list overwrite attack • Small • Meta word overwrite
  84. 84. Outline • Exploitation • Tiny • Overlap chunk attack • free_list overwrite attack • Small • Meta word overwrite
  85. 85. Exploitation • Overlap chunk attack • 其⽬目的在於創造出 overlap chunk 進⽽而更更改其他 chunk 內容,在 overflow 只能蓋到 size 時很好⽤用 • ⽅方法為利利⽤用漏洞洞改掉 size 加⼤大原本的 free chunk,並利利⽤用合併的特性, 使得要 free 的 chunk 變很⼤大,進⽽而蓋掉其他 chunk • 另外在 free 的時候也會檢查 cache 中的 ptr 與正要 free 的 ptr 兩兩個是 否相等,如果相等就會 abort (double free)
  86. 86. Exploitation A B C D 0x30 0x50 0x40 0x20 magazine padding mag_last_free mag_last_free_msize mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine free(B) 01000100001001 01000100001001 free_list[2] free_list[3] free_list[4] free_list[5] … Header Inuse
  87. 87. Exploitation A B C D 0x30 0x50 0x40 0x20 magazine padding B 0x5 mag_last_free_rgn … free_list[2] … free_list[x] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100001001 free(D) free_list[2] free_list[3] free_list[4] free_list[5] … Header Inuse
  88. 88. Exploitation A B cksum | NULL cksum | NULL 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 Use A to 
 overflow msize of B free_list[5] … Header Inuse
  89. 89. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free(A) free_list[5] … Header Inuse
  90. 90. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding A 0x3 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 free(C) free_list[5] … Header Inuse
  91. 91. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding A 0x3 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 free(C) -> process free(A) free_list[5] … Header Inuse
  92. 92. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 check prev free_list[5] … Header Inuse
  93. 93. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 check next free_list[5] … Header Inuse
  94. 94. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 remove B from free_list free_list[5] … Header Inuse
  95. 95. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 Unchecksum Prev & next of B free_list[5] … Header Inuse
  96. 96. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 此時需 brute-force 4 bit Checksum 如果 checksum 沒過會 Abort free_list[5] … Header Inuse
  97. 97. Exploitation A B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 00000100000001 merge & add to list free_list[5] … Header Inuse
  98. 98. Exploitation B NULL NULL 0x9 0x5 C D 0x30 0x50 0x40 0x20 cksum | NULL cksum | NULL 0x2 0x2 magazine padding C 0x4 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100000001 00000100000001 free_list[5] … Header Inuse A cksum | NULL cksum | NULL 0xc
  99. 99. Outline • Exploitation • Tiny • Overlap chunk attack • free_list overwrite attack • Small • Meta word overwrite
  100. 100. • Free_list overwrite attack • 其實就是 unlink attack 但觸發時機是在 malloc 時,雖然⼤大部分 unlink 都 有檢查,但在 tiny_malloc 從 free_list 拿出來來時,並沒有去驗證 double linked-list • 利利⽤用⽅方式為覆蓋掉 free chunk 的 prev 及 next , next 內容為 shift 過後的 指針,⼀一樣需要撞 4 bit 的 checksum ,如果 checksum 有過,則會將 prev 寫到 *next 中 Exploitation
  101. 101. Exploitation • Free_list overwrite attack
  102. 102. Exploitation A B cksum | NULL cksum | NULL 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 Use A to 
 overflow B free_list[5] … Header Inuse
  103. 103. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 malloc(0x50) free_list[5] … Header Inuse
  104. 104. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse Check cache 0x5 != 0x2
  105. 105. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse Malloc from free_list
  106. 106. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse next = unchecksum(target >> 4)
  107. 107. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse next = unchecksum(target >> 4) 這邊需要 bruteforce 4 bit
  108. 108. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse Next->previous = ptr->previous
  109. 109. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100000001 free_list[5] … Header Inuse target = deadbeef
  110. 110. Exploitation A B deadbeef target >> 4 0x5 0x5 C D 0x30 0x50 0x40 0x20 magazine padding D 0x2 mag_last_free_rgn … free_list[2] free_list[3] free_list[4] mag_bitmap[4] mag_bytes_free_at_end mag_bytes_free_at_start mag_last_region mag_num_bytes_in_objects mag_bytes_in_magazine 01000100001001 01000100001001 free_list[5] … Header Inuse Set inuse and
 return B to user
  111. 111. Exploitation • Tiny • 除了了上⾯面兩兩種利利⽤用⽅方式之外,⼀一般的 unlink attack 也可以利利⽤用,不過需 要過兩兩次 checksum 檢查 (prev & next) 機率變為 1/256 • 當然也可以蓋掉 region 底端的 header 來來製造出 overlap chunk
  112. 112. Outline • Exploitation • Tiny • Overlap chunk attack • free_list overwrite attack • Small • Meta word overwrite
  113. 113. • Small • 基本上能利利⽤用的點不多,如果想要達成 unlink attack 需要 brute-force 2 個 byte 的 checksum • 比較利利⽤用的點是 Meta word overwrite ,不過要能蓋到 region 尾端 Exploitation
  114. 114. • Meta word overwrite • 基本上就構造 meta word 使得 malloc 取得偽造的 msize 進⽽而製造出 overlap chunk Exploitation
  115. 115. • https://opensource.apple.com/source/libmalloc/ Reference

    Seja o primeiro a comentar

    Entre para ver os comentários

  • ssuser02c605

    Mar. 31, 2021
  • ssuserd711772

    Apr. 28, 2021

MacOS memory allocator (libmalloc) Exploitation - Chinese Version

Vistos

Vistos totais

3.061

No Slideshare

0

De incorporações

0

Número de incorporações

17

Ações

Baixados

91

Compartilhados

0

Comentários

0

Curtir

2

×