Arbitrary call via UAF¶
Bir function pointer gömen bir kernel objesini free et, slot'unu attacker'ın kontrol ettiği data ile reclaim et, sonra indirect call'u tetikleyerek RIP kontrolü elde et.
Mechanism¶
Note
Bir function pointer (bir ops table pointer'ı ya da bir callback) içeren bir obje
üzerindeki use-after-free, attacker (1) bir dangling reference kalırken objeyi free
ettiğinde, (2) freed slot'u aynı kmalloc size'da kontrol edilen byte'larla reclaim
ettiğinde ve (3) corrupt edilen pointer üzerinden indirect/virtual call yapan code
path'ini sürdüğünde RIP kontrolüne dönüşür. Invariant, size eşlemesidir: reclaim objesi
free edilen obje ile aynı kmalloc cache'ine düşmeli ki function pointer'ı örtsün.
Walkthrough¶
Kanonik bir target, 0x400-byte'lık bir driver buffer'ı üzerindeki bir UAF ile ulaşılan
tty_struct'tır (kmalloc-1024):
int magic; /* off 0x00, must stay 0x5401 */
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops; /* off 0x18 <-- hijack target */
Akış: fd1'i aç (buffer'ı allocate eder), fd2'yi aç (aynı pointer'ı reallocate eder),
fd2 dangle ederken free etmek için close(fd1). Slot'u, ops'u kontrol edilen bir
tty_operations table'ına işaret eden sahte bir tty_struct ile reclaim et; sonra tty
üzerinde ioctl() çağırarak 12 * sizeof(uint64_t) slot'undaki function pointer'ı kontrol
edilen cmd/arg ile fire et.
SMEP/SMAP sahte table'ı ve ROP chain'i kernel memory'sinde yaşamaya zorladığı için,
önce tty_struct->ops'u (sabit bir offset'te .rodata'ya işaret eder) leak ederek kernel
base'i kurtar ve spray'lenen chain'in nerede oturduğunu öğrenmek için bir msg_msg
heap-address leak'i kullan. Sonra ops->ioctl'i bir stack-pivot gadget'ı olarak sahtele:
Warning
Corrupt edilen objenin close/shutdown/cleanup pointer'larını bir ret gadget'ına
ayarla; aksi halde obje teardown garbage'ı dereference eder ve kernel'i panic'ler (ve
saldırının sinyalini verir).
Detection¶
Gereken leak + spray + indirect-call dizisi (örn. tty allocation, msg_msg address
leak'leri, olağandışı bir ioctl cmd'i) tespit edilebilir; düzgün ret stub'ları olmadan
teardown'dan gelen bir panic, gürültülü bir sinyaldir.
Mitigation¶
- SMEP, userspace shellcode'a bir jump yerine ROP'u zorlar; SMAP kernel'in
userspace'i dereference etmesini engeller, dolayısıyla sahte
opstable'ı ve chain kernel memory'sinde olmalıdır. - KASLR, herhangi bir gadget adresi kullanılabilir olmadan önce
opsleak'ini zorlar. - CFI (forward-edge control-flow integrity), uyumsuz target'lara yapılan indirect call'ları reddederek hijack edilen call'u kırar. Slab freelist randomization ve hardened freelist pointer'ları reclaim güvenilirliğini düşürür.