Skip to content

Shadow (jemalloc heap exploitation framework)

argp & huku (CENSUS) tarafından yazılan, canlı jemalloc metadata'sını — arena'ları, run'ları, region'ları, bin'leri, tcache'leri — introspect ederek heap grooming'e ve exploit geliştirmeye yardımcı olan debugger plugin'i; unmask_jemalloc'un halefi.

Mechanism

Note

Shadow, kendisi bir memory-corruption primitive'i değildir — jemalloc primitive'lerini pratik kılan görünürlük araç setidir. jemalloc, kullanıcı data'sının yanına kasıtlı olarak neredeyse hiç in-line metadata koymaz (free edilmiş region'ların içinde yaşayan dlmalloc tarzı size/fd/bk word'leri yok), dolayısıyla bir attacker heap state'ini anlamak için sadece "chunk header'ı okuyamaz". Bunun yerine bookkeeping ayrı yapılarda yaşar: arena'lar (allocation havuzları), chunk'lar (büyük page-aligned span'ler), run'lar (tek bir size class'a ayrılmış sub-chunk page grupları), region'lar (bir run içindeki bireysel aynı boyutlu slot'lar), bin'ler (size-class başına run listeleri) ve tcache'ler (thread başına magazine'ler). Bir savunucunun burada önemsediği "invariant", bu harici metadata'nın hangi region'ların canlı ve hangilerinin free olduğunu doğru şekilde yansıtmasıdır.

Shadow, bu yapıları bir debugger'dan (gdb / lldb / pykd-WinDbg) dolaşır ve resmi yeniden kurar: hangi run size class N'i servis ediyor, hangi region'lar free, tcache stack'leri nereye işaret ediyor. Bu introspection, bir exploit yazarının bir victim object'i deterministik olarak bir overflow kaynağının yanına yerleştirmesini, hangi free()/malloc()'un bir region'ı recycle edeceğini tahmin etmesini ve bir groom'un işe yaradığını doğrulamasını sağlar — pahole/heap viewer'ların ptmalloc için yaptığı işin aynısı, ama jemalloc'un bölünmüş metadata'sı için.

Walkthrough

Yüksek seviye, herkese açık CENSUS materyalinden. Shadow bir debugger'a yüklenir ve hedef process için (Android libc, Firefox, FreeBSD libc veya standalone jemalloc) jemalloc'un runtime yapılarını parse eden komutlar sağlar:

  1. Soy. Shadow, argp & huku'nun Phrack 68:10 çalışmasındaki Firefox-dönemi jemalloc gezgini unmask_jemalloc'un yeniden tasarımıdır; modüler bir driver/engine ayrımıyla yeniden inşa edilmiştir, böylece aynı çekirdek mantık gdb, lldb ve pykd/WinDbg altında çalışır.

  2. Arena'ları ve bin'leri listele. Komutlar, arena dizisini ve her bin için mevcut run'ı ve onun run-header bitmap'ini dump eder; böylece analist size class başına free ve allocated region'ları görür.

  3. Run'ları ve region'ları incele. Bir run viewer, region size'ı, region count'u ve hangi slot'ların free olduğunu gösterir — N boyutundaki bir sonraki allocation'ın nereye ineceği hakkında akıl yürütmek için gereken data.

  4. Tcache'leri incele. Thread başına cache stack'leri dump edilir, böylece analist bir malloc'un thread magazine'den mi yoksa bir run'dan mı servis edileceğini bilir.

  5. Snapshot / diff / search. Heap snapshot'ları ve address-analysis komutları, analistin groom yapmasına, bir "öncesi" resmi almasına, app davranışını tetiklemesine ve amaçlanan adjacency veya recycling'in gerçekten gerçekleştiğini doğrulamasına olanak tanır.

Aşağıda, plugin'in public (CENSUS/shadow repo'sundaki) komut isimleriyle tipik bir inspection akışı ve bir size class için free/allocated region raporunun sanitize edilmiş, illustrative bir özeti gösteriliyor. Bu yalnızca allocator-state reporting'tir; hiçbir struct offset'i, gadget veya exploit adımı içermez. Komut isimleri repo dokümantasyonuna göre verilmiştir; çıktı formatı jemalloc sürüm/hedefe göre değişir, dolayısıyla aşağıdaki adresler/sayılar temsilîdir.

# debugger içinde (gdb / lldb / pykd-WinDbg), Shadow yüklü
(dbg) jeparse                 # belleğe karşı jemalloc yapılarını parse et
(dbg) jearenas                # arena'ları listele
(dbg) jebins                  # bin'leri (size-class başına run listeleri) listele
(dbg) jeregions 0x40          # 0x40 size class'ını host eden tüm run'ları dök
(dbg) jetcaches               # tüm tcache'leri dök
(dbg) jeinfo <addr>           # tek bir adres için tüm detayları göster

# 'jeregions 0x40' için temsilî, sanitize edilmiş çıktı:
#   size class 0x40 (64 bytes), regs per run = 64
#   run @ <run_addr>   total=64   free=2   allocated=62
#     region[00] <reg+0x000>  ALLOCATED
#     region[01] <reg+0x040>  ALLOCATED
#     region[02] <reg+0x080>  FREE
#     ...
#     region[40] <reg+0x...>  FREE
#     ...

Buradaki savunmacı okuma: rapor, harici metadata'nın (run-header bitmap'i) hangi region'ların canlı/free olduğunu doğru yansıtıp yansıtmadığını gösterir; bir groom'un beklenen adjacency'yi üretip üretmediği de buradan doğrulanır — yeni bir corruption primitive'i sağlamaz.

