
Note di reverse engineering e un PoC funzionante per il bug di PackageKit su macOS relativo al seguente dei symlink (CVE-2026-28912), con diff di disassemblaggio della correzione nella 26.6.
Reverse engineering indipendente del bug di macOS PackageKit relativo al seguito dei symlink (CVE-2026-28912), più un PoC funzionante che dimostra come l'installer scriva un file controllato dall'attaccante come root attraverso un symlink di directory nel percorso di destinazione dell'installazione.
Il bug è una path walk non sincronizzata nella logica di file-relink di PKCoreShove. Un .pkg malevolo può dichiarare un percorso di destinazione in una directory non privilegiata, posizionare un symlink di directory su uno dei componenti del percorso che punta a una posizione privilegiata, e far sì che l'installer — in esecuzione come root — scriva nel target del symlink. La fix di Apple nella 26.6 aggiunge _PKSIPOpenPathSafely che percorre ogni componente del percorso con O_NOFOLLOW e rifiuta qualsiasi symlink.
| Campo | Valore |
|---|---|
| CVE | CVE-2026-28912 |
| Componente | PackageKit (PKCoreShove, PKBundleComponent) |
| Affetto | macOS Tahoe 26.5 e precedenti |
| Corretto in | macOS Tahoe 26.6 |
| Impatto dell'advisory | "Un'app potrebbe essere in grado di ottenere privilegi di root." |
| CVSS v3.1 | 7.8 (High) |
| Segnalato da | Scopritori originali secondo l'advisory di Apple |
L'advisory di Apple per CVE-2026-28912 documenta l'impatto e la versione corretta. Non documenta il meccanismo tecnico:
Al momento della stesura non è stato trovato alcun writeup tecnico pubblico. Questo repository colma tale lacuna con un'analisi di reverse engineering indipendente di PackageKit tra la 26.4 e la 26.6, e un PoC funzionante che dimostra la primitiva dal vivo.
Questa non è una rivendicazione di scoperta. Il CVE è stato segnalato dagli scopritori originali e corretto da Apple. Il contributo qui è l'analisi tecnica e la riproduzione.
PKCoreShove _relinkFile:dest: in macOS 26.4 percorre il percorso di destinazione componente per componente quando crea un file:
; macOS 26.4, PackageKit
1a9fb14f8 _relinkFile:dest:
...
bl _linkResolutionProhibitted ; returns 0 in the normal case
mov w8, 0x10 ; RENAME_NOFOLLOW_ANY
cmp w0, 0
csel w22, w8, wzr, ne ; w22 = 0x10 if prohibited, else 0
...
mov x2, x22
bl _renamex_np ; uses w22 as flags
_linkResolutionProhibitted restituisce 0 (false) quando il processo chiamante non può modificare i file SIP — il caso normale per un'installazione avviata dall'utente. Questo disabilita RENAME_NOFOLLOW_ANY, quindi la rename segue qualsiasi symlink nel percorso di destinazione.
La fix della 26.6 aggiunge _PKSIPOpenPathSafely, chiamata da PKBundleComponent initWithBundleAtPath:relativeToDestination::
; macOS 26.6, PackageKit
1aa6dfe18 bl _PKSIPOpenPathSafely ; walks each component with O_NOFOLLOW
_PKSIPOpenPathSafely:
Qualsiasi componente che sia un symlink che punta al di fuori del percorso previsto viene rifiutato con EPERM o ELOOP, e l'installazione fallisce.
Vedi docs/ANALYSIS.md per il writeup completo e docs/ARTIFACTS.md per indirizzi e campioni di log.
link.sh — un PoC self-contained in un singolo file:
L'impatto dimostrato è la primitiva di symlink-following — esattamente il comportamento che la fix della 26.6 chiude.
Il PoC viene eseguito interamente sul target. Sia il symlink che il payload vengono creati localmente. Questo mantiene il PoC self-contained e riproducibile senza alcuna configurazione di rete.
chmod +x link.sh
./link.sh
Tuning opzionale tramite variabili d'ambiente:
sudo CONTENT="test content" ./link.sh
CONTENT imposta il contenuto scritto attraverso il symlink. Per default è hello.
[*] System information:
ProductName: macOS
ProductVersion: 26.4
BuildVersion: 25E246
[*] Setup...
Symlink: /Users/nerd/cve-poc/target → /Users/nerd/cve-poc/real
[*] Build .pkg...
Payload: /Users/nerd/cve-poc/payload/Users/nerd/cve-poc/target/poc.txt
Package: /Users/nerd/cve-poc/poc.pkg
[*] Install (password prompt expected)...
installer: Package name is poc
installer: Installing at base path /
installer: The install was successful.
[✓] VULNERABILITY CONFIRMED
Landed at /Users/nerd/cve-poc/real/poc.txt
Owner: root:wheel
Content: hello
CVE-2026-28912 trigger SUCCESSFUL
Su un sistema corretto (26.6), lo stesso PoC fallisce:
[✗] Not triggered
No file was created in /Users/nerd/cve-poc/real/
Vedi docs/PATCH_DIFF.md per il confronto del disassemblaggio.
Due dettagli nel PoC sono stati scoperti durante lo sviluppo e sono documentati qui affinché altri che costruiscono tooling simile non li incontrino: