The House of Force
Exploiting the wilderness
Glibc Version
*-2.29
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!
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?