Upgrade to Pro — share decks privately, control downloads, hide ads and more …

sleepyholder - HITCON 2016 writeup

Dhaval Kapil
December 14, 2017

sleepyholder - HITCON 2016 writeup

Dhaval Kapil

December 14, 2017

More Decks by Dhaval Kapil

Other Decks in Education


  1. sleepyholder HITCON 2016

  2. Challenge overview

  3. Challenge overview • Menu driven: ◦ Keep secret ◦ Wipe

    secret ◦ Renew secret
  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
  5. Challenge overview Renew secret if (***_secret_flag == 1) { read(0,

    ***_secret, ***_SIZE); } // but no renew for huge secret
  6. Challenge overview Wipe secret free(***_secret); // Vulnerability - Double Free

    ***_secret_flag = 0; // But no wipe for huge secret
  7. Problem • Unlike ‘secretholder’, we cannot allocate ‘huge_secret’ through ‘top_chunk’

  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.
  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.
  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
  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’
  12. https://github.com/DhavalKapil/ctf-writeups/blob/master/hitcon-2016/sleepyholder/ exploit.py [Exploit]