Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Advanced heap exploitaion

13,157 views

Published on

延續先前的 heap exploitation 再增加一些常見的 heap 漏洞利用的技巧

Published in: Technology
  • Be the first to comment

Advanced heap exploitaion

  1. 1. Advanced heap exploitation Angelboy scwuaptx@gmail.com
  2. 2. Who am I • Angelboy • 中央⼤大學資⼯工系碩⼠士班 • Advanced Defense Lab • Member of • Bamboofox CTF team • HITCON CTF team 2
  3. 3. 前⾔言 • 請先服⽤用 Heap exploitation • 這邊會在列出幾個常⾒見的 heap 漏洞利⽤用⽅方式 • 如果這份投影⽚片內容有錯誤的地⽅方,記得⼀一定要告訴我 • 環境 • glibc - 2.19 • kernel - 4.2 • 64 bit
  4. 4. Outline • Fastbin corruption • Shrink the chunk • Extend the chunk
  5. 5. Outline • Fastbin corruption • Shrink the chunk • Extend the chunk
  6. 6. Fastbin corruption • 假設程式存在著 double free 的漏洞 • ⺫⽬目的: • 我們可以利⽤用 fastbin chunk 改掉 fd 使得下下 次 malloc 該 chunk 時可以取得⾃自⼰己想要的位置 • 為了利⽤用 double free 的漏洞來改變 free chunk 中的 fd ,我們可以利⽤用⼀一些 fastbin 的特性達到 我們的⺫⽬目的,但我們也必須通過⼀一些 chunk 的檢 查
  7. 7. Fastbin corruption • fastbin 的檢查 • in free(p) : • chunk address < - size 且 alignment • chunk size >= MINSIZE(0x20) 且為 0x10 的倍數 • nextchunk->size • ⼤大於 MINSIZE(0x20) • ⼩小於 system_mem (0x21000) • 檢查屬於該 size 的 fastbin 中的第⼀一塊 chunk 與 p 是否不同
  8. 8. Fastbin corruption • fastbin 的檢查 • in malloc(bytes) : • 根據 bytes ⼤大⼩小取得 index 後,到對應的 fastbin 找, 取出後檢查該 chunk 的 (unsigned long) size 是否屬 於該 fastbin • 但實際⽐比較的時候是先以 fastbin 中第⼀一塊 size 取 得 fastbin 的 index ,再去⽤用這個 index 跟剛剛算的 index 是否相同,不過這取 index 的⽅方式是⽤用 unsigned int (4 byte)
  9. 9. Fastbin corruption • fast bin • a singly linked list • chunk size <= 0x80 byte • 不取消 inuse flag • 依據 bin 中所存的 chunk ⼤大⼩小,在分為 10 個 fast bin 分別為 size 0x20,0x30,0x40… • LIFO • 當下次 malloc ⼤大⼩小與這次 free ⼤大⼩小相同時,會從相同的 bin 取 出,也就是會取到相同位置的 chunk
  10. 10. • fastbin layout Fastbin corruption 0x128 0 0xdada …… 0 ….. 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata prev_size size = 0x40 fd = null bk = null datadata 0x128 0xdada fast bin array
  11. 11. Fastbin corruption • 我們可以利⽤用 fastbin 的 chunk 在 free 的時候只 檢查屬於該 size 的 fastbin 中的第⼀一塊 chunk 與 p 是否不同這項特性,來創造 overlaps chunk • 創造出⼀一個 circle 的 singly linked list,這樣就可 以達到類似 UAF 的效果
  12. 12. • fastbin layout Fastbin corruption 0x128 0 0 …… 0 ….. 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array free(0x603090)
  13. 13. • fastbin layout Fastbin corruption 0x128 0 0x603080 …… 0 ….. 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = null bk = null datadata 0x603080 free(0x6030d0)
  14. 14. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = null bk = null datadata 0x603080 free(0x603090) double free 0x128 0 0x6030c0 …… 0 …..
  15. 15. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = null bk = null datadata 0x603080 free(0x603090) double free 但因為 fastbin 只會檢查 fastbin 的第⼀一塊,故通過檢查 0x128 0 0x6030c0 …… 0 …..
  16. 16. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 0x128 0 0x603080 …… 0 ….. Circle singly linked list
  17. 17. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 0x128 0 0x603080 …… 0 ….. Same chunk in the fastbin 這樣在之後 malloc 時會有 overlap 情形發⽣生
  18. 18. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = 0x6030c0 bk = null datadata 0x603080 0x128 0 0x603080 …… 0 ….. malloc(0x30)
  19. 19. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = 0xdeadbeef bk = null datadata 0x603080 0x128 0 0x6030c0 …… 0 ….. You will get the 0x603080 chunk ,and overwrite the fd But the chunk is also in the fastbin
  20. 20. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0x603080 bk = null datadata 0x6030c0 prev_size size = 0x40 fd = 0xdeadbeef bk = null datadata 0x603080 0x128 0 0x6030c0 …… 0 ….. malloc(0x30)
  21. 21. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array prev_size size = 0x40 fd = 0xdeadbeef bk = null datadata 0x603080 0x128 0 0x603080 …… 0 ….. malloc(0x30)
  22. 22. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array 0x128 0 0xdeadbeef …… 0 ….. malloc(0x30)
  23. 23. • fastbin layout Fastbin corruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array 0x128 0 0 …… 0 ….. Get the 0xdeadbeef chunk
  24. 24. Fastbin corruption • fd 只要符合 size 是否屬於該 chunk 就可以通過 malloc 檢查即可, 因此只要想寫⼊入的位址附近有屬於該 bin 的 size 就可以讓 malloc 分配到該位置 • 根據 bytes ⼤大⼩小取得 index 後,到對應的 fastbin 找,取出後檢 查該 chunk 的 (unsigned long) size 是否屬於該 fastbin • 但實際⽐比較的時候是先以 fastbin 中第⼀一塊 size 取得 fastbin 的 index ,再去⽐比 index 跟剛剛算的 index 是否相同,不過這 取 index 的⽅方式是⽤用 unsigned int (4 byte),所以偽造時不⽤用 滿⾜足 8 byte • 因此沒有檢查 alignment 所以不⼀一定要以⼋八的倍數作為 chunk 的 address
  25. 25. Outline • Fastbin corruption • Shrink the chunk • Extend the chunk
  26. 26. Shrink the chunk • 假設存在⼀一個 off-by-one null byte 的漏洞 • ⺫⽬目的: • 創造出 overlap chunk ,進⽽而更改其他 chunk 中的內容 • 主要利⽤用 unsortbin ,smallbin 會 unlink 做合併的 特性來達到我們的⺫⽬目的
  27. 27. Shrink the chunk • ⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段,且 fastbin 是空的 0 0x41 0 0 0x171 0x101 A B C
  28. 28. • free(B) Shrink the chunk 0 0x41 0 0 0x171 0x101 A B C
  29. 29. • free(A) Shrink the chunk 0 0x41 0 0x170 0x171 0x100 A B C
  30. 30. • malloc(0x38) Shrink the chunk 0 0x41 0 0x170 0x171 0x100 A B C
  31. 31. • read data to A and off-by-one overflow Shrink the chunk 0 0x41 0 0x170 0x171 0x100 A B C
  32. 32. • malloc(0x80) Shrink the chunk 0 0x41 0 0x170 0x100 0x100 A B C
  33. 33. • malloc(0x30) Shrink the chunk 0 0x41 0 0x170 0x71 0x100 A C 0 0x91 B D
  34. 34. • free(B) Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0 0x41 B D E
  35. 35. • free(C) Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0x90 0x40 B D E
  36. 36. • free(C) Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0x90 0x40 B D 此時會因為 C 是 smallbin 的⼤大⼩小的關係, 所以會檢測上⼀一塊是否 inused E
  37. 37. • free(C) - merge Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0x90 0x40 B D 如果上⼀一塊是 freed 就會 根據prev_size 去找上⼀一塊 chunk 的 header 做 合併及 unlink E
  38. 38. Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x271 0x90 0x40 B D 此時 unsortbin 存這 這塊⼤大 chunk , 所以下次 malloc 會⽤用這⼀一塊 先份配給 user E
  39. 39. • malloc(0x260) Shrink the chunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x271 0x90 0x40 B D E
  40. 40. • 此時可任意改 D Shrink the chunk 0 0x41 A 0 0x271 0x90 0x40 B D overlap chunk
  41. 41. Shrink the chunk • overlap 的情況其實還蠻 powerful 的,如果中間 overlap 部分有 function pointer 或者是其他有⽤用 的 struct 可間接控制程式流程 • 也可以配合 fastbin freed chunk 更改 fd
  42. 42. Outline • Fastbin corruption • Shrink the chunk • Extend the chunk
  43. 43. Extend the chunk • 假設存在⼀一個 off-by-one 的漏洞 • ⺫⽬目的: • ⼀一樣是創造出 overlap chunk ,進⽽而更改其他 chunk 中的內容 • 跟 shrink 很像,但主要是加⼤大 size 直接吃掉後⾯面 的 chunk ,只要後⾯面的 chunk header 有對上就 好
  44. 44. Extend the chunk • ⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段 0 0x41 0 0 0x171 0x41 A B C
  45. 45. Extend the chunk • free(A) 0 0x41 0 0 0x171 0x41 A B C
  46. 46. Extend the chunk • malloc(0x38) 0 0x41 0 0 0x171 0x41 A B C
  47. 47. Extend the chunk • read data to A and off-by-one overflow 0 0x41 0 0 0x171 0x41 A B C
  48. 48. Extend the chunk • free(B) 0 0x41 0 0 0x1b1 0x41 A B C 0x1b1 = 0x171 + 0x40 為了之後要把 C 吃進去
  49. 49. Extend the chunk • free(B) 0 0x41 0 0 0x1b1 0x41 A B C 在此時會根據 B 的 size 去找下⼀一塊 chunk 的 header 因剛剛偽造的 size 會去抓到 C 的下⼀一塊 chunk header 做 inused bit 檢查 但 C 是 inused 所以會通過
  50. 50. Extend the chunk • free(B) 0 0x41 0 0 0x1b1 0x41 A B C 此時這塊 chunk 會被合併到 top (如果 C 後⾯面是 top) 或是加到 unsortbin 中
  51. 51. Extend the chunk • malloc(0x1a0) 0 0x41 0 0 0x1b1 0x41 A B C
  52. 52. Extend the chunk • 此時可以任意更改 C 0 0x41 0 0 0x1b1 0x41 A B Coverlap chunk
  53. 53. Extend the chunk • 不過跟 Shrink ⽐比起來相對限制⽐比較多⼀一點,必須 要可控 off-by-one 的那個 byte ,Shrink 只要是 null byte 即可,相對⽐比較常⾒見,但也不好發現就 是了
  54. 54. Summary • Heap exploitation 雖然已利⽤用來說會難⼀一點,但 常常在 Full mitigation 的情況下都可以利⽤用,畢竟 針對 heap 來說相對應的保護較少,也較難去實作 • Heap 就是⾨門藝術
  55. 55. Reference • Glibc Adventures: The Forgotten Chunks • google project zero • glibc cross reference

×