House of Force¶
Top chunk (wilderness) size'ını devasa bir değerle ezerek hazırlanmış büyük bir request'in top pointer'ını arbitrary bir adrese taşımasını sağlamak.
Mechanism¶
House of Force, top chunk (wilderness) size'ını devasa bir değerle
(tipik olarak -1 → 0xffffffffffffffff) ezer ki malloc asla mmap'e geri düşmesin ve
sınırsız contiguous bellek var sansın. Hazırlanmış tek bir büyük request ardından top
pointer'ını arbitrary bir adrese ilerletir; sonraki normal malloc, attacker'ın target'ında
bir chunk döndürür ve arbitrary bir allocation/write verir.
Note
Köken: "The Malloc Maleficarum" (2005), Phantasmal Phantasmagoria. shellphish how2heap'te
gösterildi (örn. glibc_2.27/house_of_force.c). Çıkarma işlemi
unsigned long üzerindedir, dolayısıyla wrap-around top'un herhangi bir yere konumlandırılmasına izin verir.
Walkthrough¶
top->size = 0xffffffffffffffff'i ezdikten sonra şunu iste:
/* move av->top to land at `dest`; how2heap accounts for two chunk headers */
size_t evil_size = (size_t)dest - (size_t)old_top - 4*sizeof(long);
malloc(evil_size); // advances top to dest
char *ptr = malloc(small); // returns a chunk at dest
strcpy(ptr, payload); // arbitrary write at the target (e.g. a .bss var)
old_top'u bilmek ve evil_size'ı hesaplamak için bir heap leak gerekir.
Warning
Tam header terimi (2* mı yoksa 4*sizeof(long) mı) target'taki alignment/header'lara
bağlıdır; onu gözlemlenen top adresinden türet.
Mitigation¶
sysmalloc'taki bir top-chunk integrity assert'i ile glibc 2.29'da öldürüldü (commit 30a17d8c…):
assert ((old_top == initial_top (av) && old_size == 0) ||
((unsigned long) (old_size) >= MINSIZE &&
prev_inuse (old_top) &&
((unsigned long) old_end & (pagesize - 1)) == 0));
-1 olan forge edilmiş bir top->size bunu geçemez (old_end'de page-aligned değil, size saçma) ve
process'i abort eder. Teknik ayrıca hâlâ top->size'a overflow etme yeteneğini
gerektirir (bkz. top-chunk-extension, heap-buffer-overflow).