Skip to content

House of Lore

Bir smallbin chunk'ının bk pointer'ını corrupt et ki malloc doubly-linked smallbin'i attacker belleğine doğru dolaşsın ve seçtiğin bir address'te fake bir chunk döndürsün.

Mechanism

Suistimal edilen invariant: smallbin servisi bk chain'ine güvenir

Small bin'ler exact-size, FIFO, doubly-linked list'lerdir. malloc bir smallbin'den bir request servis ettiğinde, list'in bk (backward) pointer'larını takip ederek tail'deki chunk'ı unlink eder; victim = last(bin) alır ve sonra bin->bk = victim->bk yapar. Eski glibc bu unlink'i hiç validation olmadan yapardı, dolayısıyla kuyruğa alınmış bir chunk'ın bk'sini overwrite etmek allocator'ın o pointer'ın işaret ettiği herhangi bir address'i geri vermesini sağlar — tipik olarak stack'te veya bir global'de fake bir chunk. Technique bir size field'ı değil, list-traversal güvenini suistimal eder.

Hardened glibc smallbin partial-unlink check'ini ekledi:

if (__glibc_unlikely (bck->fd != victim))
  malloc_printerr ("malloc(): smallbin double linked list corrupted");

burada bck = victim->bk. House of Lore bunu, fake target'ın fd'sini gerçek önceki node'a geri işaret ettirerek atlatır; böylece victim->bk->fd == victim geçerli olur ve check geçer.

Walkthrough

Referans: shellphish how2heap house_of_lore.c (glibc 2.23'ten 2.39'a kadar maintain ediliyor). Freed/bin'lenmiş bir chunk'ın bk'sini overwrite edebilen bir heap overflow ve fake chunk'lar için writable bir target bölge (stack/global) gerektirir.

  1. Target bellekte fake chunk chain'ini inşa et. İki fake chunk (örn. stack'te) yerleştir ve corruption-detection check'i allocator onlara ulaştığında geçecek şekilde önceden link'le:
stack_buffer_1[2] = victim_chunk;        /* fake_1->fd  = victim (passes check) */
stack_buffer_1[3] = stack_buffer_2;      /* fake_1->bk  = fake_2                */
stack_buffer_2[2] = stack_buffer_1;      /* fake_2->fd  = fake_1 (reciprocal)   */

Karşılıklı fd/bk link'leri her unlink adımında victim->bk->fd == victim'i sağlayan şeydir.

  1. Victim'i bir smallbin'e taşı.
  2. victim = malloc(0x100) ve bir referans tut.
  3. free(victim) → unsorted bin'e iner.
  4. malloc(1200) (daha büyük bir request) unsorted bin'in bir taranmasını zorlar ki bu victim'i exact-size smallbin'ine sort eder.

  5. Smallbin bk'sini corrupt et. victim->bk'yi stack_buffer_1'e (fake chain'in head'i) işaret edecek şekilde overwrite et:

victim[1] = (uintptr_t) stack_buffer_1;  /* victim->bk = fake_1 */
  1. Bin'i boşalt.
  2. malloc(0x100) gerçek victim'i döndürür ve list head'ini corrupt edilmiş bk boyunca fake chain'e ilerletir.
  3. malloc(0x100) tekrar artık fake chunk'ın içine (yani attacker'ın seçtiği stack belleğine) bir pointer döndürür.

??? example "Sonuç"

p = malloc(0x100);   /* p points into stack_buffer_2's user region */
/* writing through p overwrites a saved return address / local state */

!!! warning "Footgun: size ve link field'ları tutarlı olmalı" Fake chunk'lar boşaltılan smallbin'e uyan bir size sunmalı ve fd/bk karşılıklı link'leri geçerli olmalı, yoksa partial-unlink check malloc(): smallbin double linked list corrupted ile ateşlenir. Size class'ını yanlış yaparsan chunk adım 2'de beklenen bin'e hiç sort edilmez.

  1. Escalate et. malloc kontrollü belleğe bir pointer döndürürken, oraya bir payload yaz — klasik olarak control-flow hijack için saklı bir return address.

Detection

  • Herhangi bir heap arena'sının dışına (örn. stack'e) işaret eden bir smallbin bk anormaldir ve allocator instrumentation'ı tarafından yakalanabilir.
  • victim->bk->fd != victim tutarlılık invariant'ı, enforce edildiğinde, naif formu hem tespit eder hem bloklar.

Mitigation

  • glibc 2.32+'da eklenen smallbin partial-unlink check'i (malloc(): smallbin double linked list corrupted) attacker'ı fake target'ın fd'sini de kontrol etmeye zorlar; çıtayı yükseltir ama yeterli bellek kontrol edildiğinde technique'i kapatmaz.
  • Pointer-mangling / safe-linking (glibc 2.32+) smallbin fd/bk'yi kapsamaz (bunlar raw pointer'lardır), dolayısıyla primitive yeterli bir write verildiğinde güncel glibc'de geçerliliğini korur.

References