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
Tweet

More Decks by Dhaval Kapil

Other Decks in Education

Transcript

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

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

    ***_secret_flag = 0; // But no wipe for huge secret
  4. 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.
  5. 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.
  6. 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
  7. 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’