CVE-2026-41651 — Escalatione dei Privilegi Locali TOCTOU in PackageKit
Classificazione: Artefatto di Valutazione Purple Team
Solo uso autorizzato. Questo documento e lo script di test allegato sono destinati esclusivamente alla validazione di sicurezza interna su sistemi per i quali è stata ottenuta autorizzazione scritta.
Prova di Sfruttamento

Indice
- Panoramica della Vulnerabilità
- Analisi Tecnica
- Descrizione dello Script di Test
- Indicatori di Compromissione
- Logica di Rilevamento
- Sistemi e Versioni Interessati
- Rimedio
- Riferimenti
Panoramica della Vulnerabilità
PackageKit è un livello di astrazione D-Bus per la gestione dei pacchetti di sistema, presente per impostazione predefinita sui desktop basati su GNOME in Debian, Ubuntu, Fedora, RHEL, SUSE e Arch Linux. Poiché media operazioni privilegiate sui pacchetti per conto di utenti non privilegiati, un difetto nel suo flusso di autorizzazione ha un impatto root a livello di sistema.
Analisi Tecnica
Causa Principale
pk-transaction.c (pre-1.3.5) non applicava un controllo di stato sulla re-invocazione dei metodi di azione. Un client D-Bus poteva chiamare InstallFiles (o altri metodi di azione) più volte sullo stesso oggetto transazione dopo che questo era già passato dallo stato PK_TRANSACTION_STATE_NEW.
Catena d'Attacco
Attaccante (non privilegiato)
│
├─① CreateTransaction() → PackageKit restituisce il percorso dell'oggetto transazione (tid)
│
├─② InstallFiles(tid, FLAG_SIMULATE=4, [dummy.pkg])
│ PackageKit accoda un controllo di autorizzazione polkit per dummy.pkg.
│ Nessuna installazione avviene ancora — SIMULATE significa solo prova a secco.
│
├─③ InstallFiles(tid, FLAG_NONE=0, [payload.pkg]) ← finestra TOCTOU
│ Re-invoca sullo stesso tid prima che l'autorizzazione venga risolta.
│ Le versioni vulnerabili sovrascrivono i parametri accodati con payload.pkg.
│
└─④ polkit concede l'autorizzazione (approvata dall'utente o auto-autorizzata)
packagekitd installa payload.pkg come root.
script postinst/post di payload: install -m 4755 /bin/bash /tmp/.suid_bash
L'attaccante esegue /tmp/.suid_bash -p → shell root.
Perché la Corsa Viene Vinta
I passi ② e ③ vengono inviati come chiamate D-Bus asincrone non bloccanti sulla stessa connessione e scaricati in un'unica scrittura. I due messaggi arrivano a packagekitd prima che possa elaborare ② e avanzare la macchina a stati, lasciando aperta la finestra TOCTOU. La correzione in 1.3.5 aggiunge un controllo di stato esplicito che restituisce PK_TRANSACTION_ERROR_INVALID_STATE su qualsiasi re-invocazione dopo PK_TRANSACTION_STATE_NEW.
Descrizione dello Script di Test
File: cve-2026-41651-purpleteam.py
Linguaggio: Python 3
Dipendenze: python3-gi (introspezione GObject / binding GLib/Gio)
Scopo
Dimostra la sfruttabilità di CVE-2026-41651 su un sistema di test predisposto per gli scopi di:
- Validare se la versione di PackageKit installata è vulnerabile
- Generare telemetria IOC realistica per la messa a punto di SIEM/EDR
- Testare la copertura di rilevamento prima e dopo l'applicazione della patch
Comportamento
Supporto Ambienti Hardened
I sistemi hardened per impostazione predefinita possono bloccare l'exploit in due punti indipendenti. Lo script gestisce entrambi automaticamente.
1. umask restrittivo (027 / 077)
Un umask ereditato dal processo di 027 o 077 fa sì che mkdir() produca directory 750 o 700. Sia dpkg-deb che rpmbuild devono attraversare l'intero albero di build — se una qualsiasi directory non è leggibile la build fallisce silenziosamente.
Correzione applicata: os.umask(0o022) viene chiamato all'avvio prima che venga creato qualsiasi file o directory. Inoltre, ogni directory e file nell'albero di build riceve un chmod esplicito immediatamente dopo la creazione (0o755 per directory e script, 0o644 per i file di dati), così i permessi corretti sono garantiti indipendentemente dall'umask ereditato.
2. Flag di mount nosuid / noexec su /tmp
| Flag | Effetto sull'exploit |
|---|
nosuid | Il kernel rimuove silenziosamente il bit SUID da qualsiasi file memorizzato su quel file system — la bash copiata non diventa mai root |
noexec | Il binario SUID non può essere eseguito affatto |
Correzione applicata: All'avvio, _find_suid_dir() legge /proc/mounts e testa le directory candidate in ordine di preferenza finché non trova un file system che non ha nessuno dei due flag impostati. Il percorso risolto viene quindi incorporato nello script post-install del payload e utilizzato per il polling e l'esecuzione.
Se tutte le candidate sono bloccate lo script esce con un errore chiaro piuttosto che fallire silenziosamente.
Compatibilità
| Famiglia di Distribuzioni | Strumento Pacchetti | Testato |
|---|
| Debian / Ubuntu | dpkg-deb | ✓ |
|
Indicatori di Compromissione
Gli IOC sono elencati dal livello generico/di infrastruttura fino agli artefatti specifici dello script. I rilevamenti basati sugli indicatori generici cattureranno questo CVE indipendentemente dalla variante PoC utilizzata.
File System
Processi ed Esecuzione
Attività D-Bus
Pattern dei Log di Audit
Abilita con: auditctl -a always,exit -F arch=b64 -S all -F path=/usr/bin/packagekitd
Oppure usa le regole seguenti in /etc/audit/rules.d/:
# Rileva la creazione di file SUID in tutte le directory di drop candidate
-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
# Rileva dpkg-deb / rpmbuild da parte di non-root
-w /usr/bin/dpkg-deb -p x -k pkg_build_nonroot
-w /usr/bin/rpmbuild -p x -k pkg_build_nonroot
# Rileva l'esecuzione di bash SUID da qualsiasi directory di drop candidate
-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
Artefatti del Gestore Pacchetti
Artefatti di Escalation dei Privilegi
Logica di Rilevamento
Pseudo-Regola SIEM (Generica — copre tutte le varianti di 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")
)
Catena Comportamentale EDR
packagekitd
└─ sh / bash (cwd o arg corrisponde a /tmp, /var/tmp, /dev/shm o $HOME)
└─ install / cp / chmod (target ha SUID + proprietario root)
Segnala l'intera catena. Ogni singolo passo da solo può essere benigno; la relazione genitore-figlio attraverso packagekitd fino a un comando che imposta SUID è ad alta fedeltà indipendentemente dalla directory di drop selezionata. Amplia le regole basate sul percorso per coprire tutte e quattro le candidate.
Sistemi e Versioni Interessati
Controlla la versione installata: pkcon backend-details o packagekit --version
Vulnerabile se la versione riportata è ≤ 1.3.4.
Rimedio
Primario: Aggiorna PackageKit alla 1.3.5 o applica il backport specifico del fornitore.
# Debian / Ubuntu
apt update && apt install --only-upgrade packagekit
# Fedora / RHEL
dnf upgrade packagekit
# SUSE
zypper update packagekit
Mitigazioni (se l'applicazione della patch non è immediatamente possibile):
Riferimenti
Generato: 2026-04-24 | Aggiornato: 2026-04-25 | Valutazione Purple Team | Solo uso interno