CVE-2026-41651 — Élévation de privilèges locale TOCTOU dans PackageKit
Classification : Artefact d'évaluation Purple Team
Usage autorisé uniquement. Ce document et le script de test qui l'accompagne sont destinés exclusivement à la validation de sécurité interne sur des systèmes pour lesquels une autorisation écrite a été obtenue.
Preuve d'exploitation

Table des matières
- Présentation de la vulnérabilité
- Analyse technique
- Description du script de test
- Indicateurs de compromission
- Logique de détection
- Systèmes et versions concernés
- Remédiation
- Références
Présentation de la vulnérabilité
PackageKit est une couche d'abstraction D-Bus pour la gestion de paquets système, présente par défaut sur les environnements de bureau GNOME sous Debian, Ubuntu, Fedora, RHEL, SUSE et Arch Linux. Comme il assure la médiation des opérations de paquets privilégiées au nom des utilisateurs non privilégiés, une faille dans son flux d'autorisation a un impact root à l'échelle du système.
Analyse technique
Cause racine
pk-transaction.c (avant 1.3.5) n'appliquait pas de garde d'état sur la ré-invocation des méthodes d'action. Un client D-Bus pouvait appeler InstallFiles (ou d'autres méthodes d'action) plusieurs fois sur le même objet de transaction après que celle-ci était déjà passée hors de l'état PK_TRANSACTION_STATE_NEW.
Chaîne d'attaque
Attaquant (non privilégié)
│
├─① CreateTransaction() → PackageKit renvoie le chemin de l'objet de transaction (tid)
│
├─② InstallFiles(tid, FLAG_SIMULATE=4, [dummy.pkg])
│ PackageKit met en file une vérification d'autorisation polkit pour dummy.pkg.
│ Aucune installation n'a lieu pour l'instant — SIMULATE signifie essai à blanc uniquement.
│
├─③ InstallFiles(tid, FLAG_NONE=0, [payload.pkg]) ← fenêtre TOCTOU
│ Ré-invoque sur le même tid avant la résolution de l'autorisation.
│ Les versions vulnérables écrasent les paramètres mis en file avec payload.pkg.
│
└─④ polkit accorde l'autorisation (approbation utilisateur ou autorisation automatique)
packagekitd installe payload.pkg en tant que root.
Script postinst/post de payload : install -m 4755 /bin/bash /tmp/.suid_bash
L'attaquant exécute /tmp/.suid_bash -p → shell root.
Pourquoi la course est gagnée
Les étapes ② et ③ sont envoyées comme appels D-Bus asynchrones non bloquants sur la même connexion et vidées dans une seule écriture. Les deux messages arrivent à packagekitd avant qu'il ne puisse traiter ② et faire avancer la machine à états, laissant la fenêtre TOCTOU ouverte. Le correctif dans 1.3.5 ajoute une vérification d'état explicite qui renvoie PK_TRANSACTION_ERROR_INVALID_STATE sur toute ré-invocation après PK_TRANSACTION_STATE_NEW.
Description du script de test
Fichier : cve-2026-41651-purpleteam.py
Langage : Python 3
Dépendances : python3-gi (introspection GObject / liaisons GLib/Gio)
Objectif
Démontre l'exploitabilité de CVE-2026-41651 sur un système de test préparé dans le but de :
- Valider si la version de PackageKit installée est vulnérable
- Générer une télémétrie IOC réaliste pour le réglage SIEM/EDR
- Tester la couverture de détection avant et après l'application du correctif
Comportement
Prise en charge des environnements durcis
Les systèmes durcis par défaut peuvent bloquer l'exploit à deux points indépendants. Le script gère les deux automatiquement.
1. umask restrictif (027 / 077)
Un umask hérité du processus de 027 ou 077 fait que mkdir() produit des répertoires 750 ou 700. dpkg-deb et rpmbuild doivent tous deux parcourir l'arborescence de construction complète — si un répertoire est illisible, la construction échoue silencieusement.
Correctif appliqué : os.umask(0o022) est appelé au démarrage avant la création de tout fichier ou répertoire. De plus, chaque répertoire et fichier de l'arborescence de construction reçoit un chmod explicite immédiatement après sa création (0o755 pour les répertoires et scripts, 0o644 pour les fichiers de données), garantissant ainsi les permissions correctes quel que soit l'umask hérité.
2. Indicateurs de montage nosuid / noexec sur /tmp
| Indicateur | Effet sur l'exploit |
|---|
nosuid | Le noyau supprime silencieusement le bit SUID de tout fichier stocké sur ce système de fichiers — le bash copié ne devient jamais root |
noexec | Le binaire SUID ne peut pas être exécuté du tout |
Correctif appliqué : Au démarrage, _find_suid_dir() lit /proc/mounts et teste les répertoires candidats par ordre de préférence jusqu'à ce qu'il en trouve un dont le système de fichiers n'a aucun des deux indicateurs. Le chemin résolu est ensuite intégré dans le script post-installation de la charge utile et utilisé pour l'interrogation et l'exécution.
Si tous les candidats sont bloqués, le script se termine avec une erreur claire plutôt que d'échouer silencieusement.
Compatibilité
| Famille de distributions | Outil de paquets | Testé |
|---|
| Debian / Ubuntu | dpkg-deb | ✓ |
|
Indicateurs de compromission
Les IOC sont listés du niveau générique/infrastructure jusqu'aux artefacts spécifiques au script. Les détections basées sur les indicateurs génériques détecteront cette CVE quel que soit le variant de PoC utilisé.
Système de fichiers
Processus et exécution
Activité D-Bus
Modèles de journaux d'audit
Activez avec : auditctl -a always,exit -F arch=b64 -S all -F path=/usr/bin/packagekitd
Ou utilisez les règles ci-dessous dans /etc/audit/rules.d/ :
# Détecter la création de fichiers SUID dans tous les répertoires de dépôt candidats
-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
# Détecter dpkg-deb / rpmbuild par un non-root
-w /usr/bin/dpkg-deb -p x -k pkg_build_nonroot
-w /usr/bin/rpmbuild -p x -k pkg_build_nonroot
# Détecter l'exécution de bash SUID depuis tout répertoire de dépôt candidat
-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
Artefacts du gestionnaire de paquets
Artefacts d'élévation de privilèges
Logique de détection
Pseudo-règle SIEM (Générique — couvre tous les 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")
)
Chaîne comportementale EDR
packagekitd
└─ sh / bash (cwd ou argument correspond à /tmp, /var/tmp, /dev/shm ou $HOME)
└─ install / cp / chmod (cible avec SUID + propriétaire root)
Signalez la chaîne complète. Chaque étape individuelle seule peut être bénigne ; la relation parent-enfant à travers packagekitd vers une commande définissant SUID est à haute fidélité quel que soit le répertoire de dépôt sélectionné. Élargissez les règles basées sur les chemins pour couvrir les quatre candidats.
Systèmes et versions concernés
Vérifiez la version installée : pkcon backend-details ou packagekit --version
Vulnérable si la version signalée est ≤ 1.3.4.
Principal : Mettez à niveau PackageKit vers 1.3.5 ou appliquez le rétroportage spécifique au fournisseur.
# Debian / Ubuntu
apt update && apt install --only-upgrade packagekit
# Fedora / RHEL
dnf upgrade packagekit
# SUSE
zypper update packagekit
Atténuations (si le correctif n'est pas immédiatement possible) :
Références
Généré : 2026-04-24 | Mis à jour : 2026-04-25 | Évaluation Purple Team | Usage interne uniquement