
Notes de rétro-ingénierie et PoC fonctionnel pour le bug de suivi de lien symbolique de macOS PackageKit (CVE-2026-28912), avec diff de désassemblage du correctif 26.6.
Rétro-ingénierie indépendante du bug de suivi de lien symbolique de macOS PackageKit (CVE-2026-28912), accompagnée d'un PoC fonctionnel qui démontre que l'installateur écrit un fichier contrôlé par l'attaquant en tant que root via un lien symbolique de répertoire dans le chemin de destination de l'installation.
Le bug est un parcours de chemin non synchronisé dans la logique de reliaison de fichiers de PKCoreShove. Un .pkg malveillant peut déclarer un chemin de destination dans un répertoire non privilégié, placer un lien symbolique de répertoire sur l'un des composants du chemin pointant vers un emplacement privilégié, et amener l'installateur — s'exécutant en tant que root — à écrire dans la cible du lien symbolique. Le correctif 26.6 d'Apple ajoute _PKSIPOpenPathSafely qui parcourt chaque composant du chemin avec O_NOFOLLOW et rejette tout lien symbolique.
| Champ | Valeur |
|---|---|
| CVE | CVE-2026-28912 |
| Composant | PackageKit (PKCoreShove, PKBundleComponent) |
| Affecté | macOS Tahoe 26.5 et antérieurs |
| Corrigé dans | macOS Tahoe 26.6 |
| Impact de l'avis | « Une app peut être en mesure d'obtenir les privilèges root. » |
| CVSS v3.1 | 7.8 (Élevé) |
| Signalé par | Découvreurs originaux selon l'avis d'Apple |
L'avis d'Apple pour CVE-2026-28912 documente l'impact et la version corrigée. Il ne documente pas le mécanisme technique :
Aucune analyse technique publique n'a été trouvée au moment de la rédaction. Ce dépôt comble cette lacune avec une analyse de rétro-ingénierie indépendante de PackageKit entre 26.4 et 26.6, et un PoC fonctionnel qui démontre la primitive en direct.
Il ne s'agit pas d'une revendication de découverte. Le CVE a été signalé par les découvreurs originaux et corrigé par Apple. La contribution ici est l'analyse technique et la reproduction.
PKCoreShove _relinkFile:dest: dans macOS 26.4 parcourt le chemin de destination composant par composant lors de la création d'un fichier :
; 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 retourne 0 (faux) lorsque le processus appelant ne peut pas modifier les fichiers SIP — le cas normal pour une installation initiée par l'utilisateur. Cela désactive RENAME_NOFOLLOW_ANY, donc le renommage suit tout lien symbolique dans le chemin de destination.
Le correctif 26.6 ajoute _PKSIPOpenPathSafely, appelé depuis PKBundleComponent initWithBundleAtPath:relativeToDestination::
; macOS 26.6, PackageKit
1aa6dfe18 bl _PKSIPOpenPathSafely ; walks each component with O_NOFOLLOW
_PKSIPOpenPathSafely :
Tout composant qui est un lien symbolique pointant en dehors du chemin prévu est rejeté avec EPERM ou ELOOP, et l'installation échoue.
Voir docs/ANALYSIS.md pour l'analyse complète et docs/ARTIFACTS.md pour les adresses et les échantillons de journaux.
link.sh — un PoC autonome en un seul fichier :
L'impact démontré est la primitive de suivi de lien symbolique — le comportement exact que le correctif 26.6 ferme.
Le PoC s'exécute entièrement sur la cible. Le lien symbolique et la charge utile sont tous deux créés localement. Cela garde le PoC autonome et reproductible sans aucune configuration réseau.
chmod +x link.sh
./link.sh
Réglage optionnel via des variables d'environnement :
sudo CONTENT="test content" ./link.sh
CONTENT définit le contenu écrit à travers le lien symbolique. Par défaut, il s'agit de 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
Sur un système corrigé (26.6), le même PoC échoue :
[✗] Not triggered
No file was created in /Users/nerd/cve-poc/real/
Voir docs/PATCH_DIFF.md pour la comparaison de désassemblage.
Deux détails du PoC ont été découverts lors du développement et sont documentés ici afin que d'autres construisant des outils similaires ne les rencontrent pas :