CVE-2026-41651 — Escalada de Privilegios Local TOCTOU en PackageKit
Clasificación: Artefacto de Evaluación de Purple Team
Solo uso autorizado. Este documento y el script de prueba adjunto están destinados exclusivamente a la validación de seguridad interna en sistemas donde se haya obtenido autorización por escrito.
Prueba de Explotación

Índice
- Resumen de la Vulnerabilidad
- Análisis Técnico
- Descripción del Script de Prueba
- Indicadores de Compromiso
- Lógica de Detección
- Sistemas y Versiones Afectados
- Remediación
- Referencias
Resumen de la Vulnerabilidad
PackageKit es una capa de abstracción D-Bus para la gestión de paquetes del sistema, presente por defecto en escritorios basados en GNOME en Debian, Ubuntu, Fedora, RHEL, SUSE y Arch Linux. Debido a que media operaciones privilegiadas de paquetes en nombre de usuarios sin privilegios, una falla en su flujo de autorización tiene impacto de root a nivel de sistema.
Análisis Técnico
Causa Raíz
pk-transaction.c (anterior a 1.3.5) no aplicaba una protección de estado en la re-invocación de métodos de acción. Un cliente D-Bus podía llamar a InstallFiles (u otros métodos de acción) múltiples veces en el mismo objeto de transacción después de que ya había transitado fuera de PK_TRANSACTION_STATE_NEW.
Cadena de Ataque
Atacante (sin privilegios)
│
├─① CreateTransaction() → PackageKit devuelve la ruta del objeto de transacción (tid)
│
├─② InstallFiles(tid, FLAG_SIMULATE=4, [dummy.pkg])
│ PackageKit pone en cola una verificación de autorización polkit para dummy.pkg.
│ Aún no ocurre ninguna instalación — SIMULATE significa solo prueba en seco.
│
├─③ InstallFiles(tid, FLAG_NONE=0, [payload.pkg]) ← ventana TOCTOU
│ Re-invoca en el mismo tid antes de que se resuelva la autorización.
│ Las versiones vulnerables sobrescriben los parámetros en cola con payload.pkg.
│
└─④ polkit concede la autorización (usuario aprobó o auto-autorizado)
packagekitd instala payload.pkg como root.
script postinst/post de payload: install -m 4755 /bin/bash /tmp/.suid_bash
El atacante ejecuta /tmp/.suid_bash -p → shell root.
Por Qué Gana la Carrera
Los pasos ② y ③ se envían como llamadas D-Bus asíncronas no bloqueantes en la misma conexión y se vacían en una sola escritura. Los dos mensajes llegan a packagekitd antes de que pueda procesar ② y avanzar la máquina de estados, dejando abierta la ventana TOCTOU. La corrección en 1.3.5 añade una verificación de estado explícita que devuelve PK_TRANSACTION_ERROR_INVALID_STATE en cualquier re-invocación después de PK_TRANSACTION_STATE_NEW.
Descripción del Script de Prueba
Archivo: cve-2026-41651-purpleteam.py
Lenguaje: Python 3
Dependencias: python3-gi (introspección GObject / enlaces GLib/Gio)
Propósito
Demuestra la explotabilidad de CVE-2026-41651 en un sistema de prueba preparado con los siguientes fines:
- Validar si la versión instalada de PackageKit es vulnerable
- Generar telemetría IOC realista para el ajuste de SIEM/EDR
- Probar la cobertura de detección antes y después del parcheo
Comportamiento
Soporte para Entornos Endurecidos
Los sistemas endurecidos por defecto pueden bloquear la explotación en dos puntos independientes. El script maneja ambos automáticamente.
1. umask restrictivo (027 / 077)
Un umask heredado por el proceso de 027 o 077 hace que mkdir() produzca directorios 750 o 700. Tanto dpkg-deb como rpmbuild deben recorrer todo el árbol de compilación — si algún directorio no es legible, la compilación falla silenciosamente.
Corrección aplicada: os.umask(0o022) se llama al inicio antes de que se cree cualquier archivo o directorio. Además, cada directorio y archivo en el árbol de compilación recibe un chmod explícito inmediatamente después de su creación (0o755 para directorios y scripts, 0o644 para archivos de datos), de modo que los permisos correctos estén garantizados independientemente del umask heredado.
2. Banderas de montaje nosuid / noexec en /tmp
| Bandera | Efecto en la explotación |
|---|
nosuid | El kernel elimina silenciosamente el bit SUID de cualquier archivo almacenado en ese sistema de archivos — el bash copiado nunca se convierte en root |
noexec | El binario SUID no puede ejecutarse en absoluto |
Corrección aplicada: Al inicio, _find_suid_dir() lee /proc/mounts y prueba directorios candidatos en orden de preferencia hasta encontrar uno cuyo sistema de archivos no tenga ninguna de las dos banderas. La ruta resuelta se incorpora al script post-instalación del payload y se usa para el sondeo y la ejecución.
Si todos los candidatos están bloqueados, el script sale con un error claro en lugar de fallar silenciosamente.
Compatibilidad
| Familia de Distribuciones | Herramienta de Paquetes | Probado |
|---|
| Debian / Ubuntu | dpkg-deb | ✓ |
Indicadores de Compromiso
Los IOC se enumeran desde genéricos/nivel de infraestructura hasta artefactos específicos del script. Las detecciones basadas en los indicadores genéricos detectarán este CVE independientemente de qué variante de PoC se use.
Sistema de Archivos
Proceso y Ejecución
Actividad D-Bus
Patrones de Registro de Auditoría
Habilite con: auditctl -a always,exit -F arch=b64 -S all -F path=/usr/bin/packagekitd
O use las reglas siguientes en /etc/audit/rules.d/:
# Detectar creación de archivos SUID en todos los directorios de descarga candidatos
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/var/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/dev/shm -k suid_drop
# Detectar dpkg-deb / rpmbuild por no root
-w /usr/bin/dpkg-deb -p x -k pkg_build_nonroot
-w /usr/bin/rpmbuild -p x -k pkg_build_nonroot
# Detectar ejecución de bash SUID desde cualquier directorio de descarga candidato
-a always,exit -F arch=b64 -S execve -F dir=/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/var/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/dev/shm -F uid!=0 -F euid=0 -k priv_esc_drop
Artefactos del Gestor de Paquetes
Artefactos de Escalada de Privilegios
Lógica de Detección
Pseudo-Regla SIEM (Genérica — cubre todas las variantes de CVE-2026-41651)
(
event.category == "process"
AND process.name IN ("dpkg-deb", "rpmbuild")
AND process.user.id != "0"
AND NOT process.parent.name IN ("apt", "apt-get", "dpkg", "rpm", "dnf", "yum", "zypper", "mock", "koji")
)
OR
(
event.category == "file"
AND file.path LIKE "/tmp/%" OR file.path LIKE "/var/tmp/%" OR file.path LIKE "/dev/shm/%"
AND file.owner == "root"
AND (file.mode LIKE "04%")
)
OR
(
event.category == "process"
AND process.name == "bash"
AND process.real_user.id != "0"
AND process.effective_user.id == "0"
AND NOT process.parent.name IN ("sudo", "su", "sshd", "login", "pam")
)
Cadena de Comportamiento EDR
packagekitd
└─ sh / bash (cwd o argumento coincide con /tmp, /var/tmp, /dev/shm o $HOME)
└─ install / cp / chmod (objetivo tiene SUID + propietario root)
Marque la cadena completa. Cualquier paso individual por sí solo puede ser benigno; la relación padre-hijo a través de packagekitd hacia un comando que establece SUID es de alta fidelidad independientemente de qué directorio de descarga se haya seleccionado. Amplíe las reglas basadas en rutas para cubrir los cuatro candidatos.
Sistemas y Versiones Afectados
Verifique la versión instalada: pkcon backend-details o packagekit --version
Vulnerable si la versión reportada es ≤ 1.3.4.
Principal: Actualice PackageKit a 1.3.5 o aplique el backport específico del proveedor.
# Debian / Ubuntu
apt update && apt install --only-upgrade packagekit
# Fedora / RHEL
dnf upgrade packagekit
# SUSE
zypper update packagekit
Mitigaciones (si el parcheo no es posible de inmediato):
Referencias
Generado: 2026-04-24 | Actualizado: 2026-04-25 | Evaluación de Purple Team | Solo uso interno