Skip to content

PAC signing-gadget bypass (data PAC bypass)

kernel read/write'a sahip bir attacker, pointer'ları imzalayan in-kernel kodu — bir "signing gadget" — yeniden kullanarak PAC key'lerini hiç recover etmeden geçerli PAC-signed pointer'lar forge eder.

Mechanism

İstismar edilen invariant

ARMv8.3 Pointer Authentication (../mitigation/arm-pointer-authentication.md), bir pointer'ın kullanılmayan high bit'lerinde keyed bir cryptographic MAC'i (PAC) saklar. PAC* instruction'ları imzalar, AUT* instruction'ları verify eder; key'ler yalnızca attacker'ın okuyamayacağı hardware register'larında yaşar. Tasarım, bir pointer'ı belleğe yazabilen bir attacker'ın AUT*'ı geçen bir değer üretemeyeceğini varsayar.

Attacker zaten kernel memory read/write'a sahip olduğunda o varsayım çöker. PAC integrity'yi korur, signing'i hangi kodun çalıştırdığının confidentiality'sini değil: kernel'in kendisi pointer'ları imzalayan kod dizileri içerir. Bir signing gadget, attacker'ın etkilediği bir pointer'ı alan, ona bir kernel key'iyle PAC* uygulayan ve sonucu attacker'ın okuyabileceği bir yere bırakan herhangi bir in-kernel dizidir. Böyle bir gadget'ı (bir kernel-call primitive üzerinden) sürerek attacker, doğru imzalanmış bir pointer'ı bedavaya elde eder. Project Zero ayrıca bir AUTIA+PACIZA çiftinin bir signing oracle gibi davranabildiğini gösterdi: bu dizide AUT* authentication başarısız olduğunda pointer sıfırlanmaz, bunun yerine extension bit'leri (implementation-defined biçimde) poison edilir; attacker bu deterministik dönüşümü gözlemleyerek gerçek signature'ı recover etmeye/brute-force etmeye çalışabilir. Key'ler yalnızca farklı CPU register'larında saklanır (APIAKey, APDAKey vb.); instruction dizisi aynı olduğu için, aynı gadget kodu farklı bir key register'ına başvuran farklı bir PAC* variant'ı (PACIA, PACDA, ...) çağrılarak farklı pointer tiplerini imzalamak üzere yeniden amaçlanabilir. Bu, data PAC bypass'tır: PAC, kernel memory'yi zaten kontrol eden bir adversary'ye karşı control flow'u savunamaz.

Walkthrough

Kavramsal — patch'lenmiş public research'e dayalı

Brandon Azad'ın Project Zero analizinden ve Black Hat USA 2020 konuşmasından. Spesifik gadget adresleri, register'lar ve bit pozisyonları atlanmıştır.

1. kernel R/W'den başla. Mevcut bir ../primitive/arbitrary-read-primitive.md ve ../primitive/arbitrary-write-primitive.md (örn. mach-port-oriented-programming.md'den) ile birlikte, controlled argüman'larla bir kernel fonksiyonu çağırmanın bir yolunu varsay.

2. Bir signing gadget bul. Kontrol ettiğin bir pointer'ı imzalayıp okunabilir şekilde saklayan in-kernel kodu bul — public örnek, sysctl_unregister_oid() içindeki AUTIA ardından PACIZA dizisidir.

Signing-oracle şekli (kavramsal)
supply unsigned pointer P  (no valid PAC)
AUTIA fails  -> P' = P with ONE pac bit flipped (not zeroed)
PACIZA signs -> read out signed(P')
flip the known bit back -> a pointer that passes AUT*  (no key needed)

3. İhtiyaç duyduğun pointer'ı forge et. Temiz şekilde authenticate olması için gadget/oracle'ı kullanarak arbitrary bir hedefi (örn. bir function pointer veya bir virtual-method pointer) imzala.

4. Korunan bir indirect branch'i hijack et. Forge edilmiş pointer'ı PAC-checked bir slot'a yaz ve kernel'in onun üzerinden branch etmesine izin ver; PAC'a rağmen attacker'ın seçtiği koda control flow elde et.

Detection

  • Yalnızca bir signing primitive olarak, çoğunlukla tight loop'larda kullanılan alışılmadık bir kernel routine'inin (örn. bir sctl/sysctl unregister path'i) tekrar tekrar invoke edilmesi.
  • Aynı gadget'ın değişen pointer argüman'larıyla birçok kez çalıştırıldığını ve sonuçların geri okunduğunu gösteren kernel-call telemetrisi — oracle pattern'i.
  • Bu aşama kernel R/W'yi öngerektirir; daha önceki memory-corruption sinyalleri (zone grooming, fake port'lar) daha aksiyon alınabilir detection'lardır.

Mitigation

PAC tek başına bir containment boundary değildir

Bir attacker kernel memory R/W'ye sahip olduğunda, signing-gadget reuse PAC'ın onları güvenilir şekilde durduramayacağı anlamına gelir. Savunmalar, o R/W'yi en baştan önlemeli ve gadget'ları kaldırmalı/çeşitlendirmelidir.

  • R/W bahşeden upstream memory-corruption bug'ını ortadan kaldır.
  • AUT* failure mode'unu hardening yap; böylece başarısız bir authentication kullanılamaz (kanonik olarak geçersiz) bir pointer üretir ve one-bit oracle kapanır.
  • Signing gadget'larını azalt: attacker'ın erişebildiği pointer'lar üzerinde PAC*-sonra-store dizilerinden kaçın; key'leri context başına çeşitlendir.
  • ../mitigation/arm-pacbti.md (PAC + Branch Target Identification) ve enhanced PAC gibi hardware/architectural follow-on'lar çıtayı yükseltir ama data PAC limitasyonunu geçersiz kılmaz.

References