Skip to content

musl mallocng exploitation

Overlapping allocation'lar ve arbitrary read/write primitive elde etmek için musl'un mallocng group/meta yapılarını corrupt etmek ya da sabit-stride slab'larında object overlap'ini suistimal etmek.

Mechanism

musl libc eski oldmalloc'unu mallocng ile değiştirdi (mevcut varsayılan). mallocng belleği group'lara (yalnızca mmap() ile elde edilen multi-page slab'lar — asla brk() kullanmaz) böler; her biri sabit boyutlu slot'lara (stride'lar) bölünür. MMAP_THRESHOLD altı request'ler ~48 sizeclass'tan birine düşer; aşırı büyük request'ler sizeclass 63'ü tek-slotlu bir group olarak kullanır. Kritik olarak, neredeyse tüm bookkeeping out-of-band'dir: her group, özel bir metadata alanından allocate edilen bir struct meta ile tanımlanır; yalnızca birkaç byte'lık in-band header (IB = 4) user data'dan hemen önce durur.

Note

Korunan invariant şudur: get_meta() herhangi bir user pointer'dan trusted bir struct meta kurtarabilir ve in-band header, slot'un index'ini ve group base'e geri olan offset'ini tutarlı şekilde encode eder. meta.h'den:

struct group {
    struct meta *meta;
    unsigned char active_idx:5;
    char pad[UNIT - sizeof(struct meta *) - 1];
    unsigned char storage[];
};
struct meta {
    struct meta *prev, *next;
    struct group *mem;
    volatile int avail_mask, freed_mask;
    uintptr_t last_idx:5;
    uintptr_t freeable:1;
    uintptr_t sizeclass:6;
    uintptr_t maplen:8*sizeof(uintptr_t)-12;
};

get_meta(), group base'i ve slot index'ini yeniden inşa etmek için user pointer'ın -2, -3, -4 offset'lerindeki header byte'larını okur, ardından process başına bir secret cookie'yi (area->check == ctx.secret), sizeclass'ı ve slot index'inin [0, last_idx] içinde olduğunu doğrular. mallocng ayrıca bir offset-cycling mitigation'ı uygular: bir slot içindeki user-data offset'i her reuse'da artırılır (slack'i aştığında wrap eder), bu da sabit adresleri karıştırır ve naif double-free'yi etkisiz bırakır.

Walkthrough

Metadata kontrolleri (secret cookie, sizeclass, index, alignment) güçlü olduğu için, gerçek dünya mallocng exploit'leri genellikle meta'yı doğrudan corrupt etmekten kaçınır ve bunun yerine sabit-stride slab'larda overlapping slot / type confusion mühendisliği yapar. Alpine'ın musl'ı üzerindeki CVE-2022-24834'ün NCC Group / Fox-IT write-up'ı (Redis'in cjson encoding'inde, küçük boyutlu bir buffer ve kontrollü ~0x15555555-byte'lık bir overflow üreten bir integer overflow) kanonik çalışmadır:

  • Bir Table Lua object'i 0x48 byte'tır ve 0x50-stride bir slot'a düşer. Overflow, bir TValue pointer'ının LSB'sini 0x22 ile (overflow'u sonlandıran ") corrupt eder ve onu fake bir Table tutan bitişik bir slot'a yönlendirir.
  • Fake Table, kontrolsüz alanları (next, tt, marked) komşu TString byte'larından miras alır ama saldırganın Table->array ve Table->sizearray'i kontrol etmesine izin verir; zincirlenmiş fake table'lar üzerinden neredeyse arbitrary bir read/write verir.

Warning

mallocng'de heap feng shui, ptmalloc2'den keskin biçimde farklıdır. Bir group'u free etmek onu munmap'ler, coalesce edilebilir bir free chunk yerine unmapped bir delik bırakır. Güvenilir exploitation bu yüzden munmap boşlukları oluşturmadan bitişik group mapping'leri groom'lamayı gerektirir, böylece overlapping victim mapped ve tahmin edilebilir bir göreli offset'te kalır.

Canlı mallocng state'inin incelenmesi en iyi şekilde, slot'ları, group'ları ve meta'ları decode eden muslheap GDB plugin'i ile yapılır:

gef> mfind <addr>        # locate the slot/group/meta for an address
gef> mslot <addr>        # show INDEX / RESERVED / OVERFLOW / OFFSET_16 for a slot
gef> mheap               # dump global mallocng context, active groups and free masks

Detection

  • ASan/MSan ya da debug bir musl build'i, overlap'ten önce gelen out-of-bounds write'ı yakalar.
  • muslheap/manuel kontroller, in-band header'ı meta->check'i artık process secret'ına eşit olmayan bir group'a decode olan ya da sizeclass/index'i aralık dışı olan bir slot'u işaretler.

Mitigation

  • mallocng'nin secret cookie'sini, sizeclass/index doğrulamasını ve offset cycling'ini bozulmadan tut (bunları patch'le devre dışı bırakma); saldırganları dolaylı object-overlap stratejilerine iten şey bunlardır.
  • Kök neden olan memory-safety bug'ını düzelt (overlap'i besleyen integer overflow / OOB write).
  • Metadata group mapping'lerinin önüne konan guard page'ler, out-of-band meta dizilerini lineer in-band overflow'lardan zaten izole eder; bunları koru.

References