Skip to content

esp6 ESP transformation module exploit (CVE-2022-27666)

Linux kernel IPsec ESP transformation kodunda, local bir kullanıcının bitişik slab object'lerini overwrite edip root'a yükselmesine izin veren bir heap buffer overflow'u.

Mechanism

Kırılan invariant

IPsec ESP output path'inde (net/ipv6/esp6.c / net/ipv4/esp4.c içindeki esp6_output_head / esp_output_head), kernel skb_page_frag_refill ile bitişik çok-sayfalı (8-sayfalı) bir fragment buffer'ı allocate eder, ama attacker'ın etkilediği ESP verisinin boyutu o buffer'ı aşabilir. Sonraki crypto kopyası (örn. skb_to_sgvec memcpy) ardından bitişik kernel heap object'lerine out of bounds yazar. Kırılan invariant "allocation size ≥ kopyalanan byte"'tır; allocation hesabı hiçbir zaman page-fragment maksimumuna karşı sınırlandırılmadı (CWE-787). Etkilenen: Linux < 5.17; local bir kullanıcı buna ulaşabilir ve privilege escalation elde eder.

Kavramsal heap layout (boyutlar/adresler kernel'e göre değişir, ölçekli değildir):

  esp6_output_head: skb_page_frag_refill() ile alınan fragment buffer
  (page-fragment maks ile sınırlandırılmamış allocation)

  ┌──────────────────────────────┬───────────────────────────────┐
  │  ESP fragment buffer         │  bitişik victim slab object    │
  │  (allocation size)           │  (örn. user_key_payload /      │
  │                              │   msg_msg — length/size field) │
  └──────────────────────────────┴───────────────────────────────┘
        crypto kopyası (skb_to_sgvec / memcpy)
        ├───────────────────── kopyalanan byte ──────────────────►
                                 │ allocation < kopyalanan byte  ⇒
                                 └── OOB write bitişik object'e taşar

Walkthrough

Kamuya açık writeup'tan alınmış kavramsal tekrar.

  1. Bir ESP/IPsec transform'u (transport mode) sürebilen local bir kullanıcı olarak, output buffer kopyalanan veriden küçük olacak şekilde aşırı boyutlu bir mesaj hazırla ve OOB write'ı tetikle.
  2. Buddy allocator üzerinde page-level heap feng shui yaparak kontrol edilebilir bir victim object'i (örn. user_key_payload / msg_msg) vulnerable buffer'ın hemen ardına yerleştir.
  3. Overflow'u kullanarak bitişik object'in bir length/size field'ını boz ve onu bir out-of-bounds read primitive'ine çevir.
  4. Bitişik kernel verisini leak et (örn. arbitrary read via msg_msg ile pointer'lar) ve KASLR'ı kır.
  5. Bozulmuş metadata'yı bir arbitrary read/write primitive'ine yükselt (msg_msg next-pointer manipülasyonu, isteğe bağlı olarak bir race window kazanmak için FUSE ile bir kopyayı durdurarak).
  6. Arbitrary write'ı kullanarak modprobe_path gibi bir global'i overwrite et, sonra bir kernel-invoked usermode helper'ı tetikleyerek bir attacker binary'sini root olarak çalıştır (bkz. core-pattern / modprobe tarzı privesc).

Detection

  • esp6/esp4/xfrm module'lerinin beklenmedik yüklenmesi ya da non-root process'ler tarafından oluşturulan yeni IPsec/xfrm SA'ları (XFRM_* netlink'i, ip xfrm state değişikliklerini audit et).
  • /proc/sys/kernel/modprobe'a (modprobe_path) yapılan write'lara/değişikliklere ve alışılmadık modprobe-tetiklemeli binary'lerin çalıştırılmasına dair EDR/audit uyarıları.
  • esp6_output / skb_to_sgvec içinde slab/heap corruption, KASAN / BUG / oops, ya da beklenmedik GPF'ler gösteren kernel log'ları.
  • Unprivileged process'lerin FUSE açması/kullanması artı büyük System V message-queue (msgsnd) ya da add_key aktivitesi (klasik heap-grooming yapı taşları).
  • Yukarıdaki dizinin hemen ardından root shell'lerin spawn edilmesi / SUID değişiklikleri.

Mitigation

  • Düzeltilmiş bir kernel'a yamala: upstream commit ebe48d368e97d007bfeb76fcb065d6cfc4c96645 (kernel ≥ 5.17 / distro backport'ları).
  • Yamalama gecikirse, IPsec ESP'nin gerekmediği yerde esp6 ve esp4 module'lerini blacklist'le/unload et ve module autoloading'i kısıtla.
  • netlink/xfrm attack surface'ine kolay erişimi kesmek için unprivileged namespace oluşturmayı kısıtla (kernel.unprivileged_userns_clone=0).
  • CONFIG_SLAB_FREELIST_HARDENED, randomize edilmiş freelist'ler ve KASLR'ı etkinleştir.
  • modprobe_path / usermode-helper path'lerini izle ve kilitle; mevcutsa lockdown/IMA kullan.

References