SlideShare a Scribd company logo
1 of 189
Download to read offline
Windows Heap Exploitation
Angelboy
Windows Heap Exploitation
• Windows Memory Allocator

• NT heap

• BackEnd

• Exploitation

• FrontEnd

• LowFragmentationHeap

• Exploitation
Windows memory allocator
• Win 10 的 memory allocator 非常複雜,基本上主要有下列列兩兩種

• Nt Heap

• Default memory allocator

• SegmentHeap

• Win10 中全新的 memory allocator 機制

• 部分系統程式及 UWP 會使⽤用
Windows memory allocator
• Nt Heap 中⼜又可分

• 後端管理理器 (Back-End)

• 前端管理理器 (Front-End)

• LowFragmentationHeap

• 基本上是為了了不讓記憶體過於破碎,相同⼤大⼩小的記憶體區塊分配到⼀一定數
量量後就會使⽤用 (連續分配相同記憶體區塊 18 次)

• Size <= 0x4000
Windows memory allocator
• ⽬目前會以 win 10 (1809) 為主

• OS build - 17763.379

• 之後版本可能不⼀一定完全正確

• 結構常常改動很⼤大,有個概念念後,到新的發⾏行行版本,需要⾃自⼰己去追⼀一下結
構
Windows memory allocator
• Overview
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Kernel
Front-End
Back-End
Windows memory allocator
• 在 LFH 沒啟⽤用下,我們呼叫 malloc
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
Kernel
Back-End
Windows memory allocator
• 啟⽤用 LFH 後,第⼀一次或 LFH 能⽤用的⽤用完時

會先跟 Back-End 要⼀一⼤大塊空間來來管理理
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Kernel
Front-End
Back-End
Windows memory allocator
• 啟⽤用 LFH 之後分配相同⼤大⼩小時,會直接給

Front-End 管理理
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Front-End
Windows memory allocator
• HEAP 可分為

• Process Heap

• Default heap

• 整個 process 共享,呼叫 api 時會⽤用到

• 會存在 _PEB 結構中

• CRT 中的函式時也會⽤用到

• 存在 crt_heap
Windows memory allocator
• HEAP 可分為

• Private heap

• 另外創建的 heap

• HeapCreate
Windows memory allocator
• Core data structure

• _HEAP_ENTRY (chunk)

• Malloc 出來來的基本結構

• 在前後端分配器中,長相會不太⼀一樣,但都是同⼀一個名字
Windows memory allocator
• _HEAP_ENTRY (chunk)
data
chunk header
chunk header
data
_HEAP
chunk header
.
.
.
malloc return value
Windows memory allocator
• Core data structure

• _HEAP

• 整個 memory allocator 中最核⼼心的結構,⽤用來來管理理該 heap

• 每個 Heap 都會有⼀一個 _HEAP 通常在 heap 開頭
Windows memory allocator
• _HEAP

• EncodeFlagMask

• Heap 初始化後會設置為
0x100000 在判斷是否要 encode
該 heap 中 chunk 的 header

• Encoding (_HEAP_ENTRY)

• ⽤用來來與 chunk header 做 xor 的
cookies
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• _HEAP

• BlocksIndex (_HEAP_LIST_LOOKUP_)

• Back-End 中,重要的結構之⼀一,⽤用
來來管理理 Back-End 中的 chunk ,後
⾯面會詳細敘述

• FreeList (_HEAP_ENTRY)

• 串串接 Back-End 中的所有 free chunk
,類似 unsorted bin

• Sorted list
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• _HEAP

• FrontEndHeap

• 指向管理理 FrontEnd 的 Heap 的結構

• FrontEndHeapUsageData

• 指向⼀一個對應各⼤大⼩小 chunk 的陣列列

• 紀錄各種⼤大⼩小 chunk 使⽤用次數,到
達某個程度時會去 enable 該對應⼤大
⼩小 chunk 的 Front-End allocator
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• Nt Heap

• 後端管理理器 (Back-End)

• 前端管理理器 (Front-End)
Nt heap
• Nt Heap

• 後端管理理器 (Back-End)

• Data structure

• 分配機制
Windows memory allocator
• _HEAP_ENTRY (chunk)

• 分為三種狀狀況

• Allocated chunk

• Freed chunk

• VirtualAlloc chunk
Nt heap
• _HEAP_ENTRY (chunk)

• PreviousBlockPrivateData

• 基本上可為前⼀一塊 chunk 的 data,因
為 chunk 必須對⿑齊 0x10

• Size

• Chunk 的 size 但存入⽅方式並不是直接
存 size ⽽而是存 (size >>4) 後的值
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Flag

• 表⽰示該 chunk 是否 inused

• SmallTagIndex

• 前⾯面三個 byte 的 Checksum(三個
byte 做 xor),之後拿 header 出來來時會
驗證
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• PreviousSize

• 相鄰的前⼀一塊 chunk 的 Size ,這邊ㄧ
樣是 (Size >> 4) 過後的數值

• SegmentOffset

• 某些情況下⽤用來來找 segment 的
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Unusedbyte

• 紀錄 user malloc 後所剩 chunk 的空間

• 可以⽤用來來判斷 chunk 的狀狀態判斷 chunk
是 FrontEnd or BackEnd

• User Data

• User 所使⽤用的區塊
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Flink

• 指向 linked list 中下⼀一塊 chunk

• Blink

• 指向 linked list 中上⼀一塊 chunk

• Unusedbyte 

• 恆為 0
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
freed
Flink
Blink
Nt heap
• _HEAP_VIRTUAL_ALLOC_ENTRY (mmap
chunk)

• Flink

• 指向下⼀一塊 VirtualAlloc 出來來的 chunk

• Blink

• 指向上⼀一塊 VirtualAlloc 出來來的 chunk
User Data
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
inused
Flink
Blink
…
Nt heap
• _HEAP_VIRTUAL_ALLOC_ENTRY (mmap
chunk)

• Size

• 這邊的 size 指的是 unused size,且
沒有 shift 過

• Unusedbyte

• 恆為 4
User Data
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
inused
Flink
Blink
…
Nt heap
• FreeLists (_HEAP_ENTRY)

• 在 Free 完⼀一塊 chunk 後,會將該 chunk 放到 FreeLists 中,並會依照⼤大
⼩小決定插在 FreeLists 中的位置
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
Nt heap
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateDat
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Flink
Blink
_HEAP
Nt heap
• Remark

• 關於 header encoding

• 所有的 chunk 都會經過 xor 過,在存 chunk header 時,會將整個
header^(_HEAP->Encoding) 在存入

• decode 時會驗證 check sum 確保沒被改掉

• 驗證⽅方式為 encode_header^(_HEAP->Encoding) 後的值,前 3 byte
xor 後和第 4 byte 比對
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• 主要⽤用來來管理理各種不同⼤大⼩小的 freed chunk 的結構,⽅方便便在配置記憶體
時,能快速的找到適合的 chunk
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ExtendedLookup (_HEAP_LIST_LOOKUP)

• 指向下⼀一個 ExtendedLookup

• 通常下⼀一個會管理理更更⼤大塊 chunk 所⽤用的
結構

• ArraySize

• 該結構會管理理的,最⼤大 chunk 的⼤大⼩小,
通常為 0x80 (實際上是 0x800)
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ItemCount

• ⽬目前該結構所管理理的 chunk 數

• OutofRangeItems

• 超出該結構所管理理⼤大⼩小的 chunk 的
數量量
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• BaseIndex

• 該結構所管理理的 chunk 的起始 index,
⽤用來來從 ListHint 找適合⼤大⼩小的 free
chunk ⽤用的,下⼀一個 BlocksIndex 將從
這個 index 的最⼤大值作為 BaseIndex

• ListHead (_HEAP_ENTRY)

• FreeList 的 Head
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ListsInUseUlong

• ⽤用在判斷 ListHint 中是否有適合⼤大⼩小的
chunk,是⼀一個 bitmap 

• ListHint 

• 重要結構,⽤用來來指向相對應⼤大⼩小的 chunk
array

• 其⽬目的就在於更更快速找到適合⼤大⼩小的 chunk

⼤大⼩小為 0x10 為⼀一個間隔
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageDat
…
_HEAP
BlocksIndex
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivate
Flink
Blink
Chunk header(0x160)
PreviousBlockPrivat
ListHint
Flink
Flink
Flink
ListHint[7]
ListHint[0x11]
ListHint[0x16]
000001…1…1000000000
ListsInUseUlong
Nt heap
• Nt Heap

• 後端管理理器 (Back-End)

• Data structure

• 分配機制
Nt heap
• Allocate (RtlpAllocateHeap)

• 基本上分為三種

• Size <= 0x4000

• 0x4000 < size <= 0xff000

• Size > 0xff000
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• 基本上主要分配都會在 RtlpAllocateHeap

• 接著會去看該 size 對應到的 FrontEndHeapStatusBitmap 使否有啟⽤用 LFH

• 沒有的話會對對應到的 FrontEndHeapUsageData 加上 0x21

• 並且檢查值是否超過 0xff00 或者 & 0x1f 後超過 0x10

通過條件就會啟⽤用 LFH
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• 接下來來會先看對應到的 ListHint 是否有值,會以 ListHint 中的 chunk 為優先

• 如果有適合剛好的 chunk 在 ListHint 上則移除 ListHint,並且會看該 chunk 的 Flink ⼤大⼩小是否
剛好也是同樣 size

• 是的話就將 LintHint 填上 Flink

• 不是則清空

• 最後則 unlink 該 chunk 把這塊 chunk 從 linked list 中移除返還給使⽤用者,並將 header xor
回去
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• 如果沒有剛好適合的

• 從比較⼤大的 ListHint 中找,有找到比較⼤大的後如果該 chunk 將會從 ListHint 則移除之,
並看下⼀一塊 chunk size 有沒有剛好⼤大⼩小,有則補上,並且 unlink 將該 chunk 移除
freelist

• 最後將該 chunk 做切割,剩下的⼤大⼩小重新加入 Freelist ,如果可以放進 ListHint 就會放
進去

• 然後回傳切好的 chunk 給使⽤用者,這邊也會對切割後跟回傳使⽤用者的 chunk header xor
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• 如果 FreeList 中都沒有

• 嘗試 ExtendHeap 加⼤大 heap 空間

• 再從 extend 出來來的 chunk 拿

