Skip to content

mach_portal (CVE-2016-7644)

Ian Beer'in iOS 10 exploit chain'i: bir Mach port'unda (set_dp_control_port) bir missing-lock use-after-free, port-name ve notification bug'larıyla birleşip kernel task port'unu (tfp0) ele geçirir.

Mechanism

Suistimal edilen invariant

XNU, Mach port'larını reference-count'lar ve her port reference düşüşünün serialize edildiğini, böylece nesnenin tam olarak bir kez, son right kaybolduğunda free edildiğini varsayar. set_dp_control_port(), bir reference'ı gerekli lock'u tutmadan release etti, dolayısıyla bir race bir port'u over-release edebildi — dangling bir receive/send right hâlâ slot'a işaret ederken onu free etti.

O tek race security-boundary kırılmasıdır: memory'sini attacker'ın reclaim edebileceği freed bir ipc_port, güvenilen IPC katmanı içinde controlled bir nesne haline gelir (mach-port-oriented-programming.md'nin ../primitive/use-after-free.md → fake-port pattern'i). mach_portal bunu iki üst düzey IPC trust bug'ıyla eşler — freed bir port name'inin bir system service'in port'unu değiştirmek için yeniden kullanılmasına izin veren pegged user-reference count'ları (CVE-2016-7637) ve bir root daemon'u task port'unu attacker-controlled bir endpoint'e yeniden göndermeye kandıran spoofable dead-name notification'ları (CVE-2016-7661). Chain'lendiğinde, unprivileged bir app'ten tam kernel memory access'e yürürler.

Walkthrough

Tarihsel, patch'lenmiş (iOS 10.1 dönemi) — yalnızca inceleme

Public Project Zero issue'sundan ve survey'inden kavramsal akış. Zone layout'u ve tam race'ler version'a özgüdür ve atlanmıştır.

1. Over-release'i race et. Çok sayıda port allocate et; bir alt küme üzerinde unlocked release'i tetikle, böylece bir right hâlâ ona referans verirken her biri free edilir.

Race'in şekli
allocate N ports
for ~20 victims: race set_dp_control_port  -> port over-released
force zone GC                              -> freed slots returned
reclaim slots with an out-of-line ports array (controlled bytes)

2. Kernel task port adresini disclose et. Reclaim edilen OOL ports array'i dangling port'ların üstünde oturur; onu geri okumak pointer'ları (host port dahil) leak eder ve attacker'ın kernel task port'unun nerede yaşadığını tahmin etmesine izin verir — ilgili region için ../mitigation/kernel-address-space-layout-randomization.md'nin yenilmesi.

3. Kernel task port'una bir send right sahtele. Dangling bir port'un context'ini tahmin edilen kernel-task-port adresine yönelt ve gerçek kernel task port'una bir send right geri veren bir OOL port al.

4. Persistence/privilege için service hijack. CVE-2016-7637 kullanarak, freed bir port name'i launchd'de iohideventsystem'i değiştirmek için yeniden kullan; CVE-2016-7661 sonra yeniden başlatılan powerd'yi (root) attacker port'una yeniden bağlanmaya ve task port'unu göndermeye iter. Sonuç tfp0 — arbitrary kernel read/write — ve bir root task port'udur.

Detection

  • Zone garbage collection ve büyük bir out-of-line ports message ardından gelen port allocation/free patlamaları — reclaim imzası.
  • İyi bilinen service port'larının beklenmedik churn'ü (örn. bir launchd service name'inin yeniden yönelmesi) ya da daemon'ların (powerd) crash olup yeniden başlaması.
  • Userspace'in root process'lere crafted MACH_NOTIFY_DEAD_NAME mesajları göndermesi.

Mitigation

Apple tarafından fix'lendi

iOS 10.1 / macOS 10.12.1 zaman diliminde patch'lendi: port reference drop etrafında doğru locking, düzeltilmiş user-reference accounting ve spoofed dead-name notification'larının reddi.

  • Tüm port reference değişikliklerini port lock altında serialize et (root fix).
  • IPC trust'ı hardened et: notification sender'larını doğrula ve gerçek uref limit'lerini zorla.
  • Type-stable, isolated port zone'ları ve pointer authentication (../mitigation/arm-pointer-authentication.md), sonraki donanımda port nesnelerini reclaim etmenin ve sahtelemenin maliyetini artırır.

References