Upload
lowtec
View
236
Download
1
Embed Size (px)
Citation preview
8/4/2019 XPSP2 Heap Exploitation
1/59
Windows Heap Exploitation(Win2KSP0 through WinXPSP2)
Original CanSecWest 04 Presentation: Matt Conover & Oded Horovitz
XP SP2 Additions added/presented, Matt Conover @ SyScan 2004
8/4/2019 XPSP2 Heap Exploitation
2/59
Agenda
Practical Windows heap internals
How to exploit Win2K WinXP SP1 heap overflows 3rd party (me ) assessment of WinXP SP2
improvements
How to exploit WinXP SP2 heap overflows
Summary
8/4/2019 XPSP2 Heap Exploitation
3/59
Windows Heap Internals
Many heaps can coexist in one process (normally 2-3)
PEB
2nd Heap
Default Heap
0x0010 Default
Heap
0x0080 Heaps
Count0x0090 Heap List
0x70000
0x170000
8/4/2019 XPSP2 Heap Exploitation
4/59
Windows Heap Internals
Important heap structures
Segments
Lookaside List
SegmentList
Free Lists
Virtual Allocation list
8/4/2019 XPSP2 Heap Exploitation
5/59
Windows Heap Internals
Introduction to Free Lists
128 doubly-linked list of free chunks (from 8 bytesto 1024 bytes)
Chunk size is table row index * 8 bytes
Entry [0] is a variable sized free lists contains
buffers of 1KB
8/4/2019 XPSP2 Heap Exploitation
6/59
Windows Heap Internals
Lookaside Table
Used for fast allocates and deallocates whenavailable
Starts empty
128 singly-linked lists of busy chunks (free but leftmarked as busy)
0
1
2
3
4
5
6
16
48 48
8/4/2019 XPSP2 Heap Exploitation
7/59
Windows Heap Internals
Why have lookasides at all? Speed!
Singly-linked Used to quickly allocate or deallocate
No coalescing (leads to fragmentation)
So the lookaside lists fill up quickly (4 entries)
8/4/2019 XPSP2 Heap Exploitation
8/59
Windows Heap Internals
Basic chunk structure 8 Bytes
Previous chunksize
Self SizeSegment
IndexFlags
Unusedbytes
Tag index(Debug)
Overflow direction
0 1 2 3 4 5 6 7 8
01 Busy02 Extra present04 Fill pattern
08 Virtual Alloc10 Last entry20 FFU140 FFU280 No coalesce
8/4/2019 XPSP2 Heap Exploitation
9/59
Windows Heap Internals
Free chunk structure 16 Bytes
Previous chunksize
Self SizeSegment
IndexFlags
Unusedbytes
Tag index(Debug)
0 1 2 3 4 5 6 7 8
Next chunk Previous chunk
8/4/2019 XPSP2 Heap Exploitation
10/59
Windows Heap Internals
Allocation algorithm (high level)
If size >= 512K, virtual memory is used (not on heap)
If < 1K, first check the Lookaside lists. If there is no freeentries on the Lookaside, check the matching free list
If >= 1K or no matching entry was found, use the heap
cache (not discussed in this presentation). If >= 1K and no free entry in the heap cache, use
FreeLists[0] (the variable sized free list)
If still cant find any free entry, extend heap as needed
8/4/2019 XPSP2 Heap Exploitation
11/59
Windows Heap Internals
Allocate algorithm FreeLists[0]
This is usually what happens for chunk sizes > 1K FreeLists[0] is sorted from smallest to biggest
Check if FreeLists[0]->Blink to see if it is big enough(the biggest block)
Then return the smallest free entry from free list[0] tofulfill the request, like this:
While (Entry->Size < NeededSize)
Entry = Entry->Flink
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
12/59
Windows Heap Internals
Allocate algorithm Virtual Allocate
Used when ChunkSize > VirtualAlloc threshold(508K)
Virtual allocate header is placed on the beginning ofthe buffer
Buffer is added to busy list of virtually allocatedbuffers (this is what Halvars VirtualAlloc overwrite is
faking)
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
13/59
Windows Heap Internals
Free Algorithm (high level)
If the chunk < 512K, it is returned to a lookaside orfree list
If the chunk < 1K, put it on the lookaside (can onlyhold 4 entries)
If the chunk < 1K and the lookaside is full, put it onthe free list
If the chunk > 1K put it on heap cache (if present) or
FreeLists[0]
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
14/59
Windows Heap Internals
Free Algorithm Free to Lookaside
Free buffer to Lookaside list only if: The lookaside is available (e.g., present and unlocked)
Requested size is < 1K (to fit the table)
Lookaside is not full yet (no more than 3 entries already)
To add an entry to the Lookaside:
Put to the head of Lookaside
Point to former head of Lookaside
Keep the buffer flags set to busy (to prevent coalescing)
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
15/59
Windows Heap Internals
Free Algorithm Coalesce
BA C
A C
A
A + B Coalesced
Step 2: Buffer removedfrom free list
Step 3: Buffer removed
from free list
Step 4: Buffer placed backon the free list
A + B + C Coalesced
Step 1: Buffer free
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
16/59
Windows Heap Internals
Free Algorithm Coalesce
Where coalesce cannot happen: Chunk to be freed is virtually allocated
Chunk to be freed will be put on Lookaside
Chunk to be coalesced with is busy
Highest bit in chunk flags is set
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
17/59
Windows Heap Internals
Free Algorithm Coalesce (cont)
Where coalesce cannot happen: Chunk to be freed is first no backward coalesce
Chunk to be freed is last no forward coalesce
The size of the coalesced chunk would be >= 508K
Wi d H I t l
8/4/2019 XPSP2 Heap Exploitation
18/59
Windows Heap Internals
Summary Questions?
Just remember:
Lookasides are allocated from and freed to before free lists
FreeLists[0] is mainly used for 1K
8/4/2019 XPSP2 Heap Exploitation
19/59
Heap Exploitation: Basic Terms
4-byte Overwrite
Able to overwrite any arbitrary 32-bit address (WhereTo) withan arbitrary 32-bit value (WithWhat)
4-to-n-byte Overwrite
Using a 4-byte overwrite to indirectly cause an overwrite of an
arbitrary-n bytes
A bit M O it E l i d
8/4/2019 XPSP2 Heap Exploitation
20/59
Arbitrary Memory Overwrite Explained
Coalesce-On-Free 4-byte Overwrite Utilize coalescing algorithms of the heap
This is the method first discussed by Oded and I at CSW04 it is ourpreferred method for reliable heap exploitation on all versions < XPSP2
Just make sure to fill the Lookaside[ChunkSize] (put 4 entries on heap)before freeing a chunk of ChunkSize to ensure coalescing
Arbitrary overwrite happens when the overflowed buffer gets freed
Index< 64
Flags!= 1
Fake Flink (WithWhat) Fake Blink (WhereTo)
Overflowstart
A bit M O it
8/4/2019 XPSP2 Heap Exploitation
21/59
Arbitrary Memory Overwrite
Lookaside List Head Overwrite:
4-to-n-byte overwrite What we want to do is overwrite a Lookaside list
head and then allocate from it
We must be the first one to allocate that size
We will get a chunk back pointing to whateverlocation in memory we want
Use this to overwrite a function pointer or put the
shellcode at a known writable location
A bit M O it
8/4/2019 XPSP2 Heap Exploitation
22/59
Arbitrary Memory Overwrite
Lookaside List Head Overwrite: How To
Use the Coalesce-on-Free Overwrite, with these values: FakeChunk.Blink = &Lookaside[ChunkSize] where ChunkSize is a
pretty infrequently allocated size
FakeChunk.Flink = what we want a pointer to
To calculate the FakeChunk.Blink value:
LookasideTable = HeapBase + 0x688
Index = (ChunkSize/8)+1
FakeChunk.Blink = LookasideTable + Index * EntrySize (0x30)
Set FakeChunk.Flags = 0x20, FakeChunk.Index = 1-63,
FakeChunk.PreviousSize = 1, FakeChunk.Size = 1
E l iti M d Si l
8/4/2019 XPSP2 Heap Exploitation
23/59
Exploition Made Simple
Overwrite PEB lock routine to point to PEB space
Put shellcode into PEB space
Then cause the PEB lock routine to execute
PEBHeader
~1k of payload
PEB lock/unlock function pointers0x7ffdf020, 0x7ffdf024
0x7ffdf130
E ploitation Made Simple
8/4/2019 XPSP2 Heap Exploitation
24/59
Exploitation Made Simple
Win2K through WinXP SP1 in a single attempt:
First 4-byte overwrite: Blink = 0x7ffdf020,
Flink = 0x7ffdf154
4-to-n-byte overwrite:
Blink = &Lookaside[(n/8)+1]
Flink = 0x7ffdf154
Be the first to allocate n bytes (cause HeapAlloc(n)):
Put your shellcode into the returned buffer All done! Either wait, or cause a crash immediately:
For example, do 4-byte overwrite with Blink =0xABABABAB
Exploitation Made Simple
8/4/2019 XPSP2 Heap Exploitation
25/59
Exploitation Made Simple
Forcing Shellcode To Run
Most applications (read: everyone but MSSQL) dontspecially handle access violations
An access violation results in ExitProcess() beingcalled
Once the process attempts to exit, ExitProcess() iscalled
The first thing ExitProcess() does is call the PEB lock
routine Thus, causing crash = instant shellcode execution
Nice
Exploitation Made Simple
8/4/2019 XPSP2 Heap Exploitation
26/59
Exploitation Made Simple
Demo
Heap Exploitation
8/4/2019 XPSP2 Heap Exploitation
27/59
Heap Exploitation
Questions?
This technique we just covered is very reliably,providing success almost every time on all
Win2K (all service packs) and WinXP (up toSP2)
On to XP SP2.
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
28/59
XP Service Pack 2
Effects on Heap Exploitation
New low fragmentation heap for chunks >= 16K
PEB shuffling (aka randomization)
New security cookie in each heap chunk
Safe unlinking: (usually) stops 4-byte overwrites
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
29/59
XP Service Pack 2
PEB Randomization
In theory, it could have a big impact on heapexploitation though not in reality
Prior to XP SP2, it used to always be at the highestpage available (0x7ffdf000)
The first (and ONLY the first) TEB is also randomized
They seem to never be below 0x7ffd4000
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
30/59
XP Service Pack 2
PEB Randomization Does it make any difference?
Not much, randomization is definitely a misnomer
If 2 threads are present:
We can write to 0x7ffdf000-0x7ffdffff, and
2 other pages between 0x7ffd4000-0x7ffdefff
If 3 threads are present:0x7ffde000-0x7ffdffff
2 other pages between 0x7ffd4000-0x7ffdefff
If 11 threads are present:
100% success, no empty pages
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
31/59
XP Service Pack 2
PEB Randomization Summary
Provides little protection for
Any application that have mworkers per nconnections (IIS? Exchange?)
Any service in dllhost/services/svchost or any other
active surrogate process
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
32/59
XP Service Pack 2
Heap header cookie
Previous chunksize
Self SizeSegment
IndexFlags
Unusedbytes
Tag index(Debug)
0 1 2 3 4 5 6 7 8
Previous chunksize
Self SizeNew
CookieFlags
Unusedbytes
SegmentIndex
XP SP2Header
CurrentHeader
*reminder: overflow direction
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
33/59
XP Service Pack 2
Heap header cookie calculation
If ((AddressOfChunkHeader / 8) XOR Chunk->Cookie XOR Heap->Cookie != 0) CORRUPT
Since the cookie has only 8-bits, it has 2^8 = 256possible keys
Well randomly guess the security cookie, on
average, 1 of every 256 attempts
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
34/59
XP Service Pack 2
On the normal WinXP SP2 system, corrupting achunk will do nothing
Since we only overwrite the Flink/Blink of the chunk,we corrupt no other chunks
Thus we can keep trying until we run out of memory
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
35/59
XP Service Pack 2
Summary so far
At this point, we see that we can with enough time triviallydefeat all the other protection mechanisms.
On to safe unlinking
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
36/59
XP Service Pack 2
Safe Unlinking
Safe unlinking means that RemoveListEntry(B) will make thischeck:
(B->Flink)->Blink == B && (B->Blink)->Flink == B
In other words:
C->Blink == B && A->Flink == B
Can it be evaded? Yes, in one particular case.
A B C
Header to free
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
37/59
XP Service Pack 2
UnSafe-Unlinking FreeList Overwrite Technique
p = HeapAlloc(n);
FillLookaside(n);
HeapFree(p);
EmptyLookaside(n);
Overwrite p[0] (somewhere on the heap) with:p->Flags = Busy (to prevent accidental coalescing)
p ->Flink = (BYTE *)&ListHead[(n/8)+1] - 4
p ->Blink = (BYTE *)&ListHead[(n/8)+1] + 4
HeapAlloc(n); // defeats safe unlinking (ignore result)
p = HeapAlloc(n); // defeats safe unlinking
// p now points to &ListHead[(n/8)].Blink
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
38/59
XP Service Pack 2
Defeating Safe Unlinking (before overwrite)
[0] Flink
[4] BlinkListHead[n]
[4] Blink
[0] FlinkFreeChunk
ListHead[n+1] [0] Flink
ListHead[n-1] [4] Blink
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
39/59
XP Service Pack 2
Defeating Safe Unlinking: Step 1 (Overwrite)
[0] Flink
[4] BlinkListHead[n]
[4] Blink
[0] FlinkFreeChunk
ListHead[n+1] [0] Flink
ListHead[n-1] [4] Blink
Now call HeapAlloc(n) to unlink FreeChunk from ListHead
FreeChunk->Blink->Flink == *(*(FreeChunk+4)+0)
FreeChunk->Flink->Blink) == *(*(FreeChunk+0)+4)
Both point to FreeChunk, unlink proceeds!
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
40/59
XP Service Pack 2
Defeating Safe Unlinking: Step 2 (1st alloc)
[0] Flink
[4] BlinkListHead[n]
ListHead[n+1] [0] Flink
ListHead[n-1] [4] Blink
FreeChunk->Blink->Flink = FreeChunk->Flink
FreeChunk->Flink->Blink = FreeChunk->Blink
Returns pointer to previous FreeChunk
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
41/59
XP Service Pack 2
Defeating Safe Unlinking: Step 3 (2nd alloc)
[0] Flink
[4] BlinkListHead[n]
ListHead[n+1] [0] Flink
ListHead[n-1] [4] Blink
Returns pointer to &ListHead[n-1].Blink
Now the FreeLists point to whatever data the user puts in it
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
42/59
XP Service Pack 2
Questions?
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
43/59
XP Service Pack 2
Unsafe-Unlinking FreeList Overwrite Technique
For vulnerabilities where you can control theallocation size, safe unlinking can be evadable.
But is this reliable? Hardly.
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
44/59
XP Service Pack 2
Unsafe-Unlinking FreeList Overwrite Technique (cont)
We have to flood the heap with this repeating 8 bytesequence:
[FreeListHead-4][FreeListHead+4]
And hope the Chunks Flink/Blink pair is within the
range we can overflow
But there is an even easier method
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
45/59
XP Service Pack 2
Chunk-on-Lookaside Overwrite Technique
In fact on XP SP2, there is an even easier method
Lookasides lists take precedence over free lists
This is quite convenient because
Lookaside lists (singly linked) are easier to exploitthan the free lists (doubly linked)
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
46/59
XP Service Pack 2
Chunk-on-Lookaside Overwrites
HeapAlloc checks the lookaside before the free list
There is no check to see if the cookie wasoverwritten since it was freed
It is a singly-linked list, thus the safe unlinking checkdoesnt apply
Result: a clean exploitation technique (albeit withbrute-forcing required)
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
47/59
XP Service Pack 2
Chunk-on-Lookaside Overwrites (Technique Summary)
// We need at least 2 entries on lookaside
a_n[0] = HeapAlloc(n)
a_n[1] = HeapAlloc(n)
HeapFree(a_n[1])
HeapFree(a_n[0])Overwrite a_n[0] (somewhere on the heap) with:
a_n[0].Flags = Busy (to prevent accidental coalescing)
a_n[0].Flink = AddressWeWant
HeapAlloc(n) // discard, this returns a_n[0]
p = HeapAlloc(n)
p now points to AddressWeWant
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
48/59
XP Service Pack 2
Chunk-on-Lookaside Overwrite - Success rate?
Reqiures overwriting a chunk already freed to thelookaside
If an attacker overflows a buffer repeatedly, howoften will he/she need to before succeeding?
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
49/59
XP Service Pack 2
Chunk-on-Lookaside Overwrite Empirical results
64K heap with 1 segment
All chunk sizes sizes between 8-1024 bytes
Max overflow size = 1016 bytes
Random number of allocs between 10-1000
Free probability of 50% Took an average of 84 allocations to be within
overflow range
It will take at least 2 overwrites (one to overwrite afunction pointer, one to place shellcode)
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
50/59
XP Service Pack 2
Chunk-on-Lookaside Overwrite Empirical results
Application specific function pointer and writablelocation for shellcode:
84*2 = 168 attempts to execute shellcode
Using PEB lock routine + PEB space (application
generic): 84*2*12=2,016 attempts to execute shellcode
The 12 is for the 12 possible locations of the PEB due toPEB randomization
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
51/59
XP Service Pack 2
Chunk-on-Lookaside Overwrite Summary
To exploit a non-application specific heap exploit willtake 2000+ attempts to do it reliably
But now ask yourself how long does it take
generate 2000 heap overwrite attempts?
Lets be overly conservative and assume 5 minutes
That will really slow down a worm
But will it help you if someone is specifically trying to
hack yourmachine?
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
52/59
XP Service Pack 2
Low Fragmentation Heap (LFH)
Looks really solid kudos to its author
Uses 32-bit cookie
Obscures address of Lookaside list heads:ChunkSizes = *((DWORD *)Chunk) // (ChunkSize
8/4/2019 XPSP2 Heap Exploitation
53/59
XP Service Pack 2
Low Fragmentation Heap (LFH)
The RtlpLFHKey is a show stopper:push eaxcall _RtlRandomEx@4
mov _RtlpLFHKey, eax
lea eax, [ebp+var_4]
push eax
call _RtlRandomEx@4
imul eax, _RtlpLFHKey
push esi
mov _RtlpLFHKey, eax
XP Service Pack 2
8/4/2019 XPSP2 Heap Exploitation
54/59
XP Service Pack 2
Low Fragmentation Heap (LFH)
Must be enabled manually (viaNTDLL!RtlSetHeapInformation orKERNEL32!HeapSetInformation)
It is used for chunks < 16K
It is not used by anything on XP SP2 Professional
What irony
Summary
8/4/2019 XPSP2 Heap Exploitation
55/59
Summary
Win2K WinXP SP1
Fixed heap base and fixed PEB allow for writing verystable exploits
Overwriting FreeList/Lookaside list heads gives usthe ability to overwrite any writable address with 1Kof data
Summary
8/4/2019 XPSP2 Heap Exploitation
56/59
Summary
WinXP SP2
Decreases reliability (more bruteforcing is necessary)
But with enough time, exploitation will still succeed
XP SP2 will really slow worm propagation, but nothelp a targeted victim
...
Summary
8/4/2019 XPSP2 Heap Exploitation
57/59
Summary
WinXP SP2
Heap corruption handling is weak
PEB randomization is weak
Safe unlinking is evadable
Non-LFH cookie checks are weak
LFH looks good
Summary
8/4/2019 XPSP2 Heap Exploitation
58/59
Summary
Solutions
Use low fragmentation heap by default Just be sure it is the lowest address on the heap
Expand PEB randomization over 1MB or so
Most machines have 1GB+ RAM these days
Inform user if heap corruption exceeds a threshold
If I have an application with 50 corrupt chunks in 60seconds, I want to know someone is owning me
Check security cookies on allocation also
Summary
8/4/2019 XPSP2 Heap Exploitation
59/59
Su a y
The eventual death of 4 byte overwrites
Whether an attacker can predict theChunkSize/PrevSize or not, he/she wont be able to
predict a larger security cookie (like LFH has).
Heap exploits will focus more on attackingapplication data on the heap (not the heap itself)