House of Orange
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
The exploitation technique was fixed in this patch so this is no longer working (working in earlier than 2.26)
Same example with more comments in https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html
Abuse malloc_printerr
function
Overwrite the top chunk size
Libc and heap leaks
Some needed background from the comments from this example:
Thing is, in older versions of libc, when the malloc_printerr
function was called it would iterate through a list of _IO_FILE
structs stored in _IO_list_all
, and actually execute an instruction pointer in that struct.
이 공격은 가짜 _IO_FILE
구조체를 위조하여 **_IO_list_all
**에 쓸 것이며, malloc_printerr
를 실행하게 만듭니다.
그런 다음 _IO_FILE
구조체의 점프 테이블에 저장된 주소를 실행하게 됩니다. 우리는 코드 실행을 얻게 됩니다.
The attack starts by managing to get the top chunk inside the unsorted bin. This is achieved by calling malloc
with a size greater than the current top chunk size but smaller than mmp_.mmap_threshold
(default is 128K), which would otherwise trigger mmap
allocation. Whenever the top chunk size is modified, it's important to ensure that the top chunk + its size is page-aligned and that the prev_inuse bit of the top chunk is always set.
To get the top chunk inside the unsorted bin, allocate a chunk to create the top chunk, change the top chunk size (with an overflow in the allocated chunk) so that top chunk + size is page-aligned with the prev_inuse bit set. Then allocate a chunk larger than the new top chunk size. Note that free
is never called to get the top chunk into the unsorted bin.
The old top chunk is now in the unsorted bin. Assuming we can read data inside it (possibly due to a vulnerability that also caused the overflow), it’s possible to leak libc addresses from it and get the address of _IO_list_all.
An unsorted bin attack is performed by abusing the overflow to write topChunk->bk->fwd = _IO_list_all - 0x10
. When a new chunk is allocated, the old top chunk will be split, and a pointer to the unsorted bin will be written into _IO_list_all
.
The next step involves shrinking the size of the old top chunk to fit into a small bin, specifically setting its size to 0x61. This serves two purposes:
Insertion into Small Bin 4: When malloc
scans through the unsorted bin and sees this chunk, it will try to insert it into small bin 4 due to its small size. This makes the chunk end up at the head of the small bin 4 list which is the location of the FD pointer of the chunk of _IO_list_all
as we wrote a close address in _IO_list_all
via the unsorted bin attack.
Triggering a Malloc Check: This chunk size manipulation will cause malloc
to perform internal checks. When it checks the size of the false forward chunk, which will be zero, it triggers an error and calls malloc_printerr
.
The manipulation of the small bin will allow you to control the forward pointer of the chunk. The overlap with _IO_list_all is used to forge a fake _IO_FILE structure. The structure is carefully crafted to include key fields like _IO_write_base
and _IO_write_ptr
set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code (e.g., the system
function) can be executed.
To summarize the remaining part of the technique:
Shrink the Old Top Chunk: Adjust the size of the old top chunk to 0x61 to fit it into a small bin.
Set Up the Fake _IO_FILE
Structure: Overlap the old top chunk with the fake _IO_FILE structure and set fields appropriately to hijack execution flow.
The next step involves forging a fake _IO_FILE structure that overlaps with the old top chunk currently in the unsorted bin. The first bytes of this structure are crafted carefully to include a pointer to a command (e.g., "/bin/sh") that will be executed.
Key fields in the fake _IO_FILE structure, such as _IO_write_base
and _IO_write_ptr
, are set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code can be executed. Typically, this would be the address of the system
function or another function that can execute shell commands.
The attack culminates when a call to malloc
triggers the execution of the code through the manipulated _IO_FILE structure. This effectively allows arbitrary code execution, typically resulting in a shell being spawned or another malicious payload being executed.
Summary of the Attack:
Set up the top chunk: Allocate a chunk and modify the top chunk size.
Force the top chunk into the unsorted bin: Allocate a larger chunk.
Leak libc addresses: Use the vulnerability to read from the unsorted bin.
Perform the unsorted bin attack: Write to _IO_list_all using an overflow.
Shrink the old top chunk: Adjust its size to fit into a small bin.
Set up a fake _IO_FILE structure: Forge a fake file structure to hijack control flow.
Trigger code execution: Allocate a chunk to execute the attack and run arbitrary code.
This approach exploits heap management mechanisms, libc information leaks, and heap overflows to achieve code execution without directly calling free
. By carefully crafting the fake _IO_FILE structure and placing it in the right location, the attack can hijack the control flow during standard memory allocation operations. This enables the execution of arbitrary code, potentially resulting in a shell or other malicious activities.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)