Week 7

Heap Exploitation

Good Faith Policy

“These courses expects a high standard of professionalism from its students with regard to how security testing is conducted. We expect all students to act in good faith at all times […]”

TL;DR Don’t be mean

https://sec.edu.au/good-faith-policy

A summary of COMP6447
  • Buffer Overflows
  • Shellcode
  • Format Strings
  • Return Oriented Programming
  • Today: Heap Exploitation

Buffer Overflows

  • Vulnerable memory write functions that
    • Allow arbitrary input lengths
    • Allow longer than allocated lengths
  • Allows control of variables, stack frame, etc…
  • Not always gets / fgets
    • strcpy
  • Mitigation: Stack canaries
    • Defeat: Leak the stack canary
    • Guess it

Shellcode

  • Program is tricked into running arbitrary instructions supplied by the user
  • Pop a shell?
  • Mitigation
    • NX bit
      • Defeat: ROP
      • Disable NX
    • Small buffer * Defeat: Egg Hunters

Format Strings

  • [..]printf execution on user-controlled input
  • Allows arbitrary memory read
  • Allows arbitrary memory write
  • Mitigation: Be a better programmer™
    • Defeat: Find bad programmers /s

Return Oriented Programming

  • Exploits the multi-byte nature of instructions, where parts of instructions can be identified as their own instruction
  • Bypasses the NX bit, as the instruction address are part of the program’s text region (executable)
  • Mitigation: Quite hard. PAC?
    • Be a better programmer™ x2

General Protections

  • ASLR - System-level address randomisation
  • PIE - Application-level address randomisation
  • RELRO - Prevents modification of the GOT
  • NX - Prevents execution in heap / stack

Leak!

Attacking the GOT

  • If no RELRO - trivial
  • If partial RELRO - overwrite an uninitialised entry
  • If full RELRO - … overwrite a hook?

Uncertain Memory

  • NOP-sled
  • RET-sled
  • Egg Hunters
    • ROP Hunters

Heap

Chunks

A chunk can be in two states free, or in-use

chonk

Header Structure

Chunk :: In Use

  • Previous Size
  • Size
  • AMP*
  • Payload

Note: malloc returns the address of the payload

*AMP

  • Allocated Arena
  • Memory Mapped
  • Previous is Use
Header Structure

Chunk :: Free

  • Previous Size
  • Size
  • AMP
  • fwd
  • back
  • fd_nextsize
  • fd_previoussize
  • previoussize
  • blah blah blah…

  • Chunks are at LEAST 4 * sizeof(void*)
  • Hmm mixing data and control 🤔

free(chunk)

Freeing chunks need to be fast!

  • Instead of clearing the memory, we just unlink it!
  • Programs use several different types of ‘bins’ to efficiently store information about free’d memory.

Programs use several different types of ‘bins’ to efficiently store information about free’d memory.

  • Fast Bins
  • Unsorted Bins
  • Small Bin
  • Large Bin
  • TCache
Fast Bins
  • There are 10 fastbins
  • Small chunks are stored in size-specific bins
    • 16, 24, 32, 40, 48, 56, 64, 72, 80, 88 bytes
  • Each fastbin is essentially a single linked list
  • For each sized fastbin
    • Freed chunks added into to the start of the fastbin
    • Chunks are not combined with adjacent chunks
    • The first item in a fastbin is next allocated chunk
      • aka the last freed chunk of that fastbin
Unsorted Bins
  • For large chunks, when free'd, chunks are stored in a single bin of varying chunk sizes
  • Later sorted by malloc to be optimised

 

Other Bins

The normal bins are divided into 62 small bins (each bin has chunks of the same size), and two large bins (where each large bin has chunks of similar size)

TCache

Thread-local Cache

Faster than a global cache!

Arbitrarily sized bins that have a limit of 7 chunks (by default).
If 7 chunks have been free’d, tcache won’t be used

Note: calloc doesn’t use the tcache

Use After Free

When a chunk is freed, part of its contents is used as metadata… If we tamper with its contents, we can corrupt the linked list! This allows us to control the addresses of a future malloc chunk!

e.g. Modify the forward pointer…
malloc returns our own address!

                         // Bin: NULL
free(chunk)              // Bin: chunk -> (HEAD = NULL)
chunk = 0x41414141       // Bin: chunk -> 0x41414141 -> ???
dummy = malloc(...)      // Bin: 0x41414141 -> ???
pwn = malloc(...) ///////// pwn = 0x41414141

Double Free

Systems check that you haven’t free'd a memory address twice in a row.

free(a);
free(a);

// free(): double free detected
// Aborted (core dumped)

But… it doesn’t prevent this

free(a);
free(dummy);
free(a);

// ???

When a chunk is freed the second time…

                      // Bin: NULL
free(chunk);          // Bin: chunk -> (HEAD = NULL)
free(chunk);          // Bin: chunk -> (HEAD = chunk) -> NULL
puts(chunk.next) /////// chunk

// $$$

or maybe

                      // Bin: NULL
free(chunk);          // Bin: chunk -> (HEAD = NULL)
free(chunk);          // Bin: chunk -> (HEAD = chunk) -> NULL
malloc(...)     // some val
malloc(...)
malloc(...)     // the same val!???
// $$$

pwndbg

  • vis_heap_chunks
  • heap
  • arena
  • bins
    • ___bins

 

Demo time!

Double Free
Use After Free

heap-exploitation.dhavalkapil.com

Dates

  • Today, Tuesday, Week 7 @ 5.59pm - Wargames 5 Due
  • This Sunday 18/07 @ 5.59pm - Mid-point Fuzzer Due

 

Activities

🐏 (s)heap 🐑

Home