Advanced heap exploitation
Angelboy
scwuaptx@gmail.com
Who am I
• Angelboy
• 中央⼤大學資⼯工系碩⼠士班
• Advanced Defense Lab
• Member of
• Bamboofox CTF team
• HITCON CTF team
2
前⾔言
• 請先服⽤用 Heap exploitation
• 這邊會在列出幾個常⾒見的 heap 漏洞利⽤用⽅方式
• 如果這份投影⽚片內容有錯誤的地⽅方,記得⼀一定要告訴我
• 環境
• glibc - 2.19
• kernel - 4.2
• 64 bit
Outline
• Fastbin corruption
• Shrink the chunk
• Extend the chunk
Outline
• Fastbin corruption
• Shrink the chunk
• Extend the chunk
Fastbin corruption
• 假設程式存在著 double free 的漏洞
• ⺫⽬目的:
• 我們可以利⽤用 fastbin chunk 改掉 fd 使得下下
次 malloc 該 chunk 時可以取得⾃自⼰己想要的位置
• 為了利⽤用 double free 的漏洞來改變 free chunk
中的 fd ,我們可以利⽤用⼀一些 fastbin 的特性達到
我們的⺫⽬目的,但我們也必須通過⼀一些 chunk 的檢
查
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 是否不同
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)
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
• 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
Fastbin corruption
• 我們可以利⽤用 fastbin 的 chunk 在 free 的時候只
檢查屬於該 size 的 fastbin 中的第⼀一塊 chunk 與
p 是否不同這項特性,來創造 overlaps chunk
• 創造出⼀一個 circle 的 singly linked list,這樣就可
以達到類似 UAF 的效果
• 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)
• 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)
• 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 …..
• 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 …..
• 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
• 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 情形發⽣生
• 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)
• 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
• 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)
• 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)
• 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)
• 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
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
Outline
• Fastbin corruption
• Shrink the chunk
• Extend the chunk
Shrink the chunk
• 假設存在⼀一個 off-by-one null byte 的漏洞
• ⺫⽬目的:
• 創造出 overlap chunk ,進⽽而更改其他 chunk
中的內容
• 主要利⽤用 unsortbin ,smallbin 會 unlink 做合併的
特性來達到我們的⺫⽬目的
Shrink the chunk
• ⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段,且
fastbin 是空的
0 0x41
0
0
0x171
0x101
A
B
C
• free(B)
Shrink the chunk
0 0x41
0
0
0x171
0x101
A
B
C
• free(A)
Shrink the chunk
0 0x41
0
0x170
0x171
0x100
A
B
C
• malloc(0x38)
Shrink the chunk
0 0x41
0
0x170
0x171
0x100
A
B
C
• read data to A and off-by-one overflow
Shrink the chunk
0 0x41
0
0x170
0x171
0x100
A
B
C
• malloc(0x80)
Shrink the chunk
0 0x41
0
0x170
0x100
0x100
A
B
C
• malloc(0x30)
Shrink the chunk
0 0x41
0
0x170
0x71
0x100
A
C
0 0x91
B
D
• free(B)
Shrink the chunk
0 0x41
0
0x170
0x31
0x100
A
C
0 0x91
0 0x41
B
D
E
• free(C)
Shrink the chunk
0 0x41
0
0x170
0x31
0x100
A
C
0 0x91
0x90 0x40
B
D
E
• free(C)
Shrink the chunk
0 0x41
0
0x170
0x31
0x100
A
C
0 0x91
0x90 0x40
B
D
此時會因為 C 是 smallbin
的⼤大⼩小的關係,
所以會檢測上⼀一塊是否 inused
E
• 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
Shrink the chunk
0 0x41
0
0x170
0x31
0x100
A
C
0 0x271
0x90 0x40
B
D
此時 unsortbin 存這
這塊⼤大 chunk ,
所以下次
malloc 會⽤用這⼀一塊
先份配給 user
E
• malloc(0x260)
Shrink the chunk
0 0x41
0
0x170
0x31
0x100
A
C
0 0x271
0x90 0x40
B
D
E
• 此時可任意改 D
Shrink the chunk
0 0x41
A
0 0x271
0x90 0x40
B
D
overlap chunk
Shrink the chunk
• overlap 的情況其實還蠻 powerful 的,如果中間
overlap 部分有 function pointer 或者是其他有⽤用
的 struct 可間接控制程式流程
• 也可以配合 fastbin freed chunk 更改 fd
Outline
• Fastbin corruption
• Shrink the chunk
• Extend the chunk
Extend the chunk
• 假設存在⼀一個 off-by-one 的漏洞
• ⺫⽬目的:
• ⼀一樣是創造出 overlap chunk ,進⽽而更改其他
chunk 中的內容
• 跟 shrink 很像,但主要是加⼤大 size 直接吃掉後⾯面
的 chunk ,只要後⾯面的 chunk header 有對上就
好
Extend the chunk
• ⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段
0 0x41
0
0
0x171
0x41
A
B
C
Extend the chunk
• free(A)
0 0x41
0
0
0x171
0x41
A
B
C
Extend the chunk
• malloc(0x38)
0 0x41
0
0
0x171
0x41
A
B
C
Extend the chunk
• read data to A and off-by-one overflow
0 0x41
0
0
0x171
0x41
A
B
C
Extend the chunk
• free(B)
0 0x41
0
0
0x1b1
0x41
A
B
C
0x1b1 = 0x171 + 0x40
為了之後要把 C 吃進去
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 所以會通過
Extend the chunk
• free(B)
0 0x41
0
0
0x1b1
0x41
A
B
C
此時這塊 chunk
會被合併到 top
(如果 C 後⾯面是 top)
或是加到 unsortbin 中
Extend the chunk
• malloc(0x1a0)
0 0x41
0
0
0x1b1
0x41
A
B
C
Extend the chunk
• 此時可以任意更改 C
0 0x41
0
0
0x1b1
0x41
A
B
Coverlap chunk
Extend the chunk
• 不過跟 Shrink ⽐比起來相對限制⽐比較多⼀一點,必須
要可控 off-by-one 的那個 byte ,Shrink 只要是
null byte 即可,相對⽐比較常⾒見,但也不好發現就
是了
Summary
• Heap exploitation 雖然已利⽤用來說會難⼀一點,但
常常在 Full mitigation 的情況下都可以利⽤用,畢竟
針對 heap 來說相對應的保護較少,也較難去實作
• Heap 就是⾨門藝術
Reference
• Glibc Adventures: The Forgotten Chunks
• google project zero
• glibc cross reference

