VirtualAlloc heap spraying¶
Büyük, page-aligned
VirtualAllocMEM_COMMITregion'ları kullanarak attacker-controlled veriyi bilinen/tahmin edilebilir bir adrese yerleştirmek (precise-allocation spray, örneğin tarihî0x0c0c0c0cpattern'i).
Mechanism¶
VirtualAlloc, belleği bir process heap üzerinden değil, doğrudan virtual-memory katmanında reserve ve commit eder. Büyük, bitişik, page-aligned region'lar döndürdüğü ve (Windows 8 öncesinde) onları tahmin edilebilir adreslere yerleştirdiği için precise heap spraying'in beygiri oldu: "flooding a process's heap with large, predictable patterns of data."
Note
Bir defender'ın kavraması gereken özellik: sıradan malloc/HeapAlloc yerleşimi allocator internals tarafından yönetilir ve nişan almak zordur, ama VirtualAlloc virtual-memory seviyesinde ince taneli kontrol ve büyük bitişik block'lar aracılığıyla tahmin edilebilir yerleşim verir. Yeterince bu tür region spray'le, ve seçilen bir adres — klasik olarak 32-bit'te tekrar eden 0x0c0c0c0c değeri — ezici olasılıkla attacker-controlled byte'ların içine düşer. Tekrarlanan word çifte görev görür: hem geçerli bir pointer'dır hem de bir instruction-stream NOP-equivalent'idir, böylece "spray'in herhangi bir yerine" düşen corrupted bir control-flow hedefi payload'a kayar. VirtualAlloc ayrıca executable bellek de (PAGE_EXECUTE_READWRITE) isteyebilir; bu tarihsel olarak spray'lenmiş byte'ların doğrudan çalıştırılmasına imkân vererek heap'in non-executable varsayılanlarını atlatıyordu.
Bu, vad-spraying'in user-mode address-prediction kardeşidir: spray'in güvenilirliği, herhangi bir allocator'ın free list'lerini groom'lamaktan değil, commit edilmiş aynı region'ların salt hacminin bir adresi istatistiksel olarak kesinlikle attacker-owned hale getirmesinden gelir.
Walkthrough¶
Üst düzey ve kavramsal, public heap-spray yazılarından:
- Payload birimini inşa et. Bir NOP sled (örneğin
0x90byte'ları ya da NOP-equivalent gibi davranan0x0c0c0c0cword'leri) ve ardından payload'dan oluşan bir region oluştur. -
Çok sayıda büyük region commit et. Tekrar tekrar büyük
MEM_COMMITblock'larıVirtualAlloc'la ve her birini payload birimiyle doldur: -
Hedef adresi geçerli kıl. Tahmin edilen bir adres (tarihsel olarak
0x0c0c0c0c) region'lardan birinin içine düşene kadar yeterince spray'le. - Bug'ı tetikle. Bir memory-corruption primitive'i, control flow'u ya da dereference edilen bir pointer'ı, artık attacker byte'larına çözülen tahmin edilen adrese yönlendirir.
Neden 0x0c0c0c0c
x86'da 0x0c byte'ı zararsız OR AL, imm8 olarak decode olur, böylece bir dizi 0x0c0c0c0c bir NOP sled gibi davranırken aynı anda 0x0c0c0c0c dword değeri kullanılabilir bir jump/read adresidir — klasik spray'in hem "nereyi gösteriyorum" hem de "oraya vardığımda ne çalışır" gereksinimlerini birlikte karşılayan tek bir sabit.
Detection¶
- API telemetry: olağandışı sayıda büyük
VirtualAlloc/NtAllocateVirtualMemorycommit'i yapan bir process, özelliklePAGE_EXECUTE_READWRITEile, güçlü bir spray göstergesidir; ETW ya da EDR üzerinden topla. - Content heuristics: tek bir tekrar eden pattern'i (NOP sled + payload) paylaşan çok sayıda committed region, committed private belleği tarayarak tespit edilebilir.
- Crash context: committed private bellekte yuvarlak, tekrar eden bir adreste (örneğin
0x0c0c0c0c) bir control-flow transferi ya da fault, oturmuş bir spray'in işaretidir.
Mitigation¶
- DEP/NX data page'lerden çalıştırmayı durdurur; attacker ayrıca executable bellek de elde etmedikçe execute-from-spray modelini bozar.
- Bottom-up/top-down ASLR (Windows 8+)
VirtualAlloc/MapViewOfFilebase'lerini randomize eder; 64-bit'te high-entropy ASLR bottom-up için "1 TB of variance … 24 bits of entropy" verir, böylece "systems today do not have enough memory available to spray the amount that would be needed." - CFG/XFG indirect call hedeflerini doğrular, böylece spray'de bir isabet bile geçersiz bir call hedefi olarak reddedilir.
- Uygulama seviyesinde nullpage/bilinen-adres reservation'ı ve RWX allocation'ları devre dışı bırakma (W^X policy), tekniğin dayandığı tahmin edilebilir, executable iniş bölgelerini ortadan kaldırır.