XPSP2 Heap Exploitation

download XPSP2 Heap Exploitation

of 59

Transcript of XPSP2 Heap Exploitation

  • 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)