Skip to content

SockPuppet (CVE-2019-8605)

in6_pcbdetach()'in free edilmiş bir ip6_pktopts pointer'ını temizlememesinden kaynaklanan bir XNU socket-option use-after-free'i; app sandbox'ından erişilebilir ve kernel read/write'a çevrilebilir — iOS 12.4'ü jailbreak'lemek için kullanıldı.

Mechanism

Note

XNU networking stack'i, socket-başına IPv6 packet option'larını (struct ip6_pktopts) bir inpcb'ye inp->in6p_outputopts üzerinden bağlar. Kırılan invariant şudur: bir socket teardown edildiğinde, in6_pcbdetach() ip6_pktopts object'ini free eder ama field'ı null'lamaz, hâlâ erişilebilir bir inpcb içinde bir dangling pointer bırakır. Sonraki getsockopt() / setsockopt() çağrıları free edilmiş object üzerinde işlem yapar — hem stale object'in içine hem de ondan dereference edilen pointer'lar üzerinden sınırlı read ve write'lar gerçekleştirir. Bu, içeriğini bir attacker'ın free edilmiş slot'u reclaim ederek etkileyebileceği bir kernel heap object'inin use-after-free'idir.

Bug, sıradan socket syscall'ları üzerinden normal bir application sandbox'ından erişilebilir; bu da onu güçlü bir local kernel-LPE / jailbreak primitive'i yapar.

Walkthrough

High-level, Ned Williamson'ın Project Zero walkthrough'undan:

  1. Bir IPv6 socket oluştur ve packet option'ları kur, böylece in6p_outputopts bir ip6_pktopts allocation'ına işaret etsin.
  2. Detach path'ini tetikle, böylece in6p_outputopts hâlâ ona referans verirken ip6_pktopts free edilsin (dangling pointer).
  3. Free edilmiş allocation'ı aynı zone size'a sahip controlled bir object'le reclaim et (heap grooming / spray).
  4. Reclaim edilmiş bellek üzerinde read/write pencereleri olarak crafted getsockopt/setsockopt işlemlerini kullanarak sırasıyla şunları kur: bir arbitrary read, bir arbitrary kfree(), ve bir Mach-port adres disclosure'ı — tam bir kernel read/write'ı ve nihayetinde bir kernel task port'unu bootstrap ederek.

Warning

Apple'ın iOS 12.4 sürümü, zaten patch'lenmiş bug'ı kazara yeniden ortaya çıkardı ve public "SockPuppet" jailbreak'ini mümkün kıldı; 12.4.1'de tekrar fix'lendi. Ayrıntılı primitive inşası public writeup'ta yer alıyor ve burada yeniden verilmiyor — bu giriş kavramsaldır.

Detection

  • in6_pcbdetach, ip6_pktopts ya da IPv6 socket-option path'lerine atıf yapan iOS/macOS crash report'ları (panic log'ları); tekrarlı zone-corruption panic'leri.
  • Managed filolarda: vulnerable build'i (iOS 12.0–12.2 ve regress edilmiş 12.4) çalıştıran cihazlar MDM version politikasıyla işaretlenir.
  • Bir privilege anomalisinden önce heap-spray benzeri allocation pattern'leriyle yoğun IPv6 setsockopt/getsockopt dizileri veren anormal app'ler.
  • Primitive'in downstream'inde jailbreak göstergeleri (beklenmeyen tfp0/kernel-task-port erişimi, unsigned code execution).

Mitigation

  • Patch: iOS/macOS 12.3'te fix'lendi, 12.4'te regress etti, 12.4.1'de tekrar fix'lendi — cihazları tam güncel tut; MDM üzerinden minimum-OS zorla.
  • Yapısal fix, detach'te free edilmiş pointer'ı null'lar (clear-after-free); dangling-field UAF'ları için standart çözüm budur.
  • Apple'ın sonraki mitigation'ları (kalloc_type zone segregation, PAC, PPL), modern cihazlarda bu tür UAF'ları kernel R/W'a çevirmenin maliyetini artırır; bkz. puaf-primitive ve kernel-task-port.

References