Skip to content

PAC (arm64e Pointer Authentication)

Apple'ın arm64e platformunda Armv8.3 Pointer Authentication kullanımı: return address'ler ile function/data pointer'lar, bir pointer'ın kullanılmayan üst bitlerinde tutulan key'li kriptografik bir kodla (PAC) imzalanır ve kullanılmadan önce authenticate edilir — böylece bozulmuş bir pointer, control flow'u yönlendirmek yerine fault verir.

Mechanism

Kapsam farkı

Bu not özellikle Apple arm64e'nin sertleştirilmiş konuşlandırmasına odaklanır (per-boot key re-randomization, userspace/kernel ayrı key'leri, Project Zero iPhone XS analizi). Generic ARMv8.3-A mimarisi — QARMA cipher, ARMv8.6 FPAC fault-on-fail ve PACStack/PARTS/PACtight gibi akademik hardened şemalar — için bkz. Pointer Authentication (PAC).

Sınır neden tutuyor

64-bit bir virtual address, 64 bitin çok azını kullanır ve geriye boş üst bitler bırakır. PAC bunları, pointer değeri ile 64-bit bir context/modifier üzerinden hesaplanan key'li bir imzayla doldurur. Kullanılabilir bir pointer forge etmek için saldırganın doğru PAC'i üretmesi gerekir — secret key olmadan bu pratikte imkansızdır.

  • PAC* (örn. PACIA, PACDA) imzalar; AUT* (örn. AUTIA) authenticate eder ve PAC'i çıkarır; XPAC* kontrol etmeden çıkarır. Birleşik branch/return/load varyantları (BLRA*, RETA*, LDRA*) auth'u işlemin içine katar.
  • Beş adet 128-bit key: instruction key'leri APIAKey/APIBKey, data key'leri APDAKey/APDBKey ve generic APGAKey.
  • Authentication başarısız olunca hardware branch almaz — pointer'ın extension bitlerini poison eder, böylece bir sonraki dereference bir translation fault doğurur (saldırgan koduna atlama değil, bir crash).

Apple'ın arm64e'si referans tasarımı sertleştirir: key'ler her boot'ta yeniden randomize edilir (yani bir leak kalıcı olmaz), architectural register'ları paylaşmalarına rağmen userspace ve kernel ayrı key'ler kullanır ve farklı key'ler key-substitution'ı engellemek için ilişkisiz çıktılar üretir. Invariant şudur: yalnızca key'i elinde tutan kod, authenticate olan bir pointer üretebilir, dolayısıyla saldırgan adreslerini yerleştiren ROP / JOP, AUT*'ta takılır.

Walkthrough

Yüksek seviyeli; herkese açık Project Zero analizinden — çalışan bir forgery yok.

1. Pointer'lar tanımda imzalanır, kullanımda authenticate edilir. Bir return address prologue'da imzalanır, epilogue'da authenticate edilir:

foo:
    paciasp                 ; sign LR with APIAKey, context = SP
    ...                     ; (function body)
    autiasp                 ; authenticate LR; corrupted -> poisoned pointer
    ret                     ; ret to non-canonical addr -> translation fault

2. Forgery için key — ya da bir oracle — gerekir. Key secret ve her boot'a özel olduğundan, saldırgan bir PAC'i offline hesaplayamaz.

3. Bypass denemeleri cipher'ı değil, boru tesisatını hedef alır. Project Zero'nun iPhone XS çalışması gösterdi ki gerçekçi saldırılar signing gadget'lar (saldırganın etkilediği bir pointer'ı imzalayıp geri yazan kod, yani bir signing oracle) ve pointer reuse'dur (geçerli şekilde imzalanmış bir pointer'ın, farklı bir tanesinin beklendiği yere takılması; çünkü PAC yalnızca bir geçerli imzanın var olup olmadığını kontrol eder, hangi pointer olduğunu değil).

PAC neden yine de çıtayı yükseltiyor

Bypass edildiği yerlerde bile saldırganın bir signing gadget'a veya bir oracle'a ihtiyacı oldu — bunlar "software ile yamanması kolay" şeyler. Apple tam da bu tür düzeltmeleri (örn. bir AUTIA/PACIZA etkileşimini sıkılaştırma) kriptografik bir kırılma olmadan gönderdi.

Key'ler, oracle'lar ve reuse

PAC'in gücü key'in gizliliği ve context'in benzersizliğindedir. Eğer bir (pointer, PAC) çifti başka bir context'te reuse edilebiliyorsa veya kod, saldırgan verisini imzalayıp sonucu ifşa etmeye zorlanabiliyorsa, key bilinmeden control-flow integrity düşebilir. PACMAN gibi speculative saldırılar da AUT* kontrolünü bir guess-verification oracle'ına dönüştürebilir. Same-context pointer swap'ları bilinen bir zayıflıktır.

Detection

  • PAC authentication fault'ları. AUT*/RETA* üzerindeki crash'ler (poison'lanmış, non-canonical bir adrese atlama) control-flow tampering'in yüksek sinyalli kanıtıdır — bunları generic SIGSEGV değil, security event olarak ele alın.
  • Signing-gadget isabetleri. Pointer'ları imzalayıp depoladığı bilinen bir fonksiyonun, özellikle saldırganın etkilediği girdilerle, tekrar tekrar çağrılması oracle suistimaline işaret eder.
  • Speculative-probe desenleri (tahmin edilen pointer'ları tekrar tekrar authenticate eden sıkı loop'lar) PACMAN tarzı bir saldırıya işaret edebilir.
  • Beklenmedik key state değişiklikleri (örn. control register'lar üzerinden PAC'in devre dışı bırakılması) arm64e'yi zorunlu kılması gereken bir cihazda.

Mitigation

PAC'in kendisi zaten mitigation'dır; konuşlandırma ve sınırlar:

  • Branch protection ile derle. Return address'lerin imzalanması için -mbranch-protection=pac-ret (veya pac-ret+bti) ile compile edin; arm64e imzalamayı birçok data/function pointer'a genişletir.
  • Sıkı, benzersiz context'lerle imzala. Bir imzalanmış pointer'ın başka yerde reuse edilememesi için pointer sınıfı başına ayrı modifier'lar kullanın; saldırgan kontrolündeki verinin generic imzalanmasını asla açığa çıkarmayın.
  • Signing gadget / oracle'ları bulundukça yamayın — pratik attack surface cipher değil, software'dir.
  • Diğer savunmalarla birleştir: forward edge için BTI, memory safety için MTE ve OS seviyesi integrity (operating-system-integrity-os-integrity-protections).
  • Artık risk: signing oracle'lar, pointer reuse, authenticate edilmemiş pointer'lar ve speculative oracle'lar (PACMAN) hâlâ geçerlidir.

References