Glibc provides several “hardening” features designed to make heap exploitation more difficult. Understanding these measures is crucial for both defensive security and for testing whether exploitation techniques work in hardened environments.
Hardening measures add runtime checks and modify heap behavior to detect or prevent exploitation attempts. While they raise the bar for exploitation, many are not foolproof defenses.
Many how2heap techniques will be detected by MALLOC_CHECK_:
# Test if technique works with basic hardeningMALLOC_CHECK_=1 ./fastbin_dup# Strict checking - will abort on corruptionMALLOC_CHECK_=2 ./tcache_poisoning
MALLOC_CHECK_ adds overhead and is meant for debugging, not production use. Some sophisticated exploits can bypass these checks.
MALLOC_PERTURB_ causes malloc to initialize allocated memory and freed memory with specific byte patterns. This helps detect use-after-free and uninitialized memory bugs.
# Fill allocated memory with ~1 (0xFE), freed with 0x01export MALLOC_PERTURB_=1./your_program# Fill allocated memory with ~255 (0x00), freed with 0xFFMALLOC_PERTURB_=255 ./your_program
# Test if technique relies on memory contentsMALLOC_PERTURB_=170 ./house_of_lore# Test with different patternsMALLOC_PERTURB_=1 ./techniqueMALLOC_PERTURB_=255 ./technique
Many heap exploitation techniques still work with MALLOC_PERTURB_ because they manipulate metadata rather than data contents.
# Force all allocations to use mmapexport MALLOC_MMAP_THRESHOLD_=1./your_program# Disable mmap, use only heapMALLOC_MMAP_THRESHOLD_=0 ./your_program# Set custom threshold (1 MB)MALLOC_MMAP_THRESHOLD_=1048576 ./your_program
No heap chunks - Traditional heap techniques don’t apply
Different layout - Memory addresses non-contiguous
Different metadata - mmap chunks have different structure
Isolated allocations - Can’t overflow between chunks
When disabling mmap (threshold=0):
All heap allocated - Large allocations use heap
Heap exhaustion possible - Large allocations can exhaust heap
Different exploitation surface - Different techniques applicable
Example: Testing Technique Dependency on Heap vs mmap
# Normal behavior./overlapping_chunks# Works - chunks are on heap# Force mmapMALLOC_MMAP_THRESHOLD_=1 ./overlapping_chunks# May fail - chunks are mmap'd separately# See memory mappingMALLOC_MMAP_THRESHOLD_=1 ./program &cat /proc/$!/maps
# Test if technique requires heap allocationMALLOC_MMAP_THRESHOLD_=1 ./technique# Test mmap-specific techniquesMALLOC_MMAP_THRESHOLD_=0 ./mmap_overlapping_chunks
Some how2heap examples like mmap_overlapping_chunks specifically target mmap’d allocations.
#include <mcheck.h>#include <stdlib.h>int main() { // Must call before any malloc operations mcheck(NULL); // Use default abort function // Your code here char *ptr = malloc(100); free(ptr); return 0;}
Custom abort handler:
#include <mcheck.h>#include <stdlib.h>#include <stdio.h>void my_abort_handler(enum mcheck_status status) { const char *msg; switch(status) { case MCHECK_OK: msg = "No error detected"; break; case MCHECK_DISABLED: msg = "mcheck not enabled"; break; case MCHECK_HEAD: msg = "Memory before allocation corrupted"; break; case MCHECK_TAIL: msg = "Memory after allocation corrupted"; break; case MCHECK_FREE: msg = "Block already freed"; break; default: msg = "Unknown error"; } fprintf(stderr, "Heap corruption: %s\n", msg); abort();}int main() { mcheck(my_abort_handler); // Your code return 0;}
#include <malloc.h>#include <stdlib.h>#include <stdio.h>int main() { // Configure malloc before allocations // Always use heap, never mmap mallopt(M_MMAP_MAX, 0); // Disable heap trimming mallopt(M_TRIM_THRESHOLD, -1); // Set top padding mallopt(M_TOP_PAD, 0); // Now use malloc normally char *ptr1 = malloc(1000000); // Would normally use mmap printf("Allocated large chunk on heap\n"); free(ptr1); return 0;}
# Test with each hardening measureMALLOC_CHECK_=2 ./techniqueMALLOC_PERTURB_=255 ./techniqueMALLOC_MMAP_THRESHOLD_=1 ./technique# Combined testingMALLOC_CHECK_=2 MALLOC_PERTURB_=170 ./technique
Reason: Technique manipulates metadata in a way that violates consistency checks.Options:
Refine technique to maintain consistency
Find alternative primitive that doesn’t trigger checks
Exploit before checks are enabled
Disable checks (if you control environment)
Technique Works Despite Hardening
Reason: Technique exploits logic flaws rather than memory corruption, or corruption is subtle enough to bypass checks.Implication: Technique is more robust and likely to work in real-world scenarios.
Technique Fails with MALLOC_MMAP_THRESHOLD_
Reason: Technique relies on heap allocation but target is mmap’d.Solution: Adapt technique for mmap allocations (see mmap_overlapping_chunks).