Skip to content

Mach Port-Oriented Programming (POP/PUSH)

XNU üzerinde, attacker-controlled (fake ya da dangling) ipc_port nesnelerinin chain'lenerek kernel'in kendi Mach IPC machinery'sini read, write ve control primitive'leri vermeye ikna ettiği bir code-reuse stili.

Mechanism

Suistimal edilen invariant

XNU'nun IPC subsystem'i, bir port taşıyan structure'da (bir ipc_port, bir out-of-line ports array'i, bir voucher'ın port field'ı) tutulan bir pointer'ın gerçekten gerçek, kernel-allocated bir port'a refer ettiğine güvenir. Mach message machinery'si, port right'larını yürümek, notification teslim etmek ve isimleri çevirmek için bu pointer'ları dereference eder. Bir attacker o pointer'lardan birini kontrol ettiği memory'ye refer ettirebildiğinde security boundary kırılır.

Bir fake ya da dangling ipc_port IPC katmanından ulaşılabilir hale geldiğinde, tehlikeli işi kernel'in kendisi yapar: sahte port'tan field'ları okur ve onlara göre davranır. Port-Oriented Programming (POP), böyle controlled port nesnelerini chain'leme disiplinidir — bir sahte port'la bir adres leak et, o adresle daha yetenekli ikinci bir port sahtele, vesaire — ta ki attacker kernel task port gibi davranan bir port tutana kadar. Hiçbir kernel control flow hijack edilmez; primitive'ler tamamen illegitimate nesnelere uygulanan meşru Mach operation'larından inşa edilir. Bu, POP'u IPC'ye karşı data-only bir teknik yapar.

Yapı taşları bir memory bug (../primitive/use-after-free.md ya da bir heap overflow'a bak) artı, attacker data'sını bir port pointer'ın düşeceği yere yerleştirmek için slab-grooming.md'dir.

Walkthrough

Yalnızca yetkili araştırma

Aşağıdaki adımlar, alıntılanan NDSS 2021 paper'ında ve Project Zero survey'inde tarif edildiği şekliyle POP'un public, kavramsal şeklidir. Tam zone isimleri, field layout'ları ve offset'ler XNU version'ına göre değişir ve kasıtlı olarak atlanmıştır.

1. Kontrol edilebilir bir port pointer elde et. ipc.ports zone'unda bir UAF ya da bir out-of-line ports array üzerinde bir heap overflow, içeriğini attacker'ın etkileyebileceği bir memory'ye yönelmiş bir port pointer bırakır.

Dangling pointer altına bir backing nesne spray'leme
// Conceptually: free a port, then reallocate its slot with
// attacker-shaped bytes (e.g. via IOSurface properties, pipe buffers,
// or OOL descriptors). The freed ipc_port slot now holds a fake port.
groom_zone(IPC_PORTS_ZONE);
trigger_uaf_on_port(victim);
spray_fake_port_bytes();   // reclaim the slot with controlled data

2. Bir kernel adresini disclose et. Fake port'a, kernel'in bir pointer'ı userspace'e geri kopyalamasına neden olan benign bir Mach call uygula (örneğin, bir notification isteyerek kernel'in bir port-owned array'e yazmasını, sonra onu geri okumasını sağla). Bu, sınırlı bir read'i bootstrap eder.

3. Escalate için port'ları chain'le. Leak edilen adresi kullanarak, message/right field'larını bir target structure'a yönelten ikinci bir fake port craft et ve sınırlı leak'i genel bir ../primitive/arbitrary-read-primitive.md'ye, ardından bir ../primitive/arbitrary-write-primitive.md'ye çevir.

4. Bir task-port eşdeğeri sahtele. Kernel'in kernel task port olarak ele aldığı bir port kur, kernel memory üzerinde tam mach_vm_read/write ver — klasik tfp0 sonucu.

Detection

  • ipc.ports / voucher zone'larında anormal churn: hemen ardından reclaim boyutlu spray'ler (IOSurface, pipe'lar, OOL descriptor'lar) gelen port allocation ve free patlamaları.
  • Userspace'in taze oluşturulmuş port'lara karşı çok sayıda mach_port_request_notification, mach_port_insert_right ya da voucher call yapması.
  • Telemetry açısından zengin build'lerde: backing adresi bilinen port zone'ların dışına düşen ya da generation/type field'ları tutarsız olan bir port — önerilen PUSH savunmasının doğruladığı tam sinyal.

Mitigation

Gerçek çözüm memory safety'dir

POP, bir memory-corruption primitive'inin bir sonucudur. Alttaki UAF/overflow'u ortadan kaldırmak tekniği tamamen kaldırır.

  • Zone isolation / type-segregated allocation (cross-cache-attack.md bağlamına bak): ipc_port nesnelerini dedike, type-stable zone'larda tutmak, freed bir port slot'unu yabancı data ile reclaim etmeyi çok daha zor kılar.
  • Pointer/structure validation (PUSH): alıntılanan paper, IPC katmanı bir port pointer'a göre davranmadan önce onun meşru bir port zone'da olduğunu ve field'larının kendi içinde tutarlı olduğunu kontrol etmeyi önerir.
  • Data pointer'lar üzerinde PAC, bir fake port'un dayandığı pointer'ları sahtelemenin çıtasını yükseltir (sınırlar için pac-signing-gadget-bypass.md'ye bak).

References