• 接著後⾯面⼀一樣切割,放回 ListHint,xor header
Nt heap
• Allocate (RtlpAllocateHeap)

• 0x4000 < size <= 0xff000

• 除了了沒有對 LFH 相關的操作外,其餘都跟 0x4000 ⼀一樣
Nt heap
• Allocate (RtlpAllocateHeap)

• Size > 0xff000 (VirtualMemoryThreshold << 4)

• 直接使⽤用 ZwAllocateVirtualMemory

• 類似 mmap 直接給⼀一⼤大塊,並且會插入 _HEAP->VirtualAllocdBlocks
這個 linked list 中

• 這個 linked list 是串串接該 Heap VirtualAllocate 出來來的區段⽤用的
Nt heap
• Free (RtlpFreeHeap)

• 可分為

• Size <= 0xff000 

• Size > 0xff000
Nt heap
• Free (RtlpFreeHeap)

• Size <= 0xff000 

• 會先檢查 alignment、利利⽤用 unused byte 判斷該 chunk 狀狀態

• 如果是非 LFH 下,會對對應到的 FrontEndHeapUsageData 減 1

• 接著會判斷前後的 chunk 是否為 freed ,是的話就合併

• 此時會把可以合併的 chunk 做 unlink ,並從 ListHint 移除

• 移除⽅方式與前⾯面相同,看看下⼀一塊是不是同樣⼤大⼩小,是的話補上 ListHint
Nt heap
• Free (RtlpFreeHeap)

• Size <= 0xff000 

• 合併完後, update size & prevsize ,然後會看看是不是最前跟最後,
是就插入,不⾏行行插入就從 ListHint 中插入,並且 update ListHint,插入
時也會對 linked list 做檢查

• 但這檢查不會 abort

• 其原因主要因為不做 unlink 寫入
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Free(Q)
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find Prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Prevchunk =
Chunk address
-
(prevsize << 4)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find Prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Prevchunk =
chunk addr - 0x70
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Decode prevchunk

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check checksum
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
SmallTagInex ==

(size & 0xff)
xor
(size >> 8)
xor
Flag
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check checksum
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
7 ==

0x7^0x0^0x0
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

linked list
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
P->Flink->Blink == 

P->Blink->Flink == 

P
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find 

BlocksIndex
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find suitable 

BlocksIndex
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
P->size < ArraySize
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
ListHint[7] ==
Prevchunk
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
prevchunk->Flink ==
ListHead
成立的話會準備 update

ListHint
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint[7]->Flink
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
decode
prevchunk->Flink
And check
the checksum
由於前⼀一張 slide 不成立
要去驗 Flink 的 size

ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint[7]->Flink
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Size == 

prevchunk->Flink->size
如果相等,直接將 ListHint
換成下⼀一塊

ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

ListHint[7]
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ListHint[7] =

prevchunk->Flink
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Unlink

prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Prevchunk->Blink->Flink

= Prevchunk->Flink

Prevchunk->Flink->Blink
= Prevchunk->Blink
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

prevchunk

and next chunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Prevchunk->size =

0x11 + Prevchunk->size(7)
R->Prevsize = 0x18
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

next chunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
檢查下⼀一塊 chunk

使否 freed
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find suitable

BlocksIndex

For P
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

P->Size < ArraySize
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Search

insert

point
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

P->size <
ListHead->Blink->Size

P->size <
ListHead->Flink->Size
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Insert

linked list
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

S->Blink->Flink

== S
If not pass it will not 

abort

But it will not unlink
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
If LintHint[0x18] == NULL

LintHint[0x18] = P
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x18)
SmallTagIndex = 

(size >> 8) ^

(size & 0xff) ^

Flag
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Encode

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0xda)
Flag (0xab)
SmallTagIndex (0x41)
P->header ^

_HEAP->Encoding
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
Nt heap
• Free (RtlpFreeHeap)

• Size > 0xff000 

• 檢查該 chunk 的 linked list 並從 _HEAP->VirtualAllocdBlocks 移除

• 接著使⽤用 RtlpSecMemFreeVirtualMemory 將 chunk 整個 munmap 掉
Back-End Exploitation
• Unlink

• 基本上與 Linux 中的 unlink 很類似,繞過⽅方法也差不多

• 簡⽽而⾔言之就是利利⽤用從 linked listed 移除 node 的⾏行行為來來做有限制的寫入

• 要注意的是在會 decode 的地⽅方,都要讓他正常 decode

• 也就是 check sum 要過

• 另外⼀一點是 Flink 及 Blink 並不是指向 chunk 開頭,⽽而是直接指向 User data 部分,也就是
不太需要做偏移偽造 chunk

• 所以找到⼀一個指向該 userdata 的 pointer 讓他繞過 double linked list 的驗證就好了了
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
A
A
Chunk header (0x110)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
UAF
T
A
A
A
Chunk header (0x110)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
Free(Q)
T
A
Q
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
ListHead
QListHint[0x11]
free(S)
Update ListHint
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
S
SListHint[0x11]
Q
ListHead
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
S
SListHint[0x11]
Q
ListHead
Let’s corrupt the heap !
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
free(P)
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Check next chunk 

is free
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Decode 

chunk Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead*(&Q)
==
*(&Q)
== Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead*(&Q)
==
*(&Q)
== Q
Pass the check !!
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Find 

BlockIndex
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Check

ListHint[0x11]
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead由於 S != Q

所以不會對 ListHint

做任何處理理
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Unlink !!
Q->Blink->Flink
= Q->Flink
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q - 8
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUnlink !!
Q = &Q-8
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q - 8
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Unlink !!
Q->Flink->Blink
= Q->Blink
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUnlink !!
Q = &Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUpdate 

chunk size
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadUpdate 

chunk size
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Search insert point
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadFind the last one
And decode it
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
P
Find the first one
And decode it
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
我們要插在 A 前
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Check

A->Blink->Flink
== A
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Check

Q->Flink
== A
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadFailed

不過不會 abort
只是不會 insert
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Update 

ListHint
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
P
PListHint[0x22]
Back-End Exploitation
• Edit Q

• 我們可以把 Q 周圍的 pointer 寫掉

• 最後可達成任意記憶體讀寫
P
&Q
R
S
T
Back-End Exploitation
• Edit Q

• 我們可以把 Q 周圍的 pointer 寫掉

• 最後可達成任意記憶體讀寫

• 可對 Target 1 - 4 做寫入
P
Target 1
Target 2
Target 3
Target 4
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll.dll

• PebLdr

• binary address

• Kernel32.dll
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• kernelbase

• KERNELBASE!BasepFilterInfo

• Stack address
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll.dll

• _HEAP_LOCK

• _HEAP->LockVariable.Lock

• CriticalSection->DebugInfo

• 指向 ntdll
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll!PebLdr

• _PEB_LDR_DATA

• 可找出所有 DLL 的位置

• 不過缺點是最後⼀一兩兩個 byte 可能是 0

• 可先找出 binary base 從 IAT 找 kernel32
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• BinaryBase

• 從 IAT 找出 Kernel32 位置
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• Kernel32

• 重要 dll 很多常⽤用 function 都在這 (CreateFile, ReadFile,WriteFile) 

• IAT

• 獲得 kernelbase.dll 位置
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• kernelbase

• KERNELBASE!BasepFilterInfo

• 指向 Heap 上的結構

• 裡⾯面有⾼高機率會有 stack pointer

• https://j00ru.vexillium.org/2016/07/disclosing-stack-data-from-the-default-
heap-on-windows/
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• 如果 BasepFilterInfo 中沒有 stack address

• 因 BasepFilterInfo 內容會有 stack address 是因為未初始化因素,所
以有機會沒有 stack address

• 可以從 PEB 往前或往後算 1 個 page ,通常會是 TEB 位置,上⾯面繪
有 stack 尾段的位置,可以藉由該位置找出 retrun address
Back-End Exploitation
• After arbitrary memory reading and writing

• Write 

• Return address

• Control RIP

• ROP to VirtualProtect/VirtualAlloc

• Jmp to shellcode
Windows memory allocator
• Nt Heap

• 後端管理理器 (Back-End)

• 前端管理理器 (Front-End)
Windows memory allocator
• Nt Heap

• 前端管理理器 (Front-End)

• ⽬目前 win10 主要使⽤用

• LowFragmentationHeap

• 在非 Debug 下才會 enable

• Size < 0x4000
Windows memory allocator
• Nt Heap

• 前端管理理器 (Front-End)

• Data Structure

• 分配機制
Windows memory allocator
• Nt Heap

• 前端管理理器 (Front-End)

• Data Structure

• 分配機制
LFH
• FrontEndHeap (_LFH_HEAP)

• HEAP (_HEAP)

• 指向對應到的 _HEAP

• Buckets (_HEAP_BUCKET)

• ⽤用來來尋找配置⼤大⼩小對應到 Block ⼤大⼩小
的陣列列結構
…
Heap0x18
0x2a4
…
Buckets
SegmentInfoArray
…
…
LocalData
0x4a8
0xcc0
LFH
• FrontEndHeap (_LFH_HEAP)

• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• _HEAP_LOCAL_SEGMENT_INFO array,
不同⼤大⼩小對應到不同的 Segment_info 結
構,主要管理理對應到的 Subsegment 的資訊

• LocalData (_HEAP_LOCAL_DATA)

• 其中有個欄欄位指向 LFH 本⾝身,通常⽤用來來找
回 LFH
…
Heap0x18
…
Buckets
SegmentInfoArray
…
…
LocalData
0x2a4
0x4a8
0xcc0
LFH
• Buckets (_HEAP_BUCKET)

• BlockUnits

• 要分配出去的⼀一個 block ⼤大⼩小 >> 4

• SizeIndex

• 使⽤用者需要的⼤大⼩小 >> 4
BlockUnits
Buckets
SizeIndex
…
BlockUnits
SizeIndex
…
…
…
Buckets[0]
Buckets[1]
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• LocalData (_HEAP_LOCAL_DATA)

• 對應到 _LFH_HEAP->LocalData ⽅方便便
從 SegmentInfo 找回 _LFH_HEAP

• BucketIndex

• 對應到的 BucketIndex
LocalData
SegmentInfoArray[x]
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• ActiveSubsegment (_HEAP_SUBSEGMENT)

• 極為重要結構

• 對應到分配出去的 Subsegment

