Skip to content

Heap spray

Heap'i kontrol edilen data/object'lerin birçok kopyasıyla doldurarak bir corruption primitive'inin güvenilir biçimde attacker byte'larına denk gelmesini sağlamak.

Mechanism

Heap spraying tek başına bir bug exploit etmez — "bir target process'in belleğinde önceden belirlenmiş bir konuma belirli bir byte dizisi koymaya çalışır" ve layout'un öngörülemezliğini telafi etmek için "büyük miktarda düzen ekler" ki bir corruption primitive'i güvenilir biçimde attacker-controlled byte'lara insin.

Note

Tarihsel olarak (browser/userland) sprey'lenen byte'lar hem NOP sled hem de shellcode görevi görürdü. Modern kernel exploitation, freed bir object'i reclaim etmek için slab allocator'ı sprey'ler: kmalloc() sırasında allocator yakın zamanda free'lenmiş belleği döndürür, dolayısıyla kontrollü içerikle aynı boyutta bir object allocate etmek, savunmasız freed object'in üzerine yazar.

Walkthrough

Userland/browser (tarihsel): sprey'ler "çoğunlukla JavaScript'te uygulanır ve büyük string'ler oluşturarak heap'i sprey'lerdi", bir değeri tekrar tekrar concatenate ederek. x86'da tekrarlanan 0x0c0c0c0c word'ü hem geçerli bir jump adresi hem de bir NOP eşdeğeri görevi görür, böylece sprey içinde herhangi bir yere inmek shellcode'a akar.

Kernel/slab (modern UAF reclaim): allocator boyuta göre bucket'ladığından ("33 ile 64 byte arasındaki herhangi bir allocation isteği … 64-byte bucket'tan karşılanır"), attacker freed bir slot'u reclaim etmek için kontrollü data içeren birçok aynı boyutlu object sprey'ler — örn. msgsnd(), setxattr veya sendmsg ancillary data üzerinden.

/* reclaim a just-freed kmalloc-64 object */
for (int i = 0; i < N; i++)
    msgsnd(qid[i], &ctrl, CTRL_SZ, 0);   /* ctrl payload overwrites the freed object */

Detection

KASAN, altta yatan UAF/OOB'yi raporlar; spraying'in kendisi sıradan allocation trafiğidir ve tek başına büyük ölçüde tespit edilemez. Slab-quarantine / KASAN delayed-free, spraying'in dayandığı zamanlamayı bozar.

Mitigation

Kernel slab quarantine (CONFIG_SLAB_QUARANTINE) freed allocation'ları tutar ki "anında yeniden allocate edilemesinler", isteğe bağlı olarak reclaim edilen belleği sıfırlar. Randomize / per-call-site kmalloc bucket'ları (kernel 6.6 her bucket'ı 16 yönde böler ve call site başına rastgele bir bucket seçer) ve özel kmem_buckets_create(), user tarafından kontrol edilebilen allocation'ları ayırır. Userland: ASLR/DEP, tarihsel NOP-sled'den-shellcode'a modelini yener.

References