
Notas de ingeniería inversa y un PoC funcional para el bug de seguimiento de enlaces simbólicos de macOS PackageKit (CVE-2026-28912), con diff de desensamblado del fix de 26.6.
Ingeniería inversa independiente del bug de seguimiento de enlaces simbólicos de macOS PackageKit (CVE-2026-28912), además de un PoC funcional que demuestra que el instalador escribe un archivo controlado por el atacante como root a través de un enlace simbólico de directorio en la ruta de destino de instalación.
El bug es un recorrido de ruta no sincronizado en la lógica de reenlace de archivos de PKCoreShove. Un .pkg malicioso puede declarar una ruta de destino en un directorio sin privilegios, colocar un enlace simbólico de directorio en uno de los componentes de la ruta apuntando a una ubicación privilegiada, y provocar que el instalador — ejecutándose como root — escriba en el objetivo del enlace simbólico. La corrección de Apple en 26.6 añade _PKSIPOpenPathSafely, que recorre cada componente de la ruta con O_NOFOLLOW y rechaza cualquier enlace simbólico.
| Campo | Valor |
|---|---|
| CVE | CVE-2026-28912 |
| Componente | PackageKit (PKCoreShove, PKBundleComponent) |
| Afecta a | macOS Tahoe 26.5 y anteriores |
| Parcheado en | macOS Tahoe 26.6 |
| Impacto del aviso | "Una app podría obtener privilegios de root." |
| CVSS v3.1 | 7.8 (Alto) |
| Reportado por | Descubridores originales según el aviso de Apple |
El aviso de Apple para CVE-2026-28912 documenta el impacto y la versión parcheada. No documenta el mecanismo técnico:
No se encontró ningún análisis técnico público en el momento de escribir esto. Este repositorio llena ese vacío con un análisis de ingeniería inversa independiente de PackageKit entre 26.4 y 26.6, y un PoC funcional que demuestra la primitiva en vivo.
Esto no es una reclamación de descubrimiento. El CVE fue reportado por los descubridores originales y parcheado por Apple. La contribución aquí es el análisis técnico y la reproducción.
PKCoreShove _relinkFile:dest: en macOS 26.4 recorre la ruta de destino componente por componente al crear un archivo:
; 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 devuelve 0 (falso) cuando el proceso llamador no puede modificar archivos SIP — el caso normal para una instalación iniciada por el usuario. Eso desactiva RENAME_NOFOLLOW_ANY, por lo que el rename sigue cualquier enlace simbólico en la ruta de destino.
La corrección de 26.6 añade _PKSIPOpenPathSafely, llamada desde PKBundleComponent initWithBundleAtPath:relativeToDestination::
; macOS 26.6, PackageKit
1aa6dfe18 bl _PKSIPOpenPathSafely ; walks each component with O_NOFOLLOW
_PKSIPOpenPathSafely:
Cualquier componente que sea un enlace simbólico apuntando fuera de la ruta prevista se rechaza con EPERM o ELOOP, y la instalación falla.
Consulta docs/ANALYSIS.md para el análisis completo y docs/ARTIFACTS.md para direcciones y muestras de logs.
link.sh — un PoC autocontenido de un solo archivo:
El impacto demostrado es la primitiva de seguimiento de enlaces simbólicos — el comportamiento exacto que la corrección de 26.6 cierra.
El PoC se ejecuta completamente en el objetivo. Tanto el enlace simbólico como el payload se crean localmente. Esto mantiene el PoC autocontenido y reproducible sin ninguna configuración de red.
chmod +x link.sh
./link.sh
Ajuste opcional mediante variables de entorno:
sudo CONTENT="test content" ./link.sh
CONTENT establece el contenido escrito a través del enlace simbólico. Por defecto es 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
En un sistema parcheado (26.6), el mismo PoC falla:
[✗] Not triggered
No file was created in /Users/nerd/cve-poc/real/
Consulta docs/PATCH_DIFF.md para la comparación de desensamblado.
Dos detalles del PoC se descubrieron durante el desarrollo y se documentan aquí para que otros que construyan herramientas similares no se topen con ellos: