House of Orange
The original House of Orange technique used a heap overflow vulnerability
to target the top chunk
in its first stage of exploitation. Due to this fact,
we can determine that the House of Orange fits within this section of heap
exploitation.
The technique
The House of Orange is an interesting, but somewhat convoluted, technique to gain arbitrary code execution of a vulnerable process. The House of Orange is executed in three stages:
-
Leverage a heap overflow vulnerability to overwrite the size field of the
top chunk
.- Overwrite the
top chunk
with a small size, foolingmalloc()
in future requests to believe that thetop chunk
is smaller than it actually is. - The new
top chunk
size must be page-aligned and theprev_inuse
bit must be set in order to passmalloc()
checks. - The attacker forces the program to make another
malloc()
call with a size larger than what is currently written to thetop chunk
size field. - This
malloc()
call will causemalloc()
tommap()
a new segment of heap memory.malloc()
will also determine that the new segment of heap memory and thetop chunk
are not contiguous, causingmalloc()
tofree()
the remaining space of thetop chunk
. - This newly free chunk will be too large for the fastbin, it will be linked into the unsortedbin.
- Overwrite the
-
Use the same heap overflow vulnerability and chunk to overwrite the newly freed
top chunk
that resides in the unsortedbin.- The attacker forges the metadata for a fake chunk, setting the chunk size
to
0x61
, and setting thebk
pointer to a chunk that overlaps_IO_list_all
inglibc
. - The attacker will use this to conduct an Unsortedbin Attack, writing
the memory address of the unsortedbin head in the
main arena
to_IO_list_all
. - The attacker uses the heap overflow to write a fake
_IO_FILE
struct into the heap, forging avtable_ptr
that points back into attacker controlled memory with the intent of overwriting theoverflow
method of the struct tosystem()
.
- The attacker forges the metadata for a fake chunk, setting the chunk size
to
-
The attacker requests a chunk smaller than the forged chunk that was just created, causing
malloc()
to sort the free chunk into the smallbin, triggering an Unsortedbin Attack.malloc()
attempts to follow our forgedbk
, however, chunk metadata checks will causemalloc()
to call__malloc_printerr()
, leading to aSIGABRT
.- When the program begins its exit procedures, it attempts to clear the buffers of all open file streams, including our forged one.
glibc
follows_IO_list_all
which now points to themain_arena
. Themain_arena
fails_IO_FILE
struct checks, andglibc
moves on to the next_IO_FILE
struct pointed to by themain_arena
's fakechain
member - our smallbin.glibc
inspects the forged_IO_FILE
struct the attacker created in the heap using a heap overflow and executes theoverflow
method listed in thevtable
of the forged_IO_FILE
struct. The attacker has overwritten theoverflow
method listed in thevtable
to point tosystem()
.- The address of the
_IO_FILE
is passed to this call tosystem()
- the attacker ensures that the string/bin/sh\0
resides at this location, the very first word of bytes in the forged_IO_FILE
struct.
Some notes
Like I said, this technique is convoluted. The attacker needs to have the following in order to exploit this vulnerability:
- Ability to edit chunk data
- Ability to control
malloc()
allocation size - Heap and
glibc
address leak ifASLR
is enabled - Heap overflow
Patch
There doesn't seem to be any specific patch that attempts to mitigate
exploitation using the House of Orange. Because there are so many
conditions necessary to effectively exploit this technique, the summation of
the mitigations applied to glibc
over the years have made this technique
obsolete.
For instance, the patch applied to actually check the validity of the bk
pointer in the unsortedbin causes the Unsortedbin Attack used to execute
this technique to fail. In addition, glibc
after version 2.28
no longer
traverses through all open file streams at program exit to call the overflow
method of the stream. This mitigation thwarts this techniques use of
File Stream Oriented Programming to gain code execution.