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

MacOS memory allocator (libmalloc) Exploitation

  • Seja o primeiro a comentar

MacOS memory allocator (libmalloc) Exploitation

  1. 1. libmalloc exploitation MacOS memory allocator Angelboy @scwuaptx
  2. 2. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  3. 3. OSX memory allocator • libmalloc • It can be divided into • Tiny ( <=1008 ) • Small ( <=128k ) • Large
  4. 4. Outline • OSX memory allocator • Tiny • Data Structure • mechanism • Small • Data Structure • mechanism • Exploitation
  5. 5. Tiny • block • The smallest unit can be allocated • A block size is 0x10 in tiny region • known as Quantum block Block 0x10 block block block
  6. 6. Tiny • chunk (inused) • basic data structure used by malloc • Consisting of numerous blocks • There is no metadata in the inused chunk block 0x10 block block block Chunk
  7. 7. block 0x10 block block block Tiny • chunk (freed) • Previous • Point to previous freed chunk in linked list • Next • Point to next freed chunk in linked list Previous Next Msize Chunk … Msize …
  8. 8. Tiny • chunk (freed) • Previous and next are not raw pointer but a checksum and a shifted pointer • Checksum = SumofEverybytes(ptr^cookie) & 0xf Previous Next Msize Chunk … Msize Previous >> 4 Checksum (4 bit)
  9. 9. Tiny • chunk (freed) • msize • The size of freed chunk, it would be after next pointer and the last two byte of the chunk • Size is in quantum unit • For example, If the size of chunk is 0x40, then msize is 0x4 ( 1 quantum is 0x10, so msize = 0x40 >> 4) Previous Next Msize Chunk … Msize
  10. 10. Tiny • tiny_region • The memory pool of libmalloc • Region consist of numerous blocks • Default • Size of Region : 0x100000 • Number of block : 64520 • There are some metadata at the end of region 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 • In the end of region • It is used to represent the chunk state in the region • Header is used to indicate whether the corresponding block is the head of chunk • Inuse is used to indicate whether the chunk is 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 • The structure used to manage the chunk in the region of tiny and small • mag_last • Libmalloc does not actually free (size <= 0x100) but is recorded in magazine. When the next time you call free, it will actually free the chunk. • If you call malloc with same size as the chunk in mag_last, it will use it first. • Similar to 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 • The last freed chunk • mag_last_free_msize • The size of the last freed chunk • mag_last_free_rgn • The region of the last freed chunk 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 • Linked lists to manage freed chunks • Every 0x10 bytes as an unit • There are 64 free_lists in Tiny • Chunk size larger than tiny size will be put in the last free_list • Double linked list • The first node will not point back to 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 • a bitmap used to represent free_list • mag_bytes_free_at_end • the remaining size of the 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 • The number of chunks in the region • mag_bytes_in_magazine • The allocated size of the 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 • Used to manage magazine • Types • Determine whether the rack is tiny or small • num_regions • The number of region belongs to the rack 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 • The number of magazines of the rack • magazines • The magazines pointer of the rack • cookie • Checksum cookie for tiny rack Types … num_regions num_regions_deaclloc region_hash_generation initial_regions[64] num_magazines *magazines cookie last_madvise tiny_rack
  22. 22. Tiny • szone • The core structure of libmalloc. • It will record the system's various heap information, thresholds and other information. • malloc_zone_t • virtual function table • Cookie • Same as the cookie in the tiny rack 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. • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear) • At first, it will check if (tiny_mag_ptr->mag_last_free_msize == msize) • It will not unlink the chunk. In fact, this chunk is in the cache and is not really free. Tiny mechanism
  27. 27. Tiny mechanism • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear) • If no suitable chunk in cache, it will find chunk from free_list (tiny_malloc_from_free_list) • It will take the first one from the free_list and do unchecksum for next pointer • Abort if unchecksum failed
  28. 28. Tiny mechanism • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear)
  29. 29. Tiny mechanism • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear) • If no suitable chunk in free_list, it will take from the smallest suitable free_list • It will be split, and insert the remainder chunk into free_list
  30. 30. Tiny mechanism • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear) • After finding the suitable chunk • It will update the metadata(tiny_header_inuse_pair) and return the chunk to user
  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 • When calling malloc, it will go through different processes according to the size. When size < 1008 byte, it will use tiny_malloc(tiny_malloc_should_clear) • If there is no chunk available in free_list, it will allocate from tiny_region_end if the size is enough.
  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 Allocate from tiny_region_end block (inuse) …
  36. 36. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size < 1008 byte, it will use free_tiny • Size retrieval method (szone_size) • tiny_size • Verify header and inused state first. • Use bitmap of header to calculate size Tiny mechanism
  37. 37. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size < 1008 byte, it will use free_tiny • free_tiny • If msize < 0x10, it will swap freed chunk in cache with the current chunk. Tiny mechanism
  38. 38. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size < 1008 byte, it will use free_tiny • tiny_free_no_lock • Similar as glibc, it will merge previous and next freed chunk and clear inuse bit . • The way to find the previous chunk is to use the msize at the end of the previous chunk • Use the size of chunk and address to find the next chunk • It will unlink before merge Tiny mechanism
  39. 39. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size < 1008 byte, it will use free_tiny • unlink (tiny_free_list_remove_ptr) • unchecksum • next & previous • previous_next & next_previous ( next or previous not NULL) • verify prev_next == next_prev == ptr • Abort if any conditions above failed 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 • The smallest unit can be allocated • A block size is 0x200 in tiny region • known as Quantum block Block 0x200 block block block
  53. 53. Small • chunk (inused) • Basic data structure used by malloc • Consisting of numerous blocks • There is no metadata in the inused chunk block 0x200 block block block Chunk
  54. 54. block block block Small • chunk (freed) • Previous • Point to previous freed chunk in linked list • Next • Point to next freed chunk in linked list • It is different from tiny, it used raw pointer Previous checksum (1 byte) Next Chunk checksum (1 byte) …
  55. 55. block block block Small • chunk (freed) • checksum • Unlike tiny , there is another byte added here (but padding to 8 bytes) • SumofEveryBytes(ptr ^ rack- >cookie ^ rack) Previous checksum (1 byte) Next Chunk checksum (1 byte) …
  56. 56. block block block Small • chunk (out-of-band freed) • Page aligned chunk is called oob free chunk • There is no metadata … … … Chunk … …
  57. 57. Small • oob_free_entry_s • Used to manage oob chunk • Prev • Point to previous same size freed chunk in linked list • next • Point to next same size freed chunk in linked list • it also used raw pointer Prev Next Ptr 0x0 0x8 0x10 oob free entry
  58. 58. Small • oob_free_entry_s • Ptr • The index of the oob chunk in the region • The highest 1 bit indicates whether it is oob free chunk Prev Next Ptr 0x0 0x8 0x10 oob free entry
  59. 59. Small • small_region • The memory pool of libmalloc • Similar to tiny, but the block size becomes 0x200 • Default • The size of region : 0x800000 • The number of block : 16319 • There are some metadata in the end of region 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 • Each element corresponds to each block • It contain chunk size and inuse bit 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[] • The block corresponding to the beginning of chunk(inuse) will contain the size of the chunk • The block corresponding to the beginning and end of chunk(freed) will store the size and flag of the chunk. • The highest 1 bit is used to indicate whether it is 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[32] • An array of oob_free_entry • OOB chunk will be put here. 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 • The structure used to manage the chunk in the region of tiny and small • mag_last • Libmalloc does not free the chunk first but cache in mag_last_free. When the next time you call free, it will actually free the chunk • Similar to 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 • Linked lists to manage freed chunks • Every 0x200 bytes as an unit • Chunk size larger than small size will be put in the last free_list • Double linked list • The first node will not point back to magazine • Simliar to tiny magazine
  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. • When calling malloc, it will go through different processes according to the size. When size > 1008 byte and size < 128k, it will use small_malloc (small_malloc_should_clear) • At first, it will check if (tiny_mag_ptr->mag_last_free_msize == msize) • It will not unlink the chunk. In fact, this chunk is in the cache and is not really free. Small mechanism
  70. 70. Small mechanism • When calling malloc, it will go through different processes according to the size. When size > 1008 byte and size < 128k, it will use small_malloc (small_malloc_should_clear) • If no suitable chunk in cache, it will find chunk from free_list (small_malloc_from_free_list) • It will take the first one from the free_list and check whether is oob chunk • normal chunk : do unchecksum for next pointer • Oob chunk : take from next • Do unlink • It will check the double linked list (next_prev == ptr)
  71. 71. Small mechanism • When calling malloc, it will go through different processes according to the size. When size > 1008 byte and size < 128k, it will use small_malloc (small_malloc_should_clear) • It is same as tiny except that oob chunk will not do checksum
  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. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size > 1008 byte and size < 128k, it will use free_small • free_small • it will swap freed chunk in cache with the current chunk. Small mechanism
  75. 75. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size > 1008 byte and size < 128k, it will use free_small • small_free_no_lock • It is similar to tiny, there will be a merge behavior, and finally insert into free_list • The way to find the previous chunk is to use the small_meta_word corresponding to the end of the previous chunk to determine whether the previous chunk is freed and to get the previous chunk size and position. • The way to find the next chunk is to use the small_meta_word corresponding to next chunk • It will merge previous and next freed chunk • It will unlink before merge Tiny mechanism
  76. 76. • When calling free, it will take the size of freed chunk and go through different processes according to the size. If size > 1008 byte and size < 128k, it will use free_small • unlink (small_free_list_remove_ptr) • If is not oob chunk, it will do unchecksum. If it is oob chunk, it will take directly ptr • next & previous • previous_next & next_previous ( next or previous not NULL) • Verify prev_next == next_prev == ptr • Abort if any conditions above failed 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 • The goal is to create an overlap chunk and change other chunk content, which is useful when you can use vulnerability to overwrite the size of next chunk. • The method is to use the vulnerability to overwrite the size and increase the original free chunk and use merged feature to create overlap chunk. • In addition, when calling free, it will check whether the ptr in the cache is equal to the ptr to be free. If it is equal, it will be 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 It need to brute-force 4 bit Checksum 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 • In fact, it is unlink attack but the trigger timing is in malloc. • It does not verified double linked list when tiny_malloc take free chunk from free_list • The method is to overwrite the prev and next of the free chunk. • The prev & next pointer is shifted right 4 bit pointer. • It needs to hit the 4 bit checksum • The prev will be written to *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) It need to 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 • In addition to the above two methods, the general unlink attack can also be used, but it need to bypass two checksum checks (prev & next) and the probability becomes 1/256. • You also can overwrite the metadata in the end of region to create overlap chunk.
  112. 112. Outline • Exploitation • Tiny • Overlap chunk attack • free_list overwrite attack • Small • Meta word overwrite
  113. 113. • Small • Basically, there are not many points that can be used. If you want to achieve unlink attack, you need brute-force 2 bytes of checksum. • If you arbitrary memory reading, you can calculate checksum and do unlink attack. • The more useful point is meta word overwrite, but you need to overwrite the end of the region. Exploitation
  114. 114. • Meta word overwrite • Constructing a meta word causes malloc to take a fake msize and create an overlap chunk Exploitation
  115. 115. • https://opensource.apple.com/source/libmalloc/ Reference

    Seja o primeiro a comentar

    Entre para ver os comentários

  • hama7230

    Dec. 12, 2019
  • YuxuanYe3

    Feb. 2, 2021
  • jiangcamel

    Mar. 10, 2021

MacOS memory allocator (libmalloc) Exploitation

Vistos

Vistos totais

3.003

No Slideshare

0

De incorporações

0

Número de incorporações

31

Ações

Baixados

95

Compartilhados

0

Comentários

0

Curtir

3

×