The House of Force

Exploiting the wilderness

Glibc Version

Primitive Required

  • Heap overflow into the top chunk

  • Chunk allocation of arbitrary size

Primitive Gained

  • Arbitrary Write

In the House of Force, we overflow the size field of the top chunk with a huge value. We next allocate a huge chunk size. Due to the size overwrite, we bypass the top size check:

if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))

Because the check is passed, the we trick glibc into allocating the large request to the heap rather than use mmap(). This gives us a lot of control over the remainder chunk:

remainder_size = size - nb;
remainder = chunk_at_offset (victim, nb);
av->top = remainder;

Note that if we can control the allocation size (the nb variable here), we pass that size to chunk_at_offset():

/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s)  ((mchunkptr) (((char *) (p)) + (s)))

This macro takes the address and adds nb onto it - but because we have control over nb, we can control where the remainder chunk is placed, and therefore where the next top chunk is located. This means that the next allocation can be located at an address of our choice!

Note that we can even write to addresses ahead of the heap in memory by triggering an integer overflow!

TODO mathematics

TODO source

TODO patch

The Patch

In glibc 2.29, there is a new security check to protect against the House of Force:

if (__glibc_unlikely (size > av->system_mem))
    malloc_printerr ("malloc(): corrupted top size");

Very simple - check if the size is ridiculously large, and throw an error if so.

Last updated

Was this helpful?