Exploring and Exploiting Malloc

download Exploring and Exploiting Malloc

of 75

Transcript of Exploring and Exploiting Malloc

  • 8/3/2019 Exploring and Exploiting Malloc

    1/75

    Exploring and Exploiting

    malloc

    Breaking the Heap for Fun and

    Profit

  • 8/3/2019 Exploring and Exploiting Malloc

    2/75

    Lets store some data in C-

    #include

    int main()

    { int a = 5;

    }

  • 8/3/2019 Exploring and Exploiting Malloc

    3/75

    This allocates memory on the stack

    Can only be allocated at compile time

  • 8/3/2019 Exploring and Exploiting Malloc

    4/75

    What about allocating during run time?

    Use malloc() for dynamic allocation

  • 8/3/2019 Exploring and Exploiting Malloc

    5/75

    #include

    int main()

    {int *a = malloc(sizeof(int)); /*Size

    can be given at runtime*/

    }

  • 8/3/2019 Exploring and Exploiting Malloc

    6/75

    What about buffer overflows?

    Basically occur when data input exceedsthe memory available

    DataOtherstuff

    Input

    Overflowed

  • 8/3/2019 Exploring and Exploiting Malloc

    7/75

    Memory ahead gets CORRUPTED!!

    Can lead from breaking programexecution to getting control over the OS

  • 8/3/2019 Exploring and Exploiting Malloc

    8/75

    Buffer Overflows: Stack overflow:

    #include

    int main(){

    char ch[50];

    scanf(%s, ch);}

  • 8/3/2019 Exploring and Exploiting Malloc

    9/75

    Stack overflow exploited since Stack isalso used to store IP during function calls

    Overriding stack could lead to controllingIP, hence program execution

  • 8/3/2019 Exploring and Exploiting Malloc

    10/75

    What about the Heap?

    The heap is specialized to store onlydata. So how to exploit overflow?

  • 8/3/2019 Exploring and Exploiting Malloc

    11/75

    To exploit the Heap, we need tounderstand malloc() and the memory

    allocator

  • 8/3/2019 Exploring and Exploiting Malloc

    12/75

    Malloc(), free() and realloc() are functionsof a dynamic memory allocator.

    Many allocators are available. The mostcommon one is Doug Leas allocator (called

    Dlmalloc).

  • 8/3/2019 Exploring and Exploiting Malloc

    13/75

    So, how does the memory allocator

    allocate memory?

    Well, it already has memory, and can

    always obtain more from the OS. Theproblem is managing this block of memoryinto individual variables, which can befreed and allocated at any time duringprogram execution

  • 8/3/2019 Exploring and Exploiting Malloc

    14/75

    Basically, memory is allocated in terms ofchunks. The entire heap memory isdivided into chunks.

    There are basically 2 kinds of chunks:

    -> Allocated chunks

    -> Free chunks

  • 8/3/2019 Exploring and Exploiting Malloc

    15/75

    Allocated chunks look like this in memory-

  • 8/3/2019 Exploring and Exploiting Malloc

    16/75

    And Free chunks like this-

  • 8/3/2019 Exploring and Exploiting Malloc

    17/75

    There is only one rule governing chunks:No 2 free chunks can be neighboring.

    Alongside with these chunks, there is aspecial chunk, the wilderness chunk.This is basically a special free chunk,

    located at the top of the availablememory

  • 8/3/2019 Exploring and Exploiting Malloc

    18/75

    So, our chunks could possibly look like this

    Chunk 1:Allocated

    Chunk 2:Free

    Chunk 3:Allocated

    Chunk 4:Allocated

    Wilderness chunk(Free, but special)

    Memory Addresses

  • 8/3/2019 Exploring and Exploiting Malloc

    19/75

    While the allocated blocks are returnedback to the user, what about freechunks?

    DLMalloc keeps a track of the freechunks using a binning system. Stores

    Free chunks in 128 bins

  • 8/3/2019 Exploring and Exploiting Malloc

    20/75

    There are 128 bins.In each bin, free chunks of particular sizeare stored. In the first 62 bins (called

    small bins), chunks of exact size arestored

    Bin 2: 16 bytefree chunks

    only

    Bin 3: 24 bytefree chunks

    only

    Bin 63: 508byte free

    chunks only..

  • 8/3/2019 Exploring and Exploiting Malloc

    21/75

    The remaining bins store chunks in aparticular range. The chunks are orderedin each bin in descending order

    Bin 64: 512-575 bytes

    Bin 65: 576 639 bytes

    Bin 128: Upto231 bytes

    ..

  • 8/3/2019 Exploring and Exploiting Malloc

    22/75

    Checkpoint:Introduction: Check

    Overflows: Check

    DLMalloc Intro: CheckChunks in Heap: Check

    Binning System for Free Chunks: Check

  • 8/3/2019 Exploring and Exploiting Malloc

    23/75

    Now that we saw the structure of theheap, lets see the main macros that areused, especially in the binning system.

    Unlink() and FrontLink()

    Consequently, these are the macros which

    will help exploit overflows

  • 8/3/2019 Exploring and Exploiting Malloc

    24/75

    Unlink() Macro:To remove a free chunk from a bins list.Quite simply put

    #define unlink( P, BK, FD ) { \

    BK = P->bk; \

    FD = P->fd; \

    FD->bk = BK; \

    BK->fd = FD; \}

  • 8/3/2019 Exploring and Exploiting Malloc

    25/75

    Frontlink() Macro:

    Does just the opposite: Adds a free chunk

    into a bin. *Not* so simply put-#define frontlink( A, P, S, IDX, BK, FD ) { \if ( S < MAX_SMALLBIN_SIZE ) { \

    IDX = smallbin_index( S ); \mark_binblock( A, IDX ); \BK = bin_at( A, IDX ); \FD = BK->fd; \P->bk = BK; \P->fd = FD; \

    FD->bk = BK->fd = P; \} else { \

    IDX = bin_index( S ); \BK = bin_at( A, IDX ); \FD = BK->fd; \if ( FD == BK ) { \

    mark_binblock(A, IDX); \} else { \

    while ( FD != BK && S < chunksize(FD) ) { \

    FD = FD->fd; \} \BK = FD->bk; \

    } \P->bk = BK; \P->fd = FD; \FD->bk = BK->fd = P; \

    } \}

  • 8/3/2019 Exploring and Exploiting Malloc

    26/75

    We see a lot of pointer operations goingon the macro to exploit

    But what calls these macros anyways?

  • 8/3/2019 Exploring and Exploiting Malloc

    27/75

    Malloc() !!

    Free() !!

    realloc() !!

    Lets see what malloc() and free() are.

    realloc() can also be exploited in a similarway as malloc(), so not discussed

  • 8/3/2019 Exploring and Exploiting Malloc

    28/75

  • 8/3/2019 Exploring and Exploiting Malloc

    29/75

  • 8/3/2019 Exploring and Exploiting Malloc

    30/75

    Step 2: The most recently remainderedchunk is used if large enough. If it is

    large enough, it is split into 2 parts. Thefirst is allocated, the other becomes thenew MRR chunk. If it aint big enough

    though, just put it in bin, and go Step 3

  • 8/3/2019 Exploring and Exploiting Malloc

    31/75

    Step 3: Other bins are scanned inincreasing order for chunks. If large

    enough chunk is found, remove from bin(using unlink) and split into parts. Thefirst part is allocated, the second

    becomes the MRR chunk.If there is no large enough chunkanywhere in bins, go step 4

    Free Chunk: 900bytes

    Unlink()

    Allocated: 600bytes

    Free Chunk: MRRchunk 300 bytes

  • 8/3/2019 Exploring and Exploiting Malloc

    32/75

    Step 4: Check if wilderness chunk is largeenough. If it is, then split into 2 parts.Allocate the lower part, while the upperpart becomes the new wilderness chunk

    If wilderness chunk is also not large

    enough, go to step 5

    Wilderness chunkNew Wildernesschunk

    Allocated Chunk

  • 8/3/2019 Exploring and Exploiting Malloc

    33/75

    Step 5: Ask the OS for help. Use sbrkand mmap to expand memory available. If

    this also fails, then just give up already!

  • 8/3/2019 Exploring and Exploiting Malloc

    34/75

    Ok. So that was malloc() :

    First check if perfect free chunk exists.

    Then check MRR chunk. Then check binsfor large chunks to be splitted. Thencheck the wilderness chunk. If this alsofails, ask OS for help.

  • 8/3/2019 Exploring and Exploiting Malloc

    35/75

    Free(): To perform the opposite ofmalloc(). It frees up an allocated chunk,

    adding it to bins (and coalescing withneighboring chunks)

  • 8/3/2019 Exploring and Exploiting Malloc

    36/75

    How does free() work?

    Step 1: If chunk borders wildernesschunk, coalesce into a bigger wildernesschunk. Also, coalesce the previous

    neighbor free chunk if exists

    Wilderness chunk

    Allocated Chunk

    Free Chunk

    New Wilderness Chunk

    Unlink()

  • 8/3/2019 Exploring and Exploiting Malloc

    37/75

    Step 2: Coalesce free chunk with its freechunk neighbors. Remove each free chunk

    neighbor by unlink(), then consolidate.Finally, frontlink() the new big free chunk

    Free Chunk

    Allocated Chunk

    Free Chunk

    Coalesced Free Chunk

    Unlink()

    Unlink()

    FrontLink()

  • 8/3/2019 Exploring and Exploiting Malloc

    38/75

    Done.

    Thus, weve just seen the basic steps usedin malloc() and free() .

  • 8/3/2019 Exploring and Exploiting Malloc

    39/75

    Before we start digging into the exploit,we must explore a few details more

  • 8/3/2019 Exploring and Exploiting Malloc

    40/75

    Just to recollect, allocated chunks looklike this in memory-

  • 8/3/2019 Exploring and Exploiting Malloc

    41/75

    While free chunks look like this

  • 8/3/2019 Exploring and Exploiting Malloc

    42/75

    The prev_size field of a chunk: This 4byte field is the first field in a chunk.

    If the chunk previous to this one is free,then this field stores the size of thatfree field.

  • 8/3/2019 Exploring and Exploiting Malloc

    43/75

    If the previous chunk is not free, though,then this field is overwritten by the userdata of the previous chunk (andconsidered during malloc() )

  • 8/3/2019 Exploring and Exploiting Malloc

    44/75

    How to know if a chunk is free or not?

    The chunk itself does not contain this

    information.T

    he next chunks size field,however, contains 2 flags, one of which isPREV_INUSE, which specifies if previouschunk is free or allocated

  • 8/3/2019 Exploring and Exploiting Malloc

    45/75

    AndLastly, how function calls actually dotake place?

    Due to concerns of relocating, a call tofunction func() is not replaced in assemblyby call

    main(){func();

    }

    func(){

    }

    call

  • 8/3/2019 Exploring and Exploiting Malloc

    46/75

    Instead, we have a Global Offset Table

    which stores all function pointers. A callto a function would actually first go tothe GOT, get the function pointer fromthere, and then go to that function

    pointer

    main(){func();

    }

    func(){

    }

    call

    Global Offset TableFunction ptr1Function ptr 2

  • 8/3/2019 Exploring and Exploiting Malloc

    47/75

    Armed with this knowledge, lets exploitHeap overflows!!

    Well discuss 2 methods:(a)Using the unlink() (easier)

    (b)Using the frontlink() (not so easy)

  • 8/3/2019 Exploring and Exploiting Malloc

    48/75

    Exploiting unlink():We see that unlink() is

    Check out line 4. We see that we can

    modify the value of memory locationspecified

    (1) #define unlink( P, BK, FD ) { \

    (2) BK = P->bk; \

    (3) FD = P->fd; \(4) FD->bk = BK; \(5) BK->fd = FD; \

    (6)}

  • 8/3/2019 Exploring and Exploiting Malloc

    49/75

    Why would we want to modify the value ofa particular memory location?

    We could modify the memory location inGOT, and set a function pointer to pointto our code. Thus, when that function is

    called, our code is executed instead

  • 8/3/2019 Exploring and Exploiting Malloc

    50/75

    We could specify FD as the location in

    GOT, while BK would be the location ofour shell code (custom code to do nastystuff such as spawn a shell)

  • 8/3/2019 Exploring and Exploiting Malloc

    51/75

    Ok. But how do you call unlink() with sucha free block with bad bk and fd?

    1. We can overflow a buffer, causing thechunk to be designated injustly asfree, and call unlink at step 2 of free()

    2.W

    e can overflow a buffer, causing anexisting free block to have overwrittenbk and fd. In this case, this blockwould be inaccessible since it would be

    effectively out of bin.

    So method 1 it is!

  • 8/3/2019 Exploring and Exploiting Malloc

    52/75

    Lets jump directly into the code!(1) #include

    (2)

    (3) int main(void)(4) {(5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    When malloc(768) is called, the wildernesschunk is split to allocate memory. P wouldalso be a chunk split from wilderness chunk

    overflow P Wilderness Chunk

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    53/75

    We can overflow overflow, and can hencewrite into p. We can change the size fieldof this chunk, and modify so that p is

    designated as a free chunk

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    54/75

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    Prev_sizesize

    User Data

    overflow

    Prev_sizesize

    User Data

    P

    Input

    (overflowed)

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    55/75

    Now, we must make p free chunk. Thus,next chunks size must be modified. We canmodify the location of next chunk by

    modifying the size of p. We can put thenext chunk somewhere in user-data of p

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    56/75

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    Prev_size

    Size : modified

    User Data

    P

    Prev_size of next chunk

    Size of next chunk

    Indicates p is free

    Prev_size

    Size

    fd

    bk

    Free Space

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    57/75

    Since p is thought to be free, whenfree(overflow) is called, since p is free(), itwill be coalesced with overflow. Thus,

    unlink would be called on p.We must thus, in the overflow itself, putproper values of fields of fd and bk

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    (1) #include

  • 8/3/2019 Exploring and Exploiting Malloc

    58/75

    (1) #include

    (2)

    (3) int main(void)

    (4) {

    (5) char* overflow = malloc(768);

    (6) char* p = malloc(64);(7) scanf("%s",overflow);

    (8) free(overflow);

    (9) free(p);

    (10) return 0;

    (11)}

    P

    Prev_size

    Size

    fd

    bk

    Free Space

    shellcode

    Function pointer

    Thus we see that the final shellcode takes

  • 8/3/2019 Exploring and Exploiting Malloc

    59/75

    Thus, we see that the final shellcode takeson the form

  • 8/3/2019 Exploring and Exploiting Malloc

    60/75

    Voila Instant shell with the above exploit.

    Now for introduction 2nd method: Usingfrontlink()

    Just to recollect the frontlink() macro is

  • 8/3/2019 Exploring and Exploiting Malloc

    61/75

    Just to recollect, the frontlink() macro is#define frontlink( A, P, S, IDX, BK, FD ) { \

    if ( S < MAX_SMALLBIN_SIZE ) { \

    IDX = smallbin_index( S ); \

    mark_binblock( A, IDX ); \

    BK = bin_at( A, IDX ); \

    FD = BK->fd; \

    P->bk = BK; \

    P->fd = FD; \

    FD->bk = BK->fd = P; \

    (1) } else { \

    IDX = bin_index( S ); \

    BK = bin_at( A, IDX ); \FD = BK->fd; \

    if ( FD == BK ) { \mark_binblock(A, IDX); \

    } else { \(2) while ( FD != BK && S < chunksize(FD) ) { \

    (3) FD = FD->fd; \

    } \

    (4) BK = FD->bk; \} \

    P->bk = BK; \

    P->fd = FD; \

    (5) FD->bk = BK->fd = P; \

    } \

    }

    We see the important lines

  • 8/3/2019 Exploring and Exploiting Malloc

    62/75

    We see the important lines(1) } else { \

    IDX = bin_index( S ); \BK = bin_at( A, IDX ); \FD = BK->fd; \

    if ( FD == BK ) { \mark_binblock(A, IDX); \} else { \

    (2) while ( FD != BK && S < chunksize(FD) ) { \(3) FD = FD->fd; \

    } \

    (4) BK = FD->bk; \} \P->bk = BK; \P->fd = FD; \

    (5) FD->bk = BK->fd = P; \} \

    }

    This else is executed only for bigger bins.

    We see that in 2, the loops finds the largestfd that is smaller than S. In line 4, BK isassigned FD->bk . And in 5, we set fd fieldsof BK, ie: (FD->bk)->fd

    (1) } else { \IDX bi i d ( S ) \

  • 8/3/2019 Exploring and Exploiting Malloc

    63/75

    IDX = bin_index( S ); \BK = bin_at( A, IDX ); \FD = BK->fd; \if ( FD == BK ) { \

    mark_binblock(A, IDX); \} else { \

    (2) while ( FD != BK && S < chunksize(FD) ) { \(3) FD = FD->fd; \

    } \

    (4) BK = FD->bk; \} \P->bk = BK; \P->fd = FD; \

    (5) FD->bk = BK->fd = P; \} \

    }

    Thus, if we can create a FD with an bk beinga function pointer location, then BK->fdwould allow us to overwrite the function

    pointer with the location of custom code.

    (1) } else { \IDX bin index( S ); \

  • 8/3/2019 Exploring and Exploiting Malloc

    64/75

    IDX = bin_index( S ); \BK = bin_at( A, IDX ); \FD = BK->fd; \if ( FD == BK ) { \

    mark_binblock(A, IDX); \} else { \

    (2) while ( FD != BK && S < chunksize(FD) ) { \

    (3) FD = FD->fd; \} \

    (4) BK = FD->bk; \} \P->bk = BK; \P->fd = FD; \

    (5) FD->bk = BK->fd = P; \} \

    }

    But we can only overwrite BK->fd with P. Whatif P is not susceptable to overflow?

    No problem. If we can store data in chunkprevious to P, then prev_size would contain thatdata as well. Thus, the first 4 bytes of P can be

    a jump statement to the actual shellcode

    Digging directly into the code lets see a

  • 8/3/2019 Exploring and Exploiting Malloc

    65/75

    Digging directly into the code, let s see aprogram that can be exploited usingfrontlink()#include

    int main(void)

    {char* first, second, third, fourth, fifth, sixth;

    first = malloc(800);

    second = malloc(640);third = malloc(200);

    fourth = malloc(644);fifth = malloc(200);

    sixth = malloc(16);

    scanf("%800s",first);

    free(fifth);

    scanf("%s",fourth); //Overflowablefree(second); //Injected here

    return 0;

    }

  • 8/3/2019 Exploring and Exploiting Malloc

    66/75

    Here, we first can overflow fourth afterfifth is free()d. Thus, we can overwrite

    fifth, which is already present in the bin,and hence the value of bk in fifth

  • 8/3/2019 Exploring and Exploiting Malloc

    67/75

    When second is free()d, the last step offree() executes, which involves puttingsecond in the bin. This involves

    Frontlink(second), which would take place inthe same bin as fifth.

  • 8/3/2019 Exploring and Exploiting Malloc

    68/75

    Since fifth->bk points to function pointer,the function pointer can be overwritten withaddress of second

  • 8/3/2019 Exploring and Exploiting Malloc

    69/75

    We can add text to first. We fill in thelast 4 bytes of first with a jump to theshellcode present in the rest of first.These last 4 bytes will be present inprev_size of second, ie, pointed by the

    function pointer

    h ll h l d

  • 8/3/2019 Exploring and Exploiting Malloc

    70/75

    In a nutshell, the exploit designs are

  • 8/3/2019 Exploring and Exploiting Malloc

    71/75

    Voila! Instant shell code execution using

    frontlink()

  • 8/3/2019 Exploring and Exploiting Malloc

    72/75

    And so, we saw in the presentation, 2 waysto exploit overflows in the heap to allow

    arbitrary code execution

  • 8/3/2019 Exploring and Exploiting Malloc

    73/75

    The main references for this presentation:

    Vudo Malloc Tricks. Kaempf, Michel

    "MaXX". 2007, Phrack 57, p. 0x08. Heap Overflow Tutorial

    Along with the description of Dlmalloc andits source

    Also, the article Once upon a free provided

    insights into the working of free() withunlinkMe blocks

  • 8/3/2019 Exploring and Exploiting Malloc

    74/75

    Further reading:

    Advanced Doug lea's malloc exploits

    Malloc Maleficarum

    The House of Mind

  • 8/3/2019 Exploring and Exploiting Malloc

    75/75

    By,

    Gaurav Mogre

    06co36