Skip to content

Prefetch timing KASLR bypass

Unprivileged user code'dan prefetch instruction'ını kernel adresleri üzerinde zamanla: prefetch, address translation'ı bir privilege check olmadan yapar, dolayısıyla latency'si bir kernel adresinin map'li olup olmadığını sızdırır — KASLR offset'ini ve direct-physical map'i kurtarır (Gruss vd., CCS 2016).

Mechanism

Note

x86 software-prefetch instruction'ları (prefetcht0/t1/t2/nta) birer hint'tir: bir adres için page table'ları gezip cache'i ısıtırlar, ama normal bir load'un aksine fault vermez ve privilege zorlamazlar. Bu yüzden unprivileged bir process bir kernel virtual address üzerinde prefetch çalıştırıp ne kadar sürdüğünü gözlemleyebilir. Latency, translation'ın durumuna bağlıdır: gerçekten map'li bir kernel adresi (translation'ı cache'lenebilir / TLB'ye düşer), page-table walk'u erken ya da farklı sonlanan map'siz bir adrese göre ölçülebilir biçimde daha hızlı prefetch edilir. KASLR yalnızca sabit bir kernel layout'una randomize bir offset eklediği için, aday base adreslerini taramak ve "mapped" timing imzasına sahip olanı seçmek randomization sırrını doğrudan açığa çıkarır. Aynı oracle, tüm RAM'i sabit bir virtual region'da map'leyen kernel'in direct-physical map'i (physmap) üzerine uygulandığında virtual adresleri physical olanlara çözer; ret2dir tarzı SMAP bypass'larını mümkün kılan da budur.

Walkthrough

Temel ölçüm: serialize et, cycle counter'ı oku, hedefi prefetch et, counter'ı tekrar oku ve gürültüyü süzmek için birçok denemenin minimum'unu sakla.

static inline uint64_t time_prefetch(void *addr) {
    uint32_t lo0, hi0, lo1, hi1;
    /* rdtscp, TSC'yi EDX:EAX'a yazar; iki 32-bit half'i ayrı ayrı yakala,
       yoksa üst 32 bit kaybolur (rcx = processor-id, clobber). */
    asm volatile("mfence; lfence; rdtscp" : "=a"(lo0), "=d"(hi0) :: "rcx");
    asm volatile("lfence");
    __builtin_prefetch(addr, 0, 0);          /* prefetchnta */
    asm volatile("rdtscp" : "=a"(lo1), "=d"(hi1) :: "rcx");
    asm volatile("lfence");
    uint64_t t0 = ((uint64_t)hi0 << 32) | lo0;
    uint64_t t1 = ((uint64_t)hi1 << 32) | lo1;
    return t1 - t0;
}

Kernel base'ini bulmak için her KASLR-aligned adayı prob et ve minimum latency'yi al:

for (uint64_t base = KERNEL_LO; base < KERNEL_HI; base += KASLR_ALIGN) {
    uint64_t best = ~0ULL;
    for (int i = 0; i < ROUNDS; i++) {
        uint64_t t = time_prefetch((void *)base);
        if (t < best) best = t;
    }
    record(base, best);                      /* mapped base shows a distinct low band */
}
Timing dağılımı ne gösterir

Bu oracle üzerine iki saldırı kurulur:

  • Translation-level oracle — aday adres başına bir mapping'in var olup olmadığını ayırt eder, paging hiyerarşisini ve dolayısıyla user-space ve kernel-space ASLR'yi kurtarır.
  • Address-translation (physmap) recovery — hangi physmap adresinin aynı şekilde prefetch edildiğini bularak bir virtual adresi physical frame'ine çözer, ret2dir için 64-bit Linux'ta SMAP'i atlatır.

Sinyal, denemeler üzerindeki minimum'dur: tek bir örnek TLB/cache durumu ve interrupt'lar tarafından domine edilir, ama dağılımın tabanı "mapped" ile "unmapped" adayları ayırabilecek kadar kararlıdır. Makale ayrıca aynı primitive ile Windows 10 kernel ASLR'sini kırmayı da gösterdi ve saldırılar Amazon EC2 VM'leri içinde koştu.

Warning

Sonuçlar microarchitecture'a ve microcode'a bağlıdır. rdtsc granülaritesi, prefetch davranışı ve sonraki mitigation'lar (özellikle aynı yazarların önerdiği güçlü kernel isolation olan KPTI/KAISER) sinyali değiştirir ya da ortadan kaldırır. KPTI, kernel'in çoğunu user page table'larından unmap ederek saldırının dayandığı timing farkını çökertir — bu yüzden KPTI sistemlerinde bu spesifik oracle büyük ölçüde etkisizleşir ve onun yerine başka leak'ler (bkz. entrybleed-kpti-kaslr-bypass) gerekir.

Mitigation

  • KPTI / page-table isolation (KAISER) — kanonik düzeltme; kernel'i user address space'inden unmap etmek, kernel'in çoğu için prefetch timing farkını ortadan kaldırır.
  • Unprivileged code'a sunulan timer çözünürlüğünü düşürmek ölçüm eşiğini yükseltir ama tam bir savunma değildir.

References