Bir groom'da kavramsal kullanım

Bir adjacent-region overflow'unu istismar etmek için (bkz. ../primitive/jemalloc-exploitation.md), bir attacker overflow kaynağı ile hassas bir victim object'in aynı run'da, komşu region'larda oturacağı şekilde groom yapar. Shadow tamamen layout'u doğrulamak için kullanılır: ilgili size class için run'ı, hangi region'ın kaynağı ve hangisinin victim'i tuttuğunu gösterir — olasılıksal bir spray'i deterministik bir yerleşime çevirir. Araçta hiçbir struct offset'i veya gadget zinciri yoktur; allocator state'ini raporlar.

Warning

Shadow hareketli bir hedefi izler. jemalloc internal'ları sürümler ve fork'lar arasında önemli ölçüde farklılık gösterir (Firefox'un mozjemalloc'u, Android'in bionic jemalloc'u, FreeBSD libc, upstream standalone). Framework sürüm/hedef-spesifik parser'lar taşır; desteklenmeyen bir jemalloc build'i için çıktı yanıltıcı olabilir.

Detection

Shadow analist tarafında bir araçtır, dolayısıyla tespit plugin'in kendisine değil mümkün kıldığı exploitation aktivitesine ve forensic ayak izine odaklanır:

  • Hassas process'lere debugger attach. Shadow gdb/lldb/WinDbg içinde çalışır. Endpoint'lerde, production'da asla debug edilmemesi gereken browser'lara veya diğer jemalloc-tabanlı hedeflere karşı ptrace/PTRACE_ATTACH, task_for_pid veya DebugActiveProcess üzerine alarm ver.
  • Allocator-anomalisi telemetrisi. Shadow'un yardımcı olduğu grooming, free'lerin takip ettiği olağandışı aynı-size-class allocation fırtınaları olarak görünür — allocation counter'ları veya sampling profiler'lar üzerinden gözlemlenebilen bir heap-spray imzası.
  • Crash imzaları. Başarısız jemalloc groom'ları/overflow'ları, corruption site'ında değil arena/run bookkeeping path'lerinde (region recycle, bitmap matematiği) crash olma eğilimindedir; tekrarlayan bu tür crash'ler bir göstergedir.
  • Hardened-build assert'leri. junk-fill / redzone'larla derlenmiş jemalloc (opt.junk, debug build'leri), attacker probing'i sırasında free edilmiş veya overflow'lanmış region'ların kullanımında fault verir.

Mitigation

  • jemalloc config'ini hardened yap. Mevcut olan yerlerde junk filling (opt.junk:true), redzone'lar ve page-seviyesi guard/quarantine seçeneklerini etkinleştir, böylece freed-region yeniden kullanımı ve adjacent-region overwrite'ları erken yakalanır.
  • jemalloc'u güncel tut. Daha yeni jemalloc ve mozjemalloc, deterministik grooming'i bozan metadata validation'ı ve randomization ekler.
  • Production'da debugger erişimini engelle. Yama ptrace_scope, get-task-allow eksikliği ve Windows debug-privilege kısıtlamaları, bir hedefin co-resident bir attacker tarafından canlı introspect edilmesini önler.
  • Besleyici bug class'ını ortadan kaldır. Shadow sadece yardımcı olur; asıl compromise bir jemalloc region'ına bir heap overflow, UAF veya double-free gerektirir — onları düzelt.

References