• 其⽬目的在於管理理 Userblock

• 記錄了了剩餘多少 chunk 

• 該 Userblock 最⼤大分配數等等
SegmentInfoArray[x]
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• CachedItems (_HEAP_SUBSEGMENT)

• _HEAP_SUBSEGMENT array

• 存放對映到該 SegmentInfo 且還有可
以分配 chunk 給 user 的Subsegment 

• 當 ActiveSubsegment ⽤用完時,會從
這邊填充,置換掉 ActiveSubsegment
SegmentInfoArray[x]
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
…
Heap
…
…
…
LocalData
0x18
0x2a4
0x4a8
0xcc0
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• LocalInfo
(_HEAP_LOCAL_SEGMENT_INFO)

• 指回對應到的
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• UserBlock (_HEAP_USERDATA_HEADER)

• LFH 的記憶體分配池

• 也就是要分配出去的 Chunk (Block)
所在位置

• 開頭會有些 metadata 管理理這些 chunk

• 重要結構
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• AggregateExchg (_INTERLOCK_SEQ)

• ⽤用來來管理理對應到的 UserBlock 中還有
多少 freed chunk

• LFH ⽤用這個判斷是否還從該
UserBlock 分配

• 同時也有 Lock 的作⽤用
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• BlockSize

• 在該 UserBlock 中每個 Block (chunk)的⼤大⼩小

• BlockCount

• 在該 UserBlock 中 Block 的總數

• SizeIndex

• 該 UserBlock 對應到的 SizeIndex
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• AggregateExchg (_INTERLOCK_SEQ)

• Depth

• 該 UserBlock 所剩下的 Freed chunk 數量量

• Lock

• 就是 Lock
AggregateExchg
Depth0x0
Hint (15bit)
Lock (1bit)
0x8
LFH
• UserBlock (_HEAP_USERDATA_HEADER)

• SubSegment

• 指回對應的 Subsegment

• EncodeOffsets

• ⽤用來來驗證 chunk header 是否有被改過

• BusyBitmap

• 記錄該 UserBlock 哪些 chunk 有在⽤用的
bitmap
SubSegment
UserBlock
…
EncodedOffsets
BusyBitmap
0x8
0x18
0x20
chunk header
chunk header
chunk header
LFH
• UserBlock (_HEAP_USERDATA_HEADER)

• Block (chunk)

• LFH 回傳給使⽤用者的 chunk
SubSegment
UserBlock
…
EncodedOffsets
BusyBitmap
0x8
0x18
0x20
chunk header
chunk header
chunk header
LFH
• _HEAP_ENTRY (chunk)

• SubSegmentCode

• Encode 過的 metadata ⽤用來來推回
userblock 的位置

• PreviousSize

• 該 chunk 在 UserBlock 中的 index
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
LFH
• _HEAP_ENTRY (chunk)

• Unusedbyte

• Unusedbyte & 0x80 is true
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
LFH
• _HEAP_ENTRY (chunk)

• Unusedbytes

• 恆為 0x80

• ⽤用來來判斷是否為 LFH 的 Free chunk
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Freed
LFH
• Remark

• 關於 EncodedOffsets

• 在 UserBlock 初始化時設置,其算法為下⾯面四個值的 xor

• (sizeof(userblock header) | (BlockUnit*0x10 << 16))

• LFHkey

• Userblock address

• _LFH_HEAP address
LFH
• Remark

• 關於 LFH header encoding

• 所有的 chunk header 在初始化時都會經過 xor 過,算法為下⾯面個值的 xor

• _HEAP address

• LFHkey

• Chunk address >> 4

• ((chunk address) - (UserBlock address)) << 12
LFH
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Windows memory allocator
• Nt Heap

• 前端管理理器 (Front-End)

• Data Structure

• 分配機制
Windows memory allocator
• Nt Heap

• 前端管理理器 (Front-End)

• 初始化

• 在 FrontEndHeapUsageData[x] & 0x1f > 0x10 時,下⼀一次的 allocate 會對 LFH 做出初始化 

• 會先 ExtendFrontEndUsageData 及增加更更⼤大的 BlocksIndex (0x80-0x400)

• 建立 FrontEndHeap

• 初始化 SegmentInfoArrays[idx]

• 接下來來在 allocate 相同⼤大⼩小的 chunk 就會開始使⽤用 LFH
Windows memory allocator
• LFH(初始化)

• malloc(0x40) * 16
FrontEndHeapUsageData
…
0x210
此時可 enable LFH 範圍為
index 0x0 - 0x80
Windows memory allocator
• LFH(初始化)

• malloc(0x40) (第 17 次)
FrontEndHeapUsageData
…
0x231 0x231 & 0x1f > 0x10
Windows memory allocator
• LFH(初始化)
FrontEndHeapUsageData
…
0x231
heap->CompatibilityFlag |= 0x20000000
設置上這個 flag 後
下次 allocate 時會去初始化LFH

Windows memory allocator
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x231
BlocksIndex
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Windows memory allocator
• LFH(初始化)

• malloc(0x40) (第 18 次)

• ExtendFrontEndUsageData 及增加更更⼤大的 BlocksIndex
(0x80-0x400) ,並設置對應的 bitmap

• 並在該對應的 FrontEndHeapUsageData 寫上對應的
index,此時可 enable LFH 範圍變為 (idx: 0-0x400)

• 建立並初始化 FrontEndHeap (mmap)

• 初始化 SegmentInfoArrays[idx]

• 在 SegmentInfoArrays[BucketIndex] 填上 segmentInfo
FrontEndHeapUsageData
…
0x4
Windows memory allocator
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x251 0x4
BlocksIndex
ExtendedLookup
ArraySize(0x80)
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex (0x0)
ListHead
ListsInUseUlong
ListHint
BlocksIndex
ExtendedLookup
ArraySize (0x400)
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex (0x80)
ListHead
ListsInUseUlong
ListHint
Windows memory allocator
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x251 0x4
Windows memory allocator
• LFH(初始化)

• malloc(0x40) (第 19 次)

• Allocate Userblock 並初始化

• 設置對應的 chunk 

• 設置對應的 ActiviteSubsegment

• 隨機返回其中的⼀一個 chunk
Userblock metadata
Chunk 00
Chunk 01
…
Chunk MaxBlockCount
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• 先看看 ActiveSubsegment 中是否有可分配的 chunk

• 從 ActiveSubsegment->depth 判斷

• 如果沒有則會從 CachedItem 找,有找到的話會把 ActiveSubsegment
換成 CachedItem 中的 SubSegment
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Find SegementIfoArray by bucket->SizeIndex
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Find SegementIfoArray by bucket->SizeIndex
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ActiveSubsegment
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ActiveSubsegment
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ArgregateExchg.Depth not 0
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ArgregateExchg.Depth not 0
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check Userblock
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• 取得 RtlpLowFragHeapRandomData[x] 上的直

• 下⼀一次會從 RtlpLowFragHeapRandomData[x+1] 取

• x 為 1 byte ,當下次輪輪回 x 則會 x = rand() %256 繼續取

• RtlpLowFragHeapRandomData 為⼀一個 random 256 byte 的陣列列

• 範圍為 0x0 - 0x7f
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• 最獲得的 index 為 

• RtlpLowFragHeapRandomData[x]*maxidx >> 7 

• 如果 collision 則往後取最近的

• 檢查 (unused byte & 0x3f) !=0 (表⽰示 chunk 是 freed)

• 最後設置 index 及 unused byte 就返回給使⽤用者
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
• Get an index

• RtlpLowFragHeapRandomData[x]*maxidx >> 7

• 檢查該 index 對映到的 bitmap 是否為 0

• 是 0 則返回對映的 bitmap

• 非 0 擇取最近的下⼀一個
chunk header
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
• 算出來來的 index 發現已⽤用過

• 會取下⼀一個

• 並設置對映的 bitmap
chunk header
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
• 算出來來的 index 發現已⽤用過

• 會取下⼀一個

• 並設置對映的 bitmap
chunk header
Windows memory allocator
• LFH

• Free (RtlFreeHeap)

• Update unused byte in chunk header

• Find the index of the Chunk and reset Userblock->BusyBitmap

• Update ActiveSubsegment->AggregateExchg

• 如果 Free 的 chunk 不屬於當前 ActiveSubsegment 則會看看能不能放
進 cachedItems ,可以放就放進去
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• ⽤用 chunk header 尋找
UserBlock
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• ⽤用 chunk header 尋找
UserBlock

• 找回對映的 SubSegment
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• ⽤用 chunk header 尋找
UserBlock

• 找回對映的 SubSegment

• 設置 unused byte = 0x80

• 清除對映的 bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• ⽤用 chunk header 尋找
UserBlock

• 找回對映的 SubSegment

• 設置 unused byte = 0x80

• 清除對映的 bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• ⽤用 chunk header 尋找
UserBlock

• 找回對映的 SubSegment

• 設置 unused byte = 0x80

• 清除對映的 bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADERLocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
Depth (1)
Hint (15bit)
Lock (1bit)
_INTERLOCK_SEQ
CachedItems
ActiveSubsegmet
不等於 Free 掉 chunk 的

SubSegment
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADERLocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
Depth (1)
Hint (15bit)
Lock (1bit)
_INTERLOCK_SEQ
CachedItems
CachedItems[0]
LFH Exploitation
• Reuse attack

• 假設我們有 Use after free 的漏洞洞

• 但因為 LFH 的隨機性,導致無法預側下⼀一塊 chunk 會在哪,使得我們
很難利利⽤用

• 這時可以填滿 Userblock 的⽅方式,在 free 掉其中⼀一塊,那麼下次該
chunk 必定會拿到同⼀一塊,我們可以利利⽤用這個特性,拿到 overlap
chunk 做進⼀一步利利⽤用
LFH Exploitation
• normal case

• malloc(sizeof(A))
Userblock header
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header
fptr
LFH Exploitation
• normal case

• free(A)
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(A))
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header B
fptr
Hard to use
LFH Exploitation
• Reuse attack 

• malloc(sizeof(A))
Userblock header
LFH Exploitation
• Reuse attack 

• malloc(sizeof(B)) x 6
Userblock header
fptr
LFH Exploitation
• Reuse attack 

• free(A)
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• malloc(sizeof(B))
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• A->fptr
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• A->fptr
Userblock header
B
B B B
fptr B B
Hijack the control flow !
Reference
• https://github.com/saaramar/
35C3_Modern_Windows_Userspace_Exploitation

