Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/binary-exploitation/libc-heap/house-of-orange.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

- Find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c)
- The exploitation technique was fixed in this [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) 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](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
- Same example **with more comments** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)<sup>[[2]](#references)</sup>

### Goal

Expand All @@ -21,21 +21,21 @@

### Background

Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**
Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**<sup>[[2]](#references)</sup>

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.\
This attack will forge a **fake `_IO_FILE` struct** that we will write to **`_IO_list_all`**, and cause `malloc_printerr` to run.\
Then it will **execute whatever address** we have stored in the **`_IO_FILE`** structs jump table, and we will get code execution<sup>[[2]](#references)</sup>

### Attack

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.<sup>[[1]](#references)</sup>
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.
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.<sup>[[1]](#references)</sup>

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`**.
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`**.<sup>[[2]](#references)</sup>

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:

Expand Down Expand Up @@ -69,10 +69,7 @@ This approach exploits heap management mechanisms, libc information leaks, and h

## References

- [1] [CTF-wiki - House of Orange](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
- [2] [Nightmare - House of Orange (guyinatuxedo)](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
- [1] [House of Orange - CTF Wiki](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
- [2] [House of Orange exploitation walkthrough - guyinatuxedo](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)

{{#include ../../banners/hacktricks-training.md}}



10 changes: 6 additions & 4 deletions src/binary-exploitation/libc-heap/house-of-rabbit.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

### POC 1: Modify the size of a fast bin chunk

**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk.
**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk.<sup>[[1]](#references)[[2]](#references)</sup>

- **Step 1: Allocate Chunks**

Expand Down Expand Up @@ -57,7 +57,7 @@ After consolidation, `chunk1` overlaps with `chunk2`, allowing for further explo

### POC 2: Modify the `fd` pointer

**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer.
**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer.<sup>[[1]](#references)[[2]](#references)</sup>

- **Step 1: Allocate Chunks**

Expand Down Expand Up @@ -108,7 +108,9 @@ The fake chunk becomes part of the fastbin list, making it a legitimate chunk fo

The **House of Rabbit** technique involves either modifying the size of a fast bin chunk to create overlapping chunks or manipulating the `fd` pointer to create fake chunks. This allows attackers to forge legitimate chunks in the heap, enabling various forms of exploitation. Understanding and practicing these steps will enhance your heap exploitation skills.

{{#include ../../banners/hacktricks-training.md}}

## References

- [1] [House_of_Rabbit - shift-crops (original technique/PoC)](https://github.com/shift-crops/House_of_Rabbit)
- [2] [House of Rabbit - CTF Wiki EN](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_rabbit/)

{{#include ../../banners/hacktricks-training.md}}
30 changes: 15 additions & 15 deletions src/binary-exploitation/libc-heap/house-of-roman.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

## Basic Information

This was a very interesting technique that allowed for RCE without leaks via fake fastbins, the unsorted_bin attack and relative overwrites. However it has been [**patched**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).<sup>[[7]](#references)</sup>
This was a very interesting technique that allowed for RCE without leaks via fake fastbins, the unsorted_bin attack and relative overwrites. However it has been [**patched**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).<sup>[[6]](#references)[[3]](#references)</sup>

### Applicability in 2026

- **glibc window:** Works reliably on **2.23–2.27** (the how2heap PoC tested 2.23–2.25). Starting **2.28**, the "additional checks for unsorted bin integrity" patch makes the unsorted‑bin write unreliable, so success drops sharply. From **2.34** onward `__malloc_hook/__free_hook` were removed, making the original target unavailable. Use it only on old libc's (or custom builds that keep the hooks) or for CTF challenges that ship an old libc.
- **glibc window:** Works reliably on **2.23–2.27** (the how2heap PoC tested 2.23–2.25). Starting **2.28**, the "additional checks for unsorted bin integrity" patch makes the unsorted‑bin write unreliable, so success drops sharply. From **2.34** onward `__malloc_hook/__free_hook` were removed, making the original target unavailable.<sup>[[5]](#references)</sup> Use it only on old libc's (or custom builds that keep the hooks) or for CTF challenges that ship an old libc.
- **Tcache era (≥2.26):** Tcache will eat your 0x70 allocations and stop the fastbin/unsorted primitives. Disable it (`setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);`) **before** any allocation or fill each 0x70 tcache bin with 7 frees to drain it.
- **Safe-linking:** It applies to tcache/fastbin in ≥2.32, but House of Roman only needs **partial pointer overwrite of a libc address already present in fd/bk**, so safe-linking does not help the defender here (the attacker never forges a fresh pointer). The real stopper is the hook removal and the unsorted-bin checks.

### Code

- You can find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)<sup>[[2]](#references)</sup>
- You can find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)<sup>[[1]](#references)</sup>

### Goal

Expand All @@ -36,7 +36,7 @@ Create several chunks:
- `main_arena_use` (0x80, offset 0x100)
- `relative_offset_heap` (0x60, offset 0x190): relative offset on the 'main_arena_use' chunk

Then `free(main_arena_use)` which will place this chunk in the unsorted list and will get a pointer to `main_arena + 0x68` in both the `fd` and `bk` pointers.
Then `free(main_arena_use)` which will place this chunk in the unsorted list and will get a pointer to `main_arena + 0x68` in both the `fd` and `bk` pointers.<sup>[[1]](#references)[[2]](#references)</sup>

Now it's allocated a new chunk `fake_libc_chunk(0x60)` because it'll contain the pointers to `main_arena + 0x68` in `fd` and `bk`.

Expand Down Expand Up @@ -67,7 +67,7 @@ Then, `main_arena + 0x68` is not that interesting, so let's modify it so the poi

Note that `__memalign_hook` usually starts with `0x7f` and zeros before it, then it's possible to fake it as a value in the `0x70` fast bin. Because the last 4 bits of the address are **random** there are `2^4=16` possibilities for the value to end pointing where we are interested. So a BF attack is performed here so the chunk ends like: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**

(For more info about the rest of the bytes check the explanation in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).<sup>[[2]](#references)</sup> If the brute force fails the program just crashes (restart until it works).
(For more info about the rest of the bytes check the explanation in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). If the brute force fails the program just crashes (restart until it works).<sup>[[1]](#references)</sup>

Then, 2 mallocs are performed to remove the 2 initial fast bin chunks and a third one is allocated to get a chunk in **`__malloc_hook`**.

Expand Down Expand Up @@ -111,24 +111,24 @@ In step one we controlled a chunk containing `__malloc_hook` (in the variable `m

Now, we abuse a partial overwrite in `malloc_hook_chunk` to use the libc address we wrote there (`main_arena + 0x68`) to **point to a `one_gadget` address**.

Here is where it's needed to **bruteforce 12 bits of randomness** (more info in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).<sup>[[2]](#references)</sup>
Here is where it's needed to **bruteforce 12 bits of randomness** (more info in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).<sup>[[1]](#references)</sup>

Finally, once the correct address is overwritten, **call `malloc` and trigger the `one_gadget`**.

## Modern tips & variants

- **Unsorted-bin hardening (2.28+):** The extra integrity checks on unsorted chunks (size sanity + list linkage) make the classic unsorted‑bin write fragile. To survive `_int_malloc`, you must keep `fd/bk` links consistent and sizes plausible, which usually requires stronger primitives than a simple partial overwrite.
- **Hook removal (2.34+):** With `__malloc_hook` gone, adapt the primitive to land on any writable GOT/global you can later reuse (e.g., overwrite `exit@GOT` in non-PIE binaries) or pivot to a **House of Pie** style top‑chunk hijack to control `top` instead of a hook.
- **Any‑address fastbin alloc (romanking98 writeup):** The second part shows repairing the 0x71 freelist and using the unsorted‑bin write to land a fastbin allocation over `__free_hook`, then placing `system("/bin/sh")` and triggering it via `free()` on libc‑2.24 (pre-hook removal).<sup>[[5]](#references)</sup>
- **Hook removal (2.34+):** With `__malloc_hook` gone, adapt the primitive to land on any writable GOT/global you can later reuse (e.g., overwrite `exit@GOT` in non-PIE binaries) or pivot to a **House of Pie** style top‑chunk hijack to control `top` instead of a hook.<sup>[[5]](#references)</sup>
- **Any‑address fastbin alloc (romanking98 writeup):** The second part shows repairing the 0x71 freelist and using the unsorted‑bin write to land a fastbin allocation over `__free_hook`, then placing `system("/bin/sh")` and triggering it via `free()` on libc‑2.24 (pre-hook removal).<sup>[[4]](#references)</sup>

## References

- [1] [shellphish/how2heap](https://github.com/shellphish/how2heap)
- [2] [how2heap - house_of_roman.c (glibc 2.23)](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
- [3] [CTF Wiki - House of Roman](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/)
- [4] [Heap tricks never get old - Insomni'hack Teaser 2022 (Synacktiv)](https://halloween.synacktiv.com/publications/heap-tricks-never-get-old-insomnihack-teaser-2022.html)
- [5] [House of Roman writeup (romanking98 gist)](https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc)
- [6] [glibc 2.34 NEWS](https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=NEWS;hb=glibc-2.34)
- [7] [glibc commit b90ddd0 - unsorted bin integrity checks](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)
- [1] [how2heap - house_of_roman.c (glibc 2.23)](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
- [2] [House of Roman - CTF Wiki EN](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/)
- [3] [Heap tricks never get old - Insomni'hack teaser 2022 (Synacktiv)](https://halloween.synacktiv.com/publications/heap-tricks-never-get-old-insomnihack-teaser-2022.html)
- [4] [House of Roman - leakless heap exploitation writeup (romanking98)](https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc)
- [5] [glibc NEWS file at glibc-2.34 (malloc_hook/free_hook removal)](https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=NEWS;hb=glibc-2.34)
- [6] [glibc commit fixing the House of Roman malloc_printerr/unsorted-bin abuse](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)
- [7] [shellphish/how2heap](https://github.com/shellphish/how2heap)

{{#include ../../banners/hacktricks-training.md}}
Loading