Full Report
In glibc 2.34, the hooks used for debugging malloc were completely removed from the run time configurations. Since these were commonly used for getting code execution, the author of the post wanted to find a new way to hijack the control flow. The man also runs the how2heap repo as well. The FILE data structure is used by programmers. Within glibc, there is a vtable added to the structure _IO_FILE_plus. In glibc 2.24, a restriction was added to the vtable pointers by ensuring that the pointers were within a very special section of libc called __libc_IO_vtables. Additionally, some pointers are encrypted (key stored in thread local storage) to prevent modification. A bypass for this was found though. First, the _IO_str_overflow pointers use tables outside of the vtable. So, the same attack could be used from before. Additionally, the vtable could be misaligned to invoke the wrong functions. Again, this was patched in 2.28 by removing the function pointers. So, where are we now? While manually auditing, the author found 81 unique function pointers within the special section. They checked all of them and their corresponding to calls to try to find any missing checks. Sadly, all of them are either validated via special vtables or encrypted. The encryption aspect is interesting - modifications can still be made IF we know the key. So, can we overwrite the key or leak the key stored in thread local storage? The goal is to use the misalignments to eventually do this. The file structure is very complicated. Instead of manually auditing, the author decided to use the symbolic execution tool angr. Since this is a bounded model checking problem, angr is the perfect tool for this. They configured Angr to run and let it go to town! The script found 10+ techniques - one of them which is known as the House of Emma. The tool had found a list of calls to the function tables, all which were validated, that would give control over RIP eventually. It turns out that a list of function pointers in _wide_vtable was not being validated by the vtable checker. Three of these techniques were known as the House of Apple. However, the others discovered were brand new. Overall, a good article with fun memes in it!
Analysis Summary
# Tool/Technique: angry-FSROP (Bypassing glibc vtable checks)
## Overview
This technique represents a modern approach to hijacking control flow (RIP/PC-control) in Linux systems running glibc 2.34 and above. Since the removal of `malloc_hooks`, attackers have shifted focus to the `_IO_FILE` (File Stream) structures. "angry-FSROP" refers to the use of the symbolic execution engine **angr** to automated the discovery of File Stream Return Oriented Programming (FSROP) chains that bypass the `_IO_vtable_check` security mechanism.
## Technical Details
- **Type:** Exploitation Technique / Research Tooling
- **Platform:** Linux (glibc 2.34, 2.35+)
- **Capabilities:** Bypasses glibc vtable validation; automates discovery of control-flow hijacking paths in complex C structures.
- **First Seen:** October 2022 (Research published by kylebot).
## MITRE ATT&CK Mapping
- **TA0008 - Lateral Movement / TA0004 - Privilege Escalation**
- **T1068 - Exploitation for Privilege Escalation:** Leveraging memory corruption to gain higher-level execution.
- **T1203 - Exploitation for Client Execution:** Using malformed file structures to trigger code execution.
## Functionality
### Core Capabilities
- **Vtable Misalignment:** Leveraging the fact that `_IO_vtable_check` only verifies if a pointer is within the `__libc_IO_vtables` section, but not if it is correctly aligned. This allows invoking unintended function pointers within the allowed memory range.
- **Automated Pathfinding:** Uses `angr` to perform bounded model checking on the 81 unique function pointers in the glibc vtable section to find paths to `call` or `jmp` instructions.
- **_wide_vtable Exploitation:** Identifies that while the primary `vtable` is checked, the `_wide_vtable` pointer within the `_IO_wide_data` structure was historically unvalidated, providing a direct path to RIP control.
### Advanced Features
- **Symbolic Execution Scripting:** A custom `angr` script capable of finding 10+ unique exploitation techniques (chains) by simulating different file operations (e.g., `fclose`, `fflush`, `overflow`).
- **Key Overwrite/Leak:** Provides a methodology to bypass pointer encryption (stored in TLS at `fs:0x30`) by using FSROP to leak or overwrite the secret key.
## Indicators of Compromise
- **Behavioral Indicators:**
- Crashing processes with `SIGABRT` triggered by `_IO_vtable_check` failure.
- Unexpected calls to `system()`, `execve()`, or `mprotect()` originating from within glibc file-handling functions (e.g., `_IO_file_finish`, `_IO_wfile_overflow`).
- Memory corruption or heap overflows targeting `FILE` structures or `_IO_list_all`.
## Associated Threat Actors
- Primarily utilized by security researchers and high-end exploit developers. The techniques (House of Apple, House of Emma) are frequently observed in advanced CTF (Capture The Flag) competitions and specialized exploit kits.
## Detection Methods
- **Behavioral Detection:** Monitor for illegitimate memory writes to the Thread Local Storage (TLS) area where glibc pointer encryption keys are stored.
- **Static Analysis:** Identify binary files that manually manipulate `_IO_FILE` structures or include statically linked, vulnerable versions of glibc.
- **Runtime Auditing:** Use tools like `auditd` or `eBPF` to detect unusual execution flows where code executes from the heap or unexpected areas of libc.
## Mitigation Strategies
- **Hardening Recommendations:**
- Update glibc to the latest version; developers are actively patching these gaps (e.g., adding checks to `_wide_vtable`).
- Enable **Control-flow Integrity (CFI)** mechanisms provided by compilers (like LLVM's CFI or Intel CET).
- **Prevention:** Use memory-safe languages or ensure rigorous validation of heap-allocated objects to prevent the initial memory corruption needed to forge a `FILE` structure.
## Related Tools/Techniques
- **angr:** The symbolic execution engine used for discovery.
- **House of Emma:** A technique requiring a key leak/overwrite to use encrypted pointers.
- **House of Apple (1, 2, 3):** Specific FSROP chains targeting `_wide_vtable`.
- **how2heap:** The repository maintaining these and other heap-related exploitation techniques.