cscg24-flipnote

CSCG 2024 Challenge 'FlipNote'
git clone https://git.sinitax.com/sinitax/cscg24-flipnote
Log | Files | Refs | sfeed.txt

notes (3347B)


      1Download ubuntu package using link:
      2https://launchpad.net/ubuntu/jammy/amd64/libc6-dbg/2.35-0ubuntu3.6
      3
      4reuse this link and replace package name to get direct download links.. archive only shows latest patch version for reasons(tm).
      5
      6House of muney exploit:
      7- allocate mmap'd heap chunk by making size larger than mmap_threshold
      8
      9allocated chunk has size 0x3d000, so we flip two bits to 0x5d000 (pew, pew)
     10that gives us 0x40000 to libc base and 0x1d000 into the libc address space
     11which is perfect for House of Muney exploit (after dynsym end, before plt etc)
     12
     13there is a heap chunk mapped by libc for thread-local variables between
     14our chunk and the start of libc.. this prevents us from unmapping our
     15modified heap chunk, since it would unmap thread-local variables such
     16as errno (e.g. which is accessed right after munmap!)
     17
     18but.. maybe there is something interesting in thread local chunk..
     19
     20maybe the exit handler is stored there? nope
     21
     22there is no info leak.. even puts() on the line_buf is called
     23directly after read_line, meaning it has to be null-terminated
     24(except if we close stdin.. but then we cant use the info-leak anymore)
     25
     26
     27source analysis:
     28
     29- add_note assigns to sizes[i] the size of the buffer without its terminator,
     30  since the return value assignment happens after the internal one to the
     31  &sizes[i] pointer.
     32
     33- edit_note has a 1 byte (fixed-value) overwrite, since *size == sizes[index] + 2
     34  is allowed. the trailing newline is removed in memcpy, meaning
     35  sizes[index]+1 bytes can be written to the field. but there is an implicit
     36  null terminator part of the string.. so it does not allow OOB write, just
     37  a 'clean' overwrite of the data without terminators.
     38
     39- remove_note is missing a sizes[index] == 0 and as such does not prevent a double free
     40
     41- flip_bit only checks wether the notes pointer != NULL, not wether it was freed..
     42  this means we can flip a bit in a freed chunk
     43
     44
     45use how2heap repo to find examples exploits for vulnerable libc version 2.35
     46- fastbin_dup: fastbin free(a) + free(b) + free(a)
     47- fastbin_dup_consolidate: consolidate + double-free => chunk overlap
     48- fastbin_dup + write => arbitrary malloc (fastbin_dup_into_stack / anywhere)
     49- house of botcake: consolidate + double-free => chunk overlap with one in tcache
     50- house of muney: mmap chunk in front of libc, modify size field, munmap + remap to write into libc
     51- house of spirit: free artificial fake chunk into fastbin
     52- mmap_overlapping_chunks: (could give more precise munmap control)
     53- tcache_house_of_spirit: easier fake chunk into tcache
     54
     55
     56- why do you see calloc() in some heap exploitation writeups / how2heap?
     57  => calloc has an optimization, where if the region above the top chunk
     58  has not been used yet, splitting the top chunk is preferred to
     59  getting a potentially dirty chunk from tcache that would need to be cleared..
     60
     61
     62- once we have rip control, we can use a one gadget from the libc
     63
     64
     65- merge mmap chunk near heap, then free to tcache
     66
     67- maybe we flip a bit in the exit handler 0x1400 to jump back into main (e.g 0x1200)
     68- the exit handler stays registered and we keep our pointers allowing us 
     69
     70# Nomal House of Muney does not work here, because it would unmap errno.
     71
     72
     73Perhaps we can use the fact that stdin buf is on the stack.. we could flip the
     74pointer from libc RW section to overwrite stack variables and ROP?