Advanced heap exploitaion

  • 1.
  • 2.
    Who am I •Angelboy • 中央⼤大學資⼯工系碩⼠士班 • Advanced Defense Lab • Member of • Bamboofox CTF team • HITCON CTF team 2
  • 3.
    前⾔言 • 請先服⽤用 Heapexploitation • 這邊會在列出幾個常⾒見的 heap 漏洞利⽤用⽅方式 • 如果這份投影⽚片內容有錯誤的地⽅方,記得⼀一定要告訴我 • 環境 • glibc - 2.19 • kernel - 4.2 • 64 bit
  • 4.
    Outline • Fastbin corruption •Shrink the chunk • Extend the chunk
  • 5.
    Outline • Fastbin corruption •Shrink the chunk • Extend the chunk
  • 6.
    Fastbin corruption • 假設程式存在著double free 的漏洞 • ⺫⽬目的: • 我們可以利⽤用 fastbin chunk 改掉 fd 使得下下 次 malloc 該 chunk 時可以取得⾃自⼰己想要的位置 • 為了利⽤用 double free 的漏洞來改變 free chunk 中的 fd ,我們可以利⽤用⼀一些 fastbin 的特性達到 我們的⺫⽬目的,但我們也必須通過⼀一些 chunk 的檢 查
  • 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.
    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.
    Fastbin corruption • fastbin • 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.
    • fastbin layout Fastbincorruption 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.
    Fastbin corruption • 我們可以利⽤用fastbin 的 chunk 在 free 的時候只 檢查屬於該 size 的 fastbin 中的第⼀一塊 chunk 與 p 是否不同這項特性,來創造 overlaps chunk • 創造出⼀一個 circle 的 singly linked list,這樣就可 以達到類似 UAF 的效果
  • 12.
    • fastbin layout Fastbincorruption 0x128 0 0 …… 0 ….. 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array free(0x603090)
  • 13.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 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.
    • fastbin layout Fastbincorruption 0x20size 0x30 0x40 …. 0x80 …. prev_size size = 0x20 fd = null bk = null datadata 0x128 fast bin array 0x128 0 0xdeadbeef …… 0 ….. malloc(0x30)
  • 23.
    • fastbin layout Fastbincorruption 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.
    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.
    Outline • Fastbin corruption •Shrink the chunk • Extend the chunk
  • 26.
    Shrink the chunk •假設存在⼀一個 off-by-one null byte 的漏洞 • ⺫⽬目的: • 創造出 overlap chunk ,進⽽而更改其他 chunk 中的內容 • 主要利⽤用 unsortbin ,smallbin 會 unlink 做合併的 特性來達到我們的⺫⽬目的
  • 27.
    Shrink the chunk •⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段,且 fastbin 是空的 0 0x41 0 0 0x171 0x101 A B C
  • 28.
    • free(B) Shrink thechunk 0 0x41 0 0 0x171 0x101 A B C
  • 29.
    • free(A) Shrink thechunk 0 0x41 0 0x170 0x171 0x100 A B C
  • 30.
    • malloc(0x38) Shrink thechunk 0 0x41 0 0x170 0x171 0x100 A B C
  • 31.
    • read datato A and off-by-one overflow Shrink the chunk 0 0x41 0 0x170 0x171 0x100 A B C
  • 32.
    • malloc(0x80) Shrink thechunk 0 0x41 0 0x170 0x100 0x100 A B C
  • 33.
    • malloc(0x30) Shrink thechunk 0 0x41 0 0x170 0x71 0x100 A C 0 0x91 B D
  • 34.
    • free(B) Shrink thechunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0 0x41 B D E
  • 35.
    • free(C) Shrink thechunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0x90 0x40 B D E
  • 36.
    • free(C) Shrink thechunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x91 0x90 0x40 B D 此時會因為 C 是 smallbin 的⼤大⼩小的關係, 所以會檢測上⼀一塊是否 inused E
  • 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.
    Shrink the chunk 00x41 0 0x170 0x31 0x100 A C 0 0x271 0x90 0x40 B D 此時 unsortbin 存這 這塊⼤大 chunk , 所以下次 malloc 會⽤用這⼀一塊 先份配給 user E
  • 39.
    • malloc(0x260) Shrink thechunk 0 0x41 0 0x170 0x31 0x100 A C 0 0x271 0x90 0x40 B D E
  • 40.
    • 此時可任意改 D Shrinkthe chunk 0 0x41 A 0 0x271 0x90 0x40 B D overlap chunk
  • 41.
    Shrink the chunk •overlap 的情況其實還蠻 powerful 的,如果中間 overlap 部分有 function pointer 或者是其他有⽤用 的 struct 可間接控制程式流程 • 也可以配合 fastbin freed chunk 更改 fd
  • 42.
    Outline • Fastbin corruption •Shrink the chunk • Extend the chunk
  • 43.
    Extend the chunk •假設存在⼀一個 off-by-one 的漏洞 • ⺫⽬目的: • ⼀一樣是創造出 overlap chunk ,進⽽而更改其他 chunk 中的內容 • 跟 shrink 很像,但主要是加⼤大 size 直接吃掉後⾯面 的 chunk ,只要後⾯面的 chunk header 有對上就 好
  • 44.
    Extend the chunk •⼀一開始先 malloc 3 塊 chunk ⾄至 heap 段 0 0x41 0 0 0x171 0x41 A B C
  • 45.
    Extend the chunk •free(A) 0 0x41 0 0 0x171 0x41 A B C
  • 46.
    Extend the chunk •malloc(0x38) 0 0x41 0 0 0x171 0x41 A B C
  • 47.
    Extend the chunk •read data to A and off-by-one overflow 0 0x41 0 0 0x171 0x41 A B C
  • 48.
    Extend the chunk •free(B) 0 0x41 0 0 0x1b1 0x41 A B C 0x1b1 = 0x171 + 0x40 為了之後要把 C 吃進去
  • 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.
    Extend the chunk •free(B) 0 0x41 0 0 0x1b1 0x41 A B C 此時這塊 chunk 會被合併到 top (如果 C 後⾯面是 top) 或是加到 unsortbin 中
  • 51.
    Extend the chunk •malloc(0x1a0) 0 0x41 0 0 0x1b1 0x41 A B C
  • 52.
    Extend the chunk •此時可以任意更改 C 0 0x41 0 0 0x1b1 0x41 A B Coverlap chunk
  • 53.
    Extend the chunk •不過跟 Shrink ⽐比起來相對限制⽐比較多⼀一點,必須 要可控 off-by-one 的那個 byte ,Shrink 只要是 null byte 即可,相對⽐比較常⾒見,但也不好發現就 是了
  • 54.
    Summary • Heap exploitation雖然已利⽤用來說會難⼀一點,但 常常在 Full mitigation 的情況下都可以利⽤用,畢竟 針對 heap 來說相對應的保護較少,也較難去實作 • Heap 就是⾨門藝術
  • 55.
    Reference • Glibc Adventures:The Forgotten Chunks • google project zero • glibc cross reference