• http://illmatics.com/Understanding_the_LFH.pdf

• https://github.com/saaramar/Deterministic_LFH
Thank you for listening
!189
angelboy@chroot.org @scwuaptx
!189

More Related Content

What's hot

Heap exploitation
Heap exploitationHeap exploitation
Heap exploitationAngel Boy
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolveAngel Boy
 
Reliable Windows Heap Exploits
Reliable Windows Heap ExploitsReliable Windows Heap Exploits
Reliable Windows Heap Exploitsamiable_indian
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3Angel Boy
 
Linux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowLinux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowAngel Boy
 
DeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelDeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelPeter Hlavaty
 
Modern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesModern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesMichael Scovetta
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27Sheng-Hao Ma
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程Weber Tsai
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談hackstuff
 
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytesWindows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytesPeter Hlavaty
 
Tez Shuffle Handler: Shuffling at Scale with Apache Hadoop
Tez Shuffle Handler: Shuffling at Scale with Apache HadoopTez Shuffle Handler: Shuffling at Scale with Apache Hadoop
Tez Shuffle Handler: Shuffling at Scale with Apache HadoopDataWorks Summit
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報耀德 蔡
 
You didnt see it’s coming? "Dawn of hardened Windows Kernel"
You didnt see it’s coming? "Dawn of hardened Windows Kernel" You didnt see it’s coming? "Dawn of hardened Windows Kernel"
You didnt see it’s coming? "Dawn of hardened Windows Kernel" Peter Hlavaty
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented ProgrammingAngel Boy
 
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Monica Beckwith
 
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco GrassiShakacon
 

What's hot (20)

Heap exploitation
Heap exploitationHeap exploitation
Heap exploitation
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolve
 
Reliable Windows Heap Exploits
Reliable Windows Heap ExploitsReliable Windows Heap Exploits
Reliable Windows Heap Exploits
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3
 
Linux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowLinux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflow
 
DeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows KernelDeathNote of Microsoft Windows Kernel
DeathNote of Microsoft Windows Kernel
 
Modern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesModern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and Techniques
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27
 
Execution
ExecutionExecution
Execution
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程
 
Kernel Pool
Kernel PoolKernel Pool
Kernel Pool
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談
 
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytesWindows Kernel Exploitation : This Time Font hunt you down in 4 bytes
Windows Kernel Exploitation : This Time Font hunt you down in 4 bytes
 
Tez Shuffle Handler: Shuffling at Scale with Apache Hadoop
Tez Shuffle Handler: Shuffling at Scale with Apache HadoopTez Shuffle Handler: Shuffling at Scale with Apache Hadoop
Tez Shuffle Handler: Shuffling at Scale with Apache Hadoop
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報
 
You didnt see it’s coming? "Dawn of hardened Windows Kernel"
You didnt see it’s coming? "Dawn of hardened Windows Kernel" You didnt see it’s coming? "Dawn of hardened Windows Kernel"
You didnt see it’s coming? "Dawn of hardened Windows Kernel"
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented Programming
 
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
Garbage First Garbage Collector (G1 GC) - Migration to, Expectations and Adva...
 
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
 
WSL Reloaded
WSL ReloadedWSL Reloaded
WSL Reloaded
 

Similar to Windows 10 Nt Heap Exploitation (Chinese version)

D2 t2 steven seeley - ghost in the windows 7 allocator
D2 t2   steven seeley - ghost in the windows 7 allocatorD2 t2   steven seeley - ghost in the windows 7 allocator
D2 t2 steven seeley - ghost in the windows 7 allocator_mr_me
 
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016DataStax
 
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...Spark Summit
 
Engineering fast indexes
Engineering fast indexesEngineering fast indexes
Engineering fast indexesDaniel Lemire
 
Presentation on Heap Sort
Presentation on Heap Sort Presentation on Heap Sort
Presentation on Heap Sort Amit Kundu
 
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018Codemotion
 
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heRecon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heLiang Chen
 
Computer Introduction
Computer IntroductionComputer Introduction
Computer IntroductionSpy Seat
 
Advance computer architecture
Advance computer architectureAdvance computer architecture
Advance computer architecturesuma1991
 
Hash Functions FTW
Hash Functions FTWHash Functions FTW
Hash Functions FTWsunnygleason
 
Code and Memory Optimisation Tricks
Code and Memory Optimisation Tricks Code and Memory Optimisation Tricks
Code and Memory Optimisation Tricks Sperasoft
 
Code and memory optimization tricks
Code and memory optimization tricksCode and memory optimization tricks
Code and memory optimization tricksDevGAMM Conference
 
A survey on Heap Exploitation
A survey on Heap Exploitation A survey on Heap Exploitation
A survey on Heap Exploitation Alireza Karimi
 
Lightning Talk: MongoDB Sharding
Lightning Talk: MongoDB ShardingLightning Talk: MongoDB Sharding
Lightning Talk: MongoDB ShardingMongoDB
 
Jurczyk windows kernel reference count vulnerabilities. case study
Jurczyk   windows kernel reference count vulnerabilities. case studyJurczyk   windows kernel reference count vulnerabilities. case study
Jurczyk windows kernel reference count vulnerabilities. case studyDefconRussia
 
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...Spark Summit
 
Compromising Linux Virtual Machines with Debugging Mechanisms
Compromising Linux Virtual Machines with Debugging MechanismsCompromising Linux Virtual Machines with Debugging Mechanisms
Compromising Linux Virtual Machines with Debugging MechanismsRussell Sanford
 

Similar to Windows 10 Nt Heap Exploitation (Chinese version) (20)

D2 t2 steven seeley - ghost in the windows 7 allocator
D2 t2   steven seeley - ghost in the windows 7 allocatorD2 t2   steven seeley - ghost in the windows 7 allocator
D2 t2 steven seeley - ghost in the windows 7 allocator
 
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
Myths of Big Partitions (Robert Stupp, DataStax) | Cassandra Summit 2016
 
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...
Engineering Fast Indexes for Big-Data Applications: Spark Summit East talk by...
 
Engineering fast indexes
Engineering fast indexesEngineering fast indexes
Engineering fast indexes
 
Bloom filters
Bloom filtersBloom filters
Bloom filters
 
Presentation on Heap Sort
Presentation on Heap Sort Presentation on Heap Sort
Presentation on Heap Sort
 
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018
Managing your Black Friday Logs - Antonio Bonuccelli - Codemotion Rome 2018
 
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heRecon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
 
Computer Introduction
Computer IntroductionComputer Introduction
Computer Introduction
 
Advance computer architecture
Advance computer architectureAdvance computer architecture
Advance computer architecture
 
Hash Functions FTW
Hash Functions FTWHash Functions FTW
Hash Functions FTW
 
Code and Memory Optimisation Tricks
Code and Memory Optimisation Tricks Code and Memory Optimisation Tricks
Code and Memory Optimisation Tricks
 
Code and memory optimization tricks
Code and memory optimization tricksCode and memory optimization tricks
Code and memory optimization tricks
 
A survey on Heap Exploitation
A survey on Heap Exploitation A survey on Heap Exploitation
A survey on Heap Exploitation
 
Lightning Talk: MongoDB Sharding
Lightning Talk: MongoDB ShardingLightning Talk: MongoDB Sharding
Lightning Talk: MongoDB Sharding
 
Why learn Internals?
Why learn Internals?Why learn Internals?
Why learn Internals?
 
