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
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_NAMEmesajları 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¶
- A survey of recent iOS kernel exploits — Project Zero — https://projectzero.google/2020/06/a-survey-of-recent-ios-kernel-exploits.html
- mach_portal source / writeup (Project Zero issue 965) — https://github.com/Jailbreaks/mach_portal
- Ian Beer (Project Zero), set_dp_control_port lack-of-locking UAF exploit — chains CVE-2016-7644 / CVE-2016-7637 / CVE-2016-7661 — https://www.exploit-db.com/exploits/40931