Skip to content

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 -10xffffffffffffffff) 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).

References