Jurczyk windows kernel reference count vulnerabilities. case study
Jurczyk   windows kernel reference count vulnerabilities. case studyJurczyk   windows kernel reference count vulnerabilities. case study
Jurczyk windows kernel reference count vulnerabilities. case study
 
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...
Deep Dive into Project Tungsten: Bringing Spark Closer to Bare Metal-(Josh Ro...
 
Compromising Linux Virtual Machines with Debugging Mechanisms
Compromising Linux Virtual Machines with Debugging MechanismsCompromising Linux Virtual Machines with Debugging Mechanisms
Compromising Linux Virtual Machines with Debugging Mechanisms
 
Lecture 25
Lecture 25Lecture 25
Lecture 25
 

Recently uploaded

New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 

Recently uploaded (20)

New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 

Windows 10 Nt Heap Exploitation (Chinese version)

  • 2. Windows Heap Exploitation • Windows Memory Allocator • NT heap • BackEnd • Exploitation • FrontEnd • LowFragmentationHeap • Exploitation
  • 3. Windows memory allocator • Win 10 的 memory allocator 非常複雜,基本上主要有下列列兩兩種 • Nt Heap • Default memory allocator • SegmentHeap • Win10 中全新的 memory allocator 機制 • 部分系統程式及 UWP 會使⽤用
  • 4. Windows memory allocator • Nt Heap 中⼜又可分 • 後端管理理器 (Back-End) • 前端管理理器 (Front-End) • LowFragmentationHeap • 基本上是為了了不讓記憶體過於破碎,相同⼤大⼩小的記憶體區塊分配到⼀一定數 量量後就會使⽤用 (連續分配相同記憶體區塊 18 次) • Size <= 0x4000
  • 5. Windows memory allocator • ⽬目前會以 win 10 (1809) 為主 • OS build - 17763.379 • 之後版本可能不⼀一定完全正確 • 結構常常改動很⼤大,有個概念念後,到新的發⾏行行版本,需要⾃自⼰己去追⼀一下結 構
  • 6. Windows memory allocator • Overview Kernel32.dll HeapAlloc HeapFree msvcrt140.dll malloc free ntdll.dll RtlAllocateHeap RtlFreeHeap ntdll.dll RtlpAllocateHeap RtlpFreeHeap ntdll.dll RtlpLowFragHeapAlloc RtlpLowFragHeapFree Kernel Front-End Back-End
  • 7. Windows memory allocator • 在 LFH 沒啟⽤用下,我們呼叫 malloc Kernel32.dll HeapAlloc HeapFree msvcrt140.dll malloc free ntdll.dll RtlAllocateHeap RtlFreeHeap ntdll.dll RtlpAllocateHeap RtlpFreeHeap Kernel Back-End
  • 8. Windows memory allocator • 啟⽤用 LFH 後,第⼀一次或 LFH 能⽤用的⽤用完時
 會先跟 Back-End 要⼀一⼤大塊空間來來管理理 Kernel32.dll HeapAlloc HeapFree msvcrt140.dll malloc free ntdll.dll RtlAllocateHeap RtlFreeHeap ntdll.dll RtlpAllocateHeap RtlpFreeHeap ntdll.dll RtlpLowFragHeapAlloc RtlpLowFragHeapFree Kernel Front-End Back-End
  • 9. Windows memory allocator • 啟⽤用 LFH 之後分配相同⼤大⼩小時,會直接給
 Front-End 管理理 Kernel32.dll HeapAlloc HeapFree msvcrt140.dll malloc free ntdll.dll RtlAllocateHeap RtlFreeHeap ntdll.dll RtlpLowFragHeapAlloc RtlpLowFragHeapFree Front-End
  • 10. Windows memory allocator • HEAP 可分為 • Process Heap • Default heap • 整個 process 共享,呼叫 api 時會⽤用到 • 會存在 _PEB 結構中 • CRT 中的函式時也會⽤用到 • 存在 crt_heap
  • 11. Windows memory allocator • HEAP 可分為 • Private heap • 另外創建的 heap • HeapCreate
  • 12. Windows memory allocator • Core data structure • _HEAP_ENTRY (chunk) • Malloc 出來來的基本結構 • 在前後端分配器中,長相會不太⼀一樣,但都是同⼀一個名字
  • 13. Windows memory allocator • _HEAP_ENTRY (chunk) data chunk header chunk header data _HEAP chunk header . . . malloc return value
  • 14. Windows memory allocator • Core data structure • _HEAP • 整個 memory allocator 中最核⼼心的結構,⽤用來來管理理該 heap • 每個 Heap 都會有⼀一個 _HEAP 通常在 heap 開頭
  • 15. Windows memory allocator • _HEAP • EncodeFlagMask • Heap 初始化後會設置為 0x100000 在判斷是否要 encode 該 heap 中 chunk 的 header • Encoding (_HEAP_ENTRY) • ⽤用來來與 chunk header 做 xor 的 cookies … EncodeFlagMask0x7c 0x80 0x138 Encoding … BlocksIndex … FreeList … FrontEndHeap … 0x150 0x198 FrontEndHeapUsageData0x1a8 …
  • 16. Windows memory allocator • _HEAP • BlocksIndex (_HEAP_LIST_LOOKUP_) • Back-End 中,重要的結構之⼀一,⽤用 來來管理理 Back-End 中的 chunk ,後 ⾯面會詳細敘述 • FreeList (_HEAP_ENTRY) • 串串接 Back-End 中的所有 free chunk ,類似 unsorted bin • Sorted list … EncodeFlagMask0x7c 0x80 0x138 Encoding … BlocksIndex … FreeList … FrontEndHeap … 0x150 0x198 FrontEndHeapUsageData0x1a8 …
  • 17. Windows memory allocator • _HEAP • FrontEndHeap • 指向管理理 FrontEnd 的 Heap 的結構 • FrontEndHeapUsageData • 指向⼀一個對應各⼤大⼩小 chunk 的陣列列 • 紀錄各種⼤大⼩小 chunk 使⽤用次數,到 達某個程度時會去 enable 該對應⼤大 ⼩小 chunk 的 Front-End allocator … EncodeFlagMask0x7c 0x80 0x138 Encoding … BlocksIndex … FreeList … FrontEndHeap … 0x150 0x198 FrontEndHeapUsageData0x1a8 …
  • 18. Windows memory allocator • Nt Heap • 後端管理理器 (Back-End) • 前端管理理器 (Front-End)
  • 19. Nt heap • Nt Heap • 後端管理理器 (Back-End) • Data structure • 分配機制
  • 20. Windows memory allocator • _HEAP_ENTRY (chunk) • 分為三種狀狀況 • Allocated chunk • Freed chunk • VirtualAlloc chunk
  • 21. Nt heap • _HEAP_ENTRY (chunk) • PreviousBlockPrivateData • 基本上可為前⼀一塊 chunk 的 data,因 為 chunk 必須對⿑齊 0x10 • Size • Chunk 的 size 但存入⽅方式並不是直接 存 size ⽽而是存 (size >>4) 後的值 User Data PreviousBlockPrivateData (8byte) Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 22. Nt heap • _HEAP_ENTRY (chunk) • Flag • 表⽰示該 chunk 是否 inused • SmallTagIndex • 前⾯面三個 byte 的 Checksum(三個 byte 做 xor),之後拿 header 出來來時會 驗證 User Data PreviousBlockPrivateData (8byte) Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 23. Nt heap • _HEAP_ENTRY (chunk) • PreviousSize • 相鄰的前⼀一塊 chunk 的 Size ,這邊ㄧ 樣是 (Size >> 4) 過後的數值 • SegmentOffset • 某些情況下⽤用來來找 segment 的 User Data PreviousBlockPrivateData (8byte) Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 24. Nt heap • _HEAP_ENTRY (chunk) • Unusedbyte • 紀錄 user malloc 後所剩 chunk 的空間 • 可以⽤用來來判斷 chunk 的狀狀態判斷 chunk 是 FrontEnd or BackEnd • User Data • User 所使⽤用的區塊 User Data PreviousBlockPrivateData (8byte) Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 25. Nt heap • _HEAP_ENTRY (chunk) • Flink • 指向 linked list 中下⼀一塊 chunk • Blink • 指向 linked list 中上⼀一塊 chunk • Unusedbyte • 恆為 0 User Data PreviousBlockPrivateData (8byte) Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) freed Flink Blink
  • 26. Nt heap • _HEAP_VIRTUAL_ALLOC_ENTRY (mmap chunk) • Flink • 指向下⼀一塊 VirtualAlloc 出來來的 chunk • Blink • 指向上⼀一塊 VirtualAlloc 出來來的 chunk User Data Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) inused Flink Blink …
  • 27. Nt heap • _HEAP_VIRTUAL_ALLOC_ENTRY (mmap chunk) • Size • 這邊的 size 指的是 unused size,且 沒有 shift 過 • Unusedbyte • 恆為 4 User Data Size (2byte) Flag (1byte) SmallTagIndex (1byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) inused Flink Blink …
  • 28. Nt heap • FreeLists (_HEAP_ENTRY) • 在 Free 完⼀一塊 chunk 後,會將該 chunk 放到 FreeLists 中,並會依照⼤大 ⼩小決定插在 FreeLists 中的位置 Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x110) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateData
  • 29. Nt heap Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x110) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateDat … EncodeFlagMask0x7c 0x80 0x138 Encoding … BlocksIndex … FreeList … FrontEndHeap … 0x150 0x198 FrontEndHeapUsageData0x1a8 … Flink Blink _HEAP
  • 30. Nt heap • Remark • 關於 header encoding • 所有的 chunk 都會經過 xor 過,在存 chunk header 時,會將整個 header^(_HEAP->Encoding) 在存入 • decode 時會驗證 check sum 確保沒被改掉 • 驗證⽅方式為 encode_header^(_HEAP->Encoding) 後的值,前 3 byte xor 後和第 4 byte 比對
  • 31. Nt heap • BlocksIndex (_HEAP_LIST_LOOKUP) • 主要⽤用來來管理理各種不同⼤大⼩小的 freed chunk 的結構,⽅方便便在配置記憶體 時,能快速的找到適合的 chunk
  • 32. Nt heap • BlocksIndex (_HEAP_LIST_LOOKUP) • ExtendedLookup (_HEAP_LIST_LOOKUP) • 指向下⼀一個 ExtendedLookup • 通常下⼀一個會管理理更更⼤大塊 chunk 所⽤用的 結構 • ArraySize • 該結構會管理理的,最⼤大 chunk 的⼤大⼩小, 通常為 0x80 (實際上是 0x800) BlocksIndex ExtendedLookup0x0 ArraySize0x8 … ItemCount (4 bytes) OutofRangeItems (4 bytes) 0x10 0x14 BaseIndex0x18 ListHead ListsInUseUlong ListHint 0x20 0x28 0x30
  • 33. Nt heap • BlocksIndex (_HEAP_LIST_LOOKUP) • ItemCount • ⽬目前該結構所管理理的 chunk 數 • OutofRangeItems • 超出該結構所管理理⼤大⼩小的 chunk 的 數量量 BlocksIndex ExtendedLookup0x0 ArraySize0x8 … ItemCount (4 bytes) OutofRangeItems (4 bytes) 0x10 0x14 BaseIndex0x18 ListHead ListsInUseUlong ListHint 0x20 0x28 0x30
  • 34. Nt heap • BlocksIndex (_HEAP_LIST_LOOKUP) • BaseIndex • 該結構所管理理的 chunk 的起始 index, ⽤用來來從 ListHint 找適合⼤大⼩小的 free chunk ⽤用的,下⼀一個 BlocksIndex 將從 這個 index 的最⼤大值作為 BaseIndex • ListHead (_HEAP_ENTRY) • FreeList 的 Head BlocksIndex ExtendedLookup0x0 ArraySize0x8 … ItemCount (4 bytes) OutofRangeItems (4 bytes) 0x10 0x14 BaseIndex0x18 ListHead ListsInUseUlong ListHint 0x20 0x28 0x30
  • 35. Nt heap • BlocksIndex (_HEAP_LIST_LOOKUP) • ListsInUseUlong • ⽤用在判斷 ListHint 中是否有適合⼤大⼩小的 chunk,是⼀一個 bitmap • ListHint • 重要結構,⽤用來來指向相對應⼤大⼩小的 chunk array • 其⽬目的就在於更更快速找到適合⼤大⼩小的 chunk
 ⼤大⼩小為 0x10 為⼀一個間隔 BlocksIndex ExtendedLookup0x0 ArraySize0x8 … ItemCount (4 bytes) OutofRangeItems (4 bytes) 0x10 0x14 BaseIndex0x18 ListHead ListsInUseUlong ListHint 0x20 0x28 0x30
  • 36. … EncodeFlagMask Encoding … BlocksIndex … FreeList … FrontEndHeap … FrontEndHeapUsageDat … _HEAP BlocksIndex ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Flink Blink Chunk header (0x110) PreviousBlockPrivate Flink Blink Chunk header(0x160) PreviousBlockPrivat ListHint Flink Flink Flink ListHint[7] ListHint[0x11] ListHint[0x16] 000001…1…1000000000 ListsInUseUlong
  • 37. Nt heap • Nt Heap • 後端管理理器 (Back-End) • Data structure • 分配機制
  • 38. Nt heap • Allocate (RtlpAllocateHeap) • 基本上分為三種 • Size <= 0x4000 • 0x4000 < size <= 0xff000 • Size > 0xff000
  • 39. Nt heap • Allocate (RtlpAllocateHeap) • Size <= 0x4000 • 基本上主要分配都會在 RtlpAllocateHeap • 接著會去看該 size 對應到的 FrontEndHeapStatusBitmap 使否有啟⽤用 LFH • 沒有的話會對對應到的 FrontEndHeapUsageData 加上 0x21 • 並且檢查值是否超過 0xff00 或者 & 0x1f 後超過 0x10
 通過條件就會啟⽤用 LFH
  • 40. Nt heap • Allocate (RtlpAllocateHeap) • Size <= 0x4000 • 接下來來會先看對應到的 ListHint 是否有值,會以 ListHint 中的 chunk 為優先 • 如果有適合剛好的 chunk 在 ListHint 上則移除 ListHint,並且會看該 chunk 的 Flink ⼤大⼩小是否 剛好也是同樣 size • 是的話就將 LintHint 填上 Flink • 不是則清空 • 最後則 unlink 該 chunk 把這塊 chunk 從 linked list 中移除返還給使⽤用者,並將 header xor 回去
  • 41. Nt heap • Allocate (RtlpAllocateHeap) • Size <= 0x4000 • 如果沒有剛好適合的 • 從比較⼤大的 ListHint 中找,有找到比較⼤大的後如果該 chunk 將會從 ListHint 則移除之, 並看下⼀一塊 chunk size 有沒有剛好⼤大⼩小,有則補上,並且 unlink 將該 chunk 移除 freelist • 最後將該 chunk 做切割,剩下的⼤大⼩小重新加入 Freelist ,如果可以放進 ListHint 就會放 進去 • 然後回傳切好的 chunk 給使⽤用者,這邊也會對切割後跟回傳使⽤用者的 chunk header xor
  • 42. Nt heap • Allocate (RtlpAllocateHeap) • Size <= 0x4000 • 如果 FreeList 中都沒有 • 嘗試 ExtendHeap 加⼤大 heap 空間 • 再從 extend 出來來的 chunk 拿 • 接著後⾯面⼀一樣切割,放回 ListHint,xor header
  • 43. Nt heap • Allocate (RtlpAllocateHeap) • 0x4000 < size <= 0xff000 • 除了了沒有對 LFH 相關的操作外,其餘都跟 0x4000 ⼀一樣
  • 44. Nt heap • Allocate (RtlpAllocateHeap) • Size > 0xff000 (VirtualMemoryThreshold << 4) • 直接使⽤用 ZwAllocateVirtualMemory • 類似 mmap 直接給⼀一⼤大塊,並且會插入 _HEAP->VirtualAllocdBlocks 這個 linked list 中 • 這個 linked list 是串串接該 Heap VirtualAllocate 出來來的區段⽤用的
  • 45. Nt heap • Free (RtlpFreeHeap) • 可分為 • Size <= 0xff000 • Size > 0xff000
  • 46. Nt heap • Free (RtlpFreeHeap) • Size <= 0xff000 • 會先檢查 alignment、利利⽤用 unused byte 判斷該 chunk 狀狀態 • 如果是非 LFH 下,會對對應到的 FrontEndHeapUsageData 減 1 • 接著會判斷前後的 chunk 是否為 freed ,是的話就合併 • 此時會把可以合併的 chunk 做 unlink ,並從 ListHint 移除 • 移除⽅方式與前⾯面相同,看看下⼀一塊是不是同樣⼤大⼩小,是的話補上 ListHint
  • 47. Nt heap • Free (RtlpFreeHeap) • Size <= 0xff000 • 合併完後, update size & prevsize ,然後會看看是不是最前跟最後, 是就插入,不⾏行行插入就從 ListHint 中插入,並且 update ListHint,插入 時也會對 linked list 做檢查 • 但這檢查不會 abort • 其原因主要因為不做 unlink 寫入
  • 48. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Free(Q) Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7)
  • 49. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Find Prevchunk Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Prevchunk = Chunk address - (prevsize << 4)
  • 50. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Find Prevchunk Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Prevchunk = chunk addr - 0x70
  • 51. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Decode prevchunk
 header Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7)
  • 52. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check checksum Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) SmallTagInex ==
 (size & 0xff) xor (size >> 8) xor Flag
  • 53. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check checksum Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) 7 ==
 0x7^0x0^0x0
  • 54. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 linked list Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) P->Flink->Blink == 
 P->Blink->Flink == 
 P
  • 55. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Find 
 BlocksIndex Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7)
  • 56. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Find suitable 
 BlocksIndex Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) Check P->size < ArraySize
  • 57. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 ListHint Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) Check ListHint[7] == Prevchunk
  • 58. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 ListHint Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) Check prevchunk->Flink == ListHead 成立的話會準備 update
 ListHint
  • 59. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 ListHint[7]->Flink Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) decode prevchunk->Flink And check the checksum 由於前⼀一張 slide 不成立 要去驗 Flink 的 size

  • 60. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 ListHint[7]->Flink Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) Size == 
 prevchunk->Flink->size 如果相等,直接將 ListHint 換成下⼀一塊

  • 61. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Update
 ListHint[7] Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) ListHint[7] =
 prevchunk->Flink
  • 62. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Flink Blink Chunk header (0x70) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Unlink
 prevchunk Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x7) Flag (0x0) SmallTagIndex (0x7) Prevchunk->Blink->Flink
 = Prevchunk->Flink
 Prevchunk->Flink->Blink = Prevchunk->Blink
  • 63. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Update
 prevchunk
 and next chunk Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) Prevchunk->size =
 0x11 + Prevchunk->size(7) R->Prevsize = 0x18 P Flink Blink Chunk header (0x180) PreviousBlockPrivate
  • 64. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Check
 next chunk Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) 檢查下⼀一塊 chunk
 使否 freed P Flink Blink Chunk header (0x180) PreviousBlockPrivate
  • 65. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Find suitable
 BlocksIndex
 For P Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) Check
 P->Size < ArraySize P Flink Blink Chunk header (0x180) PreviousBlockPrivate
  • 66. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Search
 insert
 point Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) Check
 P->size < ListHead->Blink->Size
 P->size < ListHead->Flink->Size P Flink Blink Chunk header (0x180) PreviousBlockPrivate
  • 67. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Insert
 linked list Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) Check
 S->Blink->Flink
 == S If not pass it will not 
 abort
 But it will not unlink P Flink Blink Chunk header (0x180) PreviousBlockPrivate
  • 68. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Update
 ListHint Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x7) If LintHint[0x18] == NULL
 LintHint[0x18] = P P Flink Blink Chunk header (0x180) PreviousBlockPrivate FlinkListHint[0x18]
  • 69. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Update
 header Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0x18) Flag (0x0) SmallTagIndex (0x18) SmallTagIndex = 
 (size >> 8) ^
 (size & 0xff) ^
 Flag P Flink Blink Chunk header (0x180) PreviousBlockPrivate FlinkListHint[0x18]
  • 70. ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint Flink Blink Chunk header(0x110) PreviousBlockPrivat FlinkListHint[7] Flink Blink Chunk header(0x70) PreviousBlockPrivat merge chunk P Q R S Encode
 header Size (0x11) Flag (0x1) SmallTagIndex (0x10) Prevsize (0x7) Size (0xda) Flag (0xab) SmallTagIndex (0x41) P->header ^
 _HEAP->Encoding P Flink Blink Chunk header (0x180) PreviousBlockPrivate FlinkListHint[0x18]
  • 71. Nt heap • Free (RtlpFreeHeap) • Size > 0xff000 • 檢查該 chunk 的 linked list 並從 _HEAP->VirtualAllocdBlocks 移除 • 接著使⽤用 RtlpSecMemFreeVirtualMemory 將 chunk 整個 munmap 掉
  • 72. Back-End Exploitation • Unlink • 基本上與 Linux 中的 unlink 很類似,繞過⽅方法也差不多 • 簡⽽而⾔言之就是利利⽤用從 linked listed 移除 node 的⾏行行為來來做有限制的寫入 • 要注意的是在會 decode 的地⽅方,都要讓他正常 decode • 也就是 check sum 要過 • 另外⼀一點是 Flink 及 Blink 並不是指向 chunk 開頭,⽽而是直接指向 User data 部分,也就是 不太需要做偏移偽造 chunk • 所以找到⼀一個指向該 userdata 的 pointer 讓他繞過 double linked list 的驗證就好了了
  • 73. Back-End Exploitation • Unlink • Q->Blink->Flink = Q->Flink • Q->Flink->Blink = Q->Blink Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x110) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateData QP R
  • 74. Back-End Exploitation • Unlink • Q->Blink->Flink = Q->Flink • Q->Flink->Blink = Q->Blink Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x110) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateData QP R
  • 75. Back-End Exploitation • Unlink • Q->Blink->Flink = Q->Flink • Q->Flink->Blink = Q->Blink Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x110) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateData QP R
  • 76. Back-End Exploitation • Unlink • Q->Blink->Flink = Q->Flink • Q->Flink->Blink = Q->Blink Flink Blink Chunk header (0x70) PreviousBlockPrivateData Flink Blink Chunk header (0x160) PreviousBlockPrivateData QP R
  • 77. A A Chunk header (0x110) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint UAF T A
  • 78. A A Chunk header (0x110) PreviousBlockPrivate Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint Free(Q) T A
  • 79. Q A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A A ListHead QListHint[0x11] free(S) Update ListHint
  • 80. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A A S SListHint[0x11] Q ListHead
  • 81. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A A S SListHint[0x11] Q ListHead Let’s corrupt the heap !
  • 82. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead free(P)
  • 83. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Check next chunk 
 is free
  • 84. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Decode 
 chunk Q
  • 85. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead(&Q-8)->Blink == (&Q)->Flink == Q
  • 86. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead(&Q-8)->Blink == (&Q)->Flink == Q Flink Blink
  • 87. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead(&Q-8)->Blink == (&Q)->Flink == Q Flink Blink
  • 88. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead*(&Q) == *(&Q) == Q
  • 89. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead*(&Q) == *(&Q) == Q Pass the check !!
  • 90. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Find 
 BlockIndex
  • 91. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Check
 ListHint[0x11]
  • 92. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead由於 S != Q
 所以不會對 ListHint
 做任何處理理
  • 93. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex Data Pointer ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Unlink !! Q->Blink->Flink = Q->Flink Flink Blink
  • 94. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P &Q - 8 R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHeadUnlink !! Q = &Q-8
  • 95. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P &Q - 8 R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHead Unlink !! Q->Flink->Blink = Q->Blink Flink Blink
  • 96. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHeadUnlink !! Q = &Q
  • 97. S A Chunk header (0x110) PreviousBlockPrivate Q Chunk header (0x110) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat P Q R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A &Q - 8 &Q SListHint[0x11] Q ListHeadUpdate 
 chunk size
  • 98. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHeadUpdate 
 chunk size P
  • 99. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead Search insert point P
  • 100. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHeadFind the last one And decode it P
  • 101. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead P Find the first one And decode it
  • 102. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead 我們要插在 A 前 P
  • 103. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead Check
 A->Blink->Flink == A P
  • 104. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead Check
 Q->Flink == A P
  • 105. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHeadFailed
 不過不會 abort 只是不會 insert P
  • 106. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead Update 
 ListHint P
  • 107. S A Chunk header (0x220) PreviousBlockPrivate Chunk header(0x50) PreviousBlockPrivat S Chunk header(0x110) PreviousBlockPrivat R S P &Q R S T ExtendedLookup ArraySize … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex ListHead ListsInUseUlong ListHint BlockIndex ListHint T A SListHint[0x11] Q ListHead P PListHint[0x22]
  • 108. Back-End Exploitation • Edit Q • 我們可以把 Q 周圍的 pointer 寫掉 • 最後可達成任意記憶體讀寫 P &Q R S T
  • 109. Back-End Exploitation • Edit Q • 我們可以把 Q 周圍的 pointer 寫掉 • 最後可達成任意記憶體讀寫 • 可對 Target 1 - 4 做寫入 P Target 1 Target 2 Target 3 Target 4
  • 110. Back-End Exploitation • After arbitrary memory reading and writing • Leak • ntdll.dll • PebLdr • binary address • Kernel32.dll
  • 111. Back-End Exploitation • After arbitrary memory reading and writing • Leak • kernelbase • KERNELBASE!BasepFilterInfo • Stack address
  • 112. Back-End Exploitation • After arbitrary memory reading and writing • Leak • ntdll.dll • _HEAP_LOCK • _HEAP->LockVariable.Lock • CriticalSection->DebugInfo • 指向 ntdll
  • 113. Back-End Exploitation • After arbitrary memory reading and writing • Leak • ntdll!PebLdr • _PEB_LDR_DATA • 可找出所有 DLL 的位置 • 不過缺點是最後⼀一兩兩個 byte 可能是 0 • 可先找出 binary base 從 IAT 找 kernel32
  • 114. Back-End Exploitation • After arbitrary memory reading and writing • Leak • BinaryBase • 從 IAT 找出 Kernel32 位置
  • 115. Back-End Exploitation • After arbitrary memory reading and writing • Leak • Kernel32 • 重要 dll 很多常⽤用 function 都在這 (CreateFile, ReadFile,WriteFile) • IAT • 獲得 kernelbase.dll 位置
  • 116. Back-End Exploitation • After arbitrary memory reading and writing • Leak • kernelbase • KERNELBASE!BasepFilterInfo • 指向 Heap 上的結構 • 裡⾯面有⾼高機率會有 stack pointer • https://j00ru.vexillium.org/2016/07/disclosing-stack-data-from-the-default- heap-on-windows/
  • 117. Back-End Exploitation • After arbitrary memory reading and writing • Leak • 如果 BasepFilterInfo 中沒有 stack address • 因 BasepFilterInfo 內容會有 stack address 是因為未初始化因素,所 以有機會沒有 stack address • 可以從 PEB 往前或往後算 1 個 page ,通常會是 TEB 位置,上⾯面繪 有 stack 尾段的位置,可以藉由該位置找出 retrun address
  • 118. Back-End Exploitation • After arbitrary memory reading and writing • Write • Return address • Control RIP • ROP to VirtualProtect/VirtualAlloc • Jmp to shellcode
  • 119. Windows memory allocator • Nt Heap • 後端管理理器 (Back-End) • 前端管理理器 (Front-End)
  • 120. Windows memory allocator • Nt Heap • 前端管理理器 (Front-End) • ⽬目前 win10 主要使⽤用 • LowFragmentationHeap • 在非 Debug 下才會 enable • Size < 0x4000
  • 121. Windows memory allocator • Nt Heap • 前端管理理器 (Front-End) • Data Structure • 分配機制
  • 122. Windows memory allocator • Nt Heap • 前端管理理器 (Front-End) • Data Structure • 分配機制
  • 123. LFH • FrontEndHeap (_LFH_HEAP) • HEAP (_HEAP) • 指向對應到的 _HEAP • Buckets (_HEAP_BUCKET) • ⽤用來來尋找配置⼤大⼩小對應到 Block ⼤大⼩小 的陣列列結構 … Heap0x18 0x2a4 … Buckets SegmentInfoArray … … LocalData 0x4a8 0xcc0
  • 124. LFH • FrontEndHeap (_LFH_HEAP) • SegmentInfoArray (_HEAP_LOCAL_SEGMENT_INFO) • _HEAP_LOCAL_SEGMENT_INFO array, 不同⼤大⼩小對應到不同的 Segment_info 結 構,主要管理理對應到的 Subsegment 的資訊 • LocalData (_HEAP_LOCAL_DATA) • 其中有個欄欄位指向 LFH 本⾝身,通常⽤用來來找 回 LFH … Heap0x18 … Buckets SegmentInfoArray … … LocalData 0x2a4 0x4a8 0xcc0
  • 125. LFH • Buckets (_HEAP_BUCKET) • BlockUnits • 要分配出去的⼀一個 block ⼤大⼩小 >> 4 • SizeIndex • 使⽤用者需要的⼤大⼩小 >> 4 BlockUnits Buckets SizeIndex … BlockUnits SizeIndex … … … Buckets[0] Buckets[1]
  • 126. LFH • SegmentInfoArray (_HEAP_LOCAL_SEGMENT_INFO) • LocalData (_HEAP_LOCAL_DATA) • 對應到 _LFH_HEAP->LocalData ⽅方便便 從 SegmentInfo 找回 _LFH_HEAP • BucketIndex • 對應到的 BucketIndex LocalData SegmentInfoArray[x] ActiveSubsegment CachedItems … BucketIndex …
  • 127. LFH • SegmentInfoArray (_HEAP_LOCAL_SEGMENT_INFO) • ActiveSubsegment (_HEAP_SUBSEGMENT) • 極為重要結構 • 對應到分配出去的 Subsegment • 其⽬目的在於管理理 Userblock • 記錄了了剩餘多少 chunk • 該 Userblock 最⼤大分配數等等 SegmentInfoArray[x] LocalData ActiveSubsegment CachedItems … BucketIndex …
  • 128. LFH • SegmentInfoArray (_HEAP_LOCAL_SEGMENT_INFO) • CachedItems (_HEAP_SUBSEGMENT) • _HEAP_SUBSEGMENT array • 存放對映到該 SegmentInfo 且還有可 以分配 chunk 給 user 的Subsegment • 當 ActiveSubsegment ⽤用完時,會從 這邊填充,置換掉 ActiveSubsegment SegmentInfoArray[x] LocalData ActiveSubsegment CachedItems … BucketIndex …
  • 130. LFH • ActiveSubsegment (_HEAP_SUBSEGMENT) • LocalInfo (_HEAP_LOCAL_SEGMENT_INFO) • 指回對應到的 _HEAP_LOCAL_SEGMENT_INFO LocalInfo ActiveSubsegment UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … 0x0 0x8 0x20 0x24 0x28 0x2a
  • 131. LFH • ActiveSubsegment (_HEAP_SUBSEGMENT) • UserBlock (_HEAP_USERDATA_HEADER) • LFH 的記憶體分配池 • 也就是要分配出去的 Chunk (Block) 所在位置 • 開頭會有些 metadata 管理理這些 chunk • 重要結構 LocalInfo ActiveSubsegment UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … 0x0 0x8 0x20 0x24 0x28 0x2a
  • 132. LFH • ActiveSubsegment (_HEAP_SUBSEGMENT) • AggregateExchg (_INTERLOCK_SEQ) • ⽤用來來管理理對應到的 UserBlock 中還有 多少 freed chunk • LFH ⽤用這個判斷是否還從該 UserBlock 分配 • 同時也有 Lock 的作⽤用 LocalInfo ActiveSubsegment UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … 0x0 0x8 0x20 0x24 0x28 0x2a
  • 133. LFH • ActiveSubsegment (_HEAP_SUBSEGMENT) • BlockSize • 在該 UserBlock 中每個 Block (chunk)的⼤大⼩小 • BlockCount • 在該 UserBlock 中 Block 的總數 • SizeIndex • 該 UserBlock 對應到的 SizeIndex LocalInfo ActiveSubsegment UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … 0x0 0x8 0x20 0x24 0x28 0x2a
  • 134. LFH • AggregateExchg (_INTERLOCK_SEQ) • Depth • 該 UserBlock 所剩下的 Freed chunk 數量量 • Lock • 就是 Lock AggregateExchg Depth0x0 Hint (15bit) Lock (1bit) 0x8
  • 135. LFH • UserBlock (_HEAP_USERDATA_HEADER) • SubSegment • 指回對應的 Subsegment • EncodeOffsets • ⽤用來來驗證 chunk header 是否有被改過 • BusyBitmap • 記錄該 UserBlock 哪些 chunk 有在⽤用的 bitmap SubSegment UserBlock … EncodedOffsets BusyBitmap 0x8 0x18 0x20 chunk header chunk header chunk header
  • 136. LFH • UserBlock (_HEAP_USERDATA_HEADER) • Block (chunk) • LFH 回傳給使⽤用者的 chunk SubSegment UserBlock … EncodedOffsets BusyBitmap 0x8 0x18 0x20 chunk header chunk header chunk header
  • 137. LFH • _HEAP_ENTRY (chunk) • SubSegmentCode • Encode 過的 metadata ⽤用來來推回 userblock 的位置 • PreviousSize • 該 chunk 在 UserBlock 中的 index User Data PreviousBlockPrivateData (8byte) SubSegmentCode (4byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 138. LFH • _HEAP_ENTRY (chunk) • Unusedbyte • Unusedbyte & 0x80 is true User Data PreviousBlockPrivateData (8byte) SubSegmentCode (4byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Inused
  • 139. LFH • _HEAP_ENTRY (chunk) • Unusedbytes • 恆為 0x80 • ⽤用來來判斷是否為 LFH 的 Free chunk User Data PreviousBlockPrivateData (8byte) SubSegmentCode (4byte) PreviousSize (2byte) SegmentOffset (1byte) Unusedbyte (1byte) Freed
  • 140. LFH • Remark • 關於 EncodedOffsets • 在 UserBlock 初始化時設置,其算法為下⾯面四個值的 xor • (sizeof(userblock header) | (BlockUnit*0x10 << 16)) • LFHkey • Userblock address • _LFH_HEAP address
  • 141. LFH • Remark • 關於 LFH header encoding • 所有的 chunk header 在初始化時都會經過 xor 過,算法為下⾯面個值的 xor • _HEAP address • LFHkey • Chunk address >> 4 • ((chunk address) - (UserBlock address)) << 12
  • 143. Windows memory allocator • Nt Heap • 前端管理理器 (Front-End) • Data Structure • 分配機制
  • 144. Windows memory allocator • Nt Heap • 前端管理理器 (Front-End) • 初始化 • 在 FrontEndHeapUsageData[x] & 0x1f > 0x10 時,下⼀一次的 allocate 會對 LFH 做出初始化 • 會先 ExtendFrontEndUsageData 及增加更更⼤大的 BlocksIndex (0x80-0x400) • 建立 FrontEndHeap • 初始化 SegmentInfoArrays[idx] • 接下來來在 allocate 相同⼤大⼩小的 chunk 就會開始使⽤用 LFH
  • 145. Windows memory allocator • LFH(初始化) • malloc(0x40) * 16 FrontEndHeapUsageData … 0x210 此時可 enable LFH 範圍為 index 0x0 - 0x80
  • 146. Windows memory allocator • LFH(初始化) • malloc(0x40) (第 17 次) FrontEndHeapUsageData … 0x231 0x231 & 0x1f > 0x10
  • 147. Windows memory allocator • LFH(初始化) FrontEndHeapUsageData … 0x231 heap->CompatibilityFlag |= 0x20000000 設置上這個 flag 後 下次 allocate 時會去初始化LFH

  • 149. Windows memory allocator • LFH(初始化) • malloc(0x40) (第 18 次) • ExtendFrontEndUsageData 及增加更更⼤大的 BlocksIndex (0x80-0x400) ,並設置對應的 bitmap • 並在該對應的 FrontEndHeapUsageData 寫上對應的 index,此時可 enable LFH 範圍變為 (idx: 0-0x400) • 建立並初始化 FrontEndHeap (mmap) • 初始化 SegmentInfoArrays[idx] • 在 SegmentInfoArrays[BucketIndex] 填上 segmentInfo FrontEndHeapUsageData … 0x4
  • 150. Windows memory allocator … EncodeFlagMask Encoding … BlocksIndex … FreeList … FrontEndHeap … FrontEndHeapUsageData … _HEAP FrontEndHeapUsageData 0x251 0x4 BlocksIndex ExtendedLookup ArraySize(0x80) … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex (0x0) ListHead ListsInUseUlong ListHint BlocksIndex ExtendedLookup ArraySize (0x400) … ItemCount (4 bytes) OutofRangeItems (4 bytes) BaseIndex (0x80) ListHead ListsInUseUlong ListHint
  • 152. Windows memory allocator • LFH(初始化) • malloc(0x40) (第 19 次) • Allocate Userblock 並初始化 • 設置對應的 chunk • 設置對應的 ActiviteSubsegment • 隨機返回其中的⼀一個 chunk Userblock metadata Chunk 00 Chunk 01 … Chunk MaxBlockCount
  • 154. Windows memory allocator • LFH • Allocate (RtlpLowFragHeapAllocFromContext) • 先看看 ActiveSubsegment 中是否有可分配的 chunk • 從 ActiveSubsegment->depth 判斷 • 如果沒有則會從 CachedItem 找,有找到的話會把 ActiveSubsegment 換成 CachedItem 中的 SubSegment
  • 162. Windows memory allocator • LFH • Allocate (RtlpLowFragHeapAllocFromContext) • 取得 RtlpLowFragHeapRandomData[x] 上的直 • 下⼀一次會從 RtlpLowFragHeapRandomData[x+1] 取 • x 為 1 byte ,當下次輪輪回 x 則會 x = rand() %256 繼續取 • RtlpLowFragHeapRandomData 為⼀一個 random 256 byte 的陣列列 • 範圍為 0x0 - 0x7f
  • 163. Windows memory allocator • LFH • Allocate (RtlpLowFragHeapAllocFromContext) • 最獲得的 index 為 • RtlpLowFragHeapRandomData[x]*maxidx >> 7 • 如果 collision 則往後取最近的 • 檢查 (unused byte & 0x3f) !=0 (表⽰示 chunk 是 freed) • 最後設置 index 及 unused byte 就返回給使⽤用者
  • 164. …. …. …. SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _HEAP_USERDATA_HEADER • Get an index • RtlpLowFragHeapRandomData[x]*maxidx >> 7 • 檢查該 index 對映到的 bitmap 是否為 0 • 是 0 則返回對映的 bitmap • 非 0 擇取最近的下⼀一個 chunk header
  • 165. …. …. …. SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _HEAP_USERDATA_HEADER • 算出來來的 index 發現已⽤用過 • 會取下⼀一個 • 並設置對映的 bitmap chunk header
  • 166. …. …. …. SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _HEAP_USERDATA_HEADER • 算出來來的 index 發現已⽤用過 • 會取下⼀一個 • 並設置對映的 bitmap chunk header
  • 167. Windows memory allocator • LFH • Free (RtlFreeHeap) • Update unused byte in chunk header • Find the index of the Chunk and reset Userblock->BusyBitmap • Update ActiveSubsegment->AggregateExchg • 如果 Free 的 chunk 不屬於當前 ActiveSubsegment 則會看看能不能放 進 cachedItems ,可以放就放進去
  • 168. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … Depth Hint (15bit) Lock (1bit) _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _INTERLOCK_SEQ _HEAP_USERDATA_HEADER • Free • ⽤用 chunk header 尋找 UserBlock
  • 169. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … Depth Hint (15bit) Lock (1bit) _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _INTERLOCK_SEQ _HEAP_USERDATA_HEADER • Free • ⽤用 chunk header 尋找 UserBlock • 找回對映的 SubSegment
  • 170. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … Depth Hint (15bit) Lock (1bit) _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _INTERLOCK_SEQ _HEAP_USERDATA_HEADER • Free • ⽤用 chunk header 尋找 UserBlock • 找回對映的 SubSegment • 設置 unused byte = 0x80 • 清除對映的 bitmap • Update AggregateExchg
  • 171. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … Depth Hint (15bit) Lock (1bit) _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _INTERLOCK_SEQ _HEAP_USERDATA_HEADER • Free • ⽤用 chunk header 尋找 UserBlock • 找回對映的 SubSegment • 設置 unused byte = 0x80 • 清除對映的 bitmap • Update AggregateExchg
  • 172. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … Depth Hint (15bit) Lock (1bit) _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _INTERLOCK_SEQ _HEAP_USERDATA_HEADER • Free • ⽤用 chunk header 尋找 UserBlock • 找回對映的 SubSegment • 設置 unused byte = 0x80 • 清除對映的 bitmap • Update AggregateExchg
  • 173. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _HEAP_USERDATA_HEADERLocalData ActiveSubsegment CachedItems … BucketIndex … LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … _HEAP_SUBSEGMENT Depth (1) Hint (15bit) Lock (1bit) _INTERLOCK_SEQ CachedItems ActiveSubsegmet 不等於 Free 掉 chunk 的
 SubSegment
  • 174. LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … _HEAP_SUBSEGMENT SubSegment … EncodedOffsets BusyBitmap chunk header chunk header chunk header _HEAP_USERDATA_HEADERLocalData ActiveSubsegment CachedItems … BucketIndex … LocalInfo UserBlock … AggregateExchg BlockSzie BlockCount … SizeIndex … _HEAP_SUBSEGMENT Depth (1) Hint (15bit) Lock (1bit) _INTERLOCK_SEQ CachedItems CachedItems[0]
  • 175. LFH Exploitation • Reuse attack • 假設我們有 Use after free 的漏洞洞 • 但因為 LFH 的隨機性,導致無法預側下⼀一塊 chunk 會在哪,使得我們 很難利利⽤用 • 這時可以填滿 Userblock 的⽅方式,在 free 掉其中⼀一塊,那麼下次該 chunk 必定會拿到同⼀一塊,我們可以利利⽤用這個特性,拿到 overlap chunk 做進⼀一步利利⽤用
  • 176. LFH Exploitation • normal case • malloc(sizeof(A)) Userblock header
  • 177. LFH Exploitation • normal case • malloc(sizeof(B)) Userblock header fptr
  • 178. LFH Exploitation • normal case • free(A) Userblock header B fptr
  • 179. LFH Exploitation • normal case • malloc(sizeof(A)) Userblock header B fptr
  • 180. LFH Exploitation • normal case • malloc(sizeof(B)) Userblock header B fptr
  • 181. LFH Exploitation • normal case • malloc(sizeof(B)) Userblock header B fptr Hard to use
  • 182. LFH Exploitation • Reuse attack • malloc(sizeof(A)) Userblock header
  • 183. LFH Exploitation • Reuse attack • malloc(sizeof(B)) x 6 Userblock header fptr
  • 184. LFH Exploitation • Reuse attack • free(A) Userblock header B B B B fptr B B
  • 185. LFH Exploitation • Reuse attack • malloc(sizeof(B)) Userblock header B B B B fptr B B
  • 186. LFH Exploitation • Reuse attack • A->fptr Userblock header B B B B fptr B B
  • 187. LFH Exploitation • Reuse attack • A->fptr Userblock header B B B B fptr B B Hijack the control flow !
  • 189. Thank you for listening !189 angelboy@chroot.org @scwuaptx !189