ROP

Stack pivoting

One gadget


Heap

  • malloc never clears the user data unless calloc is used
  • glibc-2.32 onwards have safe-linking.

safe-linking

  • fd pointers in tcache and fastbins are mangled to make exploitation harder.
  • straight-forward principle: use randomness from ASLR to mangle ptrs.
  • heap leak is needed to break safe-linking.
  • target address should be 0x10 byte aligned
def mangle(pos, ptr):
    """
    pos: int = position of heap chunk
    ptr: int = ptr we need. This should be 0x10 byte aligned
    """
    return (pos >> 12) ^ ptr

tcache

  • The free bin is a single linked list (LIFO based).
  • Used to store small freed allocations .
  • 7 allocations per bin.
  • ptr = malloc(size); free(ptr) with size <= 0x408 will go in tcache.
  • “thread” cache. So one tcache per thread.

NOTE-1: >= glibc-2.32 requires heap leak for breaking safe-linking.


NOTE-2: malloc clears out key field (address+8) for tcache


tcache bin struct:

typedef struct tcache_perthread_struct {
    char counts[TCACHE_MAX_BINS];
    tcache_entry* entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;

tcache entry struct:

typedef struct tcache_entry {
    struct tcache_entry* next;
    uintptr_t *key;
} tcache_entry;

key field prevents double-free.

https://elixir.bootlin.com/glibc/glibc-2.35/source/malloc/malloc.c#L312

Arbitrary Access Read/Write (AAW / AAR)

  • UAF write is required.
  • heap leak to break safe-linking
a = malloc(0x10);
b = malloc(0x10);
free(a);
free(b);

// tcache freelist: [b -> a -> NULL]
// write to b, to overwrite next ptr
// take care of safelinking if needed

b = malloc(0x10); // freelist [ mangled_target -> NULL]
target = malloc(0x10); // get target

// write/read from target ... 

Double-free protection bypass

  • UAF write is required.
a = malloc(0x10);
free(a);

write(a, "abcdefghijklmnop", 0x10); // overwrite the key(+8) field

free(a); // double free

House of spirit

The main principle: free(ptr) doesn’t check if the ptr points to valid heap memory, so if we can craft a fake “malloc” like chunk (with chunk size <= 0x410 and malloc arg <= 0x408) then freeing this ptr will add the address pointed by chunk on tcache.

Requirments:

  • Free on near arbitrary ptr (ptr needs to be 0x10 byte aligned).

pseudocode rough sketch:

uint64_t fake_chunks[10];
fake_chunks[1] = 0x40; // chunk size
a = &fake_chunks[2];
free(a);

void* b = malloc(0x35); // get chunk of size 0x40

// b == &fake_chunks[2] (user controlled address)

how2heap poc

Fastbins

House of spirit

Largebins

Largebin attack

Unsorted bins

Unsafe unlinking


FSOP

AAW

AAR

Control Flow Hijacking

Random notes


Format String

AAR

AAW

Control Flow Hijacking


memory “hopping”

environ

Breaking ASLR

Breaking PIE

Breaking canary

Timing side channel