$30 off During Our Annual Pro Sale. View Details »

sleepyholder - HITCON 2016 writeup

Dhaval Kapil
December 14, 2017

sleepyholder - HITCON 2016 writeup

Dhaval Kapil

December 14, 2017
Tweet

More Decks by Dhaval Kapil

Other Decks in Education

Transcript

  1. sleepyholder
    HITCON 2016

    View Slide

  2. Challenge overview

    View Slide

  3. Challenge overview
    ● Menu driven:
    ○ Keep secret
    ○ Wipe secret
    ○ Renew secret

    View Slide

  4. Challenge overview
    Keep secret
    if (***_secret_flag == 0) {
    ***_secret = calloc(1, ***_SIZE);
    ***_secret_flag = 1;
    read(0, ***_secret, ***_SIZE);
    }
    SMALL_SIZE = 40 (fast chunk)
    BIG_SIZE = 4000 (large chunk)
    HUGE_SIZE = 400000

    View Slide

  5. Challenge overview
    Renew secret
    if (***_secret_flag == 1) {
    read(0, ***_secret, ***_SIZE);
    }
    // but no renew for huge secret

    View Slide

  6. Challenge overview
    Wipe secret
    free(***_secret); // Vulnerability - Double Free
    ***_secret_flag = 0;
    // But no wipe for huge secret

    View Slide

  7. Problem
    ● Unlike ‘secretholder’, we cannot allocate ‘huge_secret’ through ‘top_chunk’

    View Slide

  8. Solution
    ● Hint given: ‘malloc_consolidate’
    ● malloc_consolidate: Removes all chunks in fastbin, consolidate if possible,
    insert back into unsorted bin - used to prevent fragmentation.
    ● ‘malloc_consolidate’ is called in certain cases. One of them being: ‘allocating
    a large chunk and no candidate chunk found in any bin’ [code].
    ● Fast chunks in fastbin are still considered ‘in_use’ to prevent consolidation.
    ● Trick: Freeing a fastbin doesn’t set the PREV_IN_USE bit of next chunk to 1.
    Allocating a fast chunk from a fastbin also doesn’t set the bit to 1. It simply
    assumes that it already is 1.

    View Slide

  9. Attack
    1. Keep small-> fast chunk allocated
    2. Keep big -> large chunk allocated
    3. Wipe small -> fast chunk inserted in fastbin (PREV_IN_USE of large chunk is
    still set)
    4. Keep huge -> no candidate chunk in any bin, ‘malloc_consolidate’ causes
    fast chunk in unsorted bin and then into small bin. PREV_IN_USE of large
    chunk cleared to 0.
    5. Wipe small -> chunk again inserted in fast chunk, PREV_IN_USE bit of large
    chunk still 0.
    6. Keep small -> chunk returned from fastbin, PREV_IN_USE bit of large chunk
    still 0.

    View Slide

  10. Attack
    ● Create a fake chunk in small secret with fd pointing to ‘small_secret - 3’ and
    bk pointing to ‘small_secret - 2’.
    ● Adjust previous size of ‘big_secret’. PREV_IN_USE bit already 0
    ● Free ‘big_secret’
    ● ‘small_secret’ now points to a few bytes before ‘big_secret’ -> Arbitrary write

    View Slide

  11. Attack (similar to ‘secretholder’)
    ● Update read’s GOT with puts@plt and leak out libc address of say puts’ GOT
    ● Calculate system’s libc address and update free’s GOT with it.
    ● Free any chunk with ‘/bin/sh\x00’

    View Slide

  12. https://github.com/DhavalKapil/ctf-writeups/blob/master/hitcon-2016/sleepyholder/
    exploit.py
    [Exploit]

    View Slide