AuthZ& AuthN - Docker Access Authorization Plugin
Il modello di autorizzazione predefinito di Docker è tutto o niente. Qualsiasi utente con il permesso di accedere al demone Docker può eseguire qualsiasi comando del client Docker. Lo stesso vale per i chiamanti che utilizzano l'API di Engine di Docker per contattare il demone. Se hai bisogno di un maggiore controllo degli accessi, puoi creare plugin di autorizzazione e aggiungerli alla configurazione del demone Docker. Utilizzando un plugin di autorizzazione, un amministratore di Docker può configurare politiche di accesso granulari per gestire l'accesso al demone Docker.
Architettura di base
I plugin di autenticazione di Docker sono plugin esterni che puoi utilizzare per consentire/negare azioni richieste al demone Docker in base all'utente che lo ha richiesto e all'azione richiesta.
Le seguenti informazioni provengono dalla documentazione
Quando viene effettuata una richiesta HTTP al demone Docker tramite CLI o tramite l'API di Engine, il sottosistema di autenticazione invia la richiesta al/i plugin di autenticazione installato/i. La richiesta contiene l'utente (chiamante) e il contesto del comando. Il plugin è responsabile di decidere se autorizzare o negare la richiesta.
I diagrammi di sequenza di seguito rappresentano un flusso di autorizzazione consentito e un flusso di autorizzazione negato:
Ogni richiesta inviata al plugin include l'utente autenticato, gli header HTTP e il corpo della richiesta/risposta. Solo il nome utente e il metodo di autenticazione utilizzato vengono passati al plugin. In particolare, non vengono passate credenziali utente o token. Infine, non tutti i corpi di richiesta/risposta vengono inviati al plugin di autorizzazione. Vengono inviati solo i corpi di richiesta/risposta in cui il Content-Type
è text/*
o application/json
.
Per i comandi che possono potenzialmente dirottare la connessione HTTP (HTTP Upgrade
), come exec
, il plugin di autorizzazione viene chiamato solo per le richieste HTTP iniziali. Una volta che il plugin approva il comando, l'autorizzazione non viene applicata al resto del flusso. In particolare, i dati in streaming non vengono passati ai plugin di autorizzazione. Per i comandi che restituiscono una risposta HTTP a blocchi, come logs
e events
, viene inviata solo la richiesta HTTP ai plugin di autorizzazione.
Durante l'elaborazione delle richieste/risposte, alcuni flussi di autorizzazione potrebbero richiedere ulteriori query al demone Docker. Per completare tali flussi, i plugin possono chiamare l'API del demone come un utente normale. Per abilitare queste query aggiuntive, il plugin deve fornire i mezzi per consentire a un amministratore di configurare le opportune politiche di autenticazione e sicurezza.
Diversi plugin
Sei responsabile di registrare il tuo plugin come parte dell'avvio del demone Docker. Puoi installare più plugin e concatenarli insieme. Questa catena può essere ordinata. Ogni richiesta al demone passa in ordine attraverso la catena. Solo quando tutti i plugin concedono l'accesso alla risorsa, viene concesso l'accesso.
Esempi di plugin
Twistlock AuthZ Broker
Il plugin authz ti consente di creare un semplice file JSON che il plugin leggerà per autorizzare le richieste. Pertanto, ti offre l'opportunità di controllare molto facilmente quali endpoint API possono raggiungere ciascun utente.
Questo è un esempio che consentirà ad Alice e Bob di creare nuovi container: {"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}
Nella pagina route_parser.go puoi trovare la relazione tra l'URL richiesto e l'azione. Nella pagina types.go puoi trovare la relazione tra il nome dell'azione e l'azione stessa.
Tutorial di plugin semplice
Puoi trovare un plugin facile da capire con informazioni dettagliate sull'installazione e il debug qui: https://github.com/carlospolop-forks/authobot
Leggi il file README
e il codice plugin.go
per capire come funziona.
Bypass del plugin di autenticazione di Docker
Enumera l'accesso
Le principali cose da verificare sono quali endpoint sono consentiti e quali valori di HostConfig sono consentiti.
Per eseguire questa enumerazione puoi utilizzare lo strumento https://github.com/carlospolop/docker_auth_profiler.
run --privileged
non consentito
run --privileged
non consentitoPrivilegi minimi
Esecuzione di un container e quindi ottenere una sessione privilegiata
In questo caso, l'amministratore di sistema ha impedito agli utenti di montare volumi e eseguire container con il flag --privileged
o di fornire qualsiasi capacità extra al container:
Tuttavia, un utente può creare una shell all'interno del container in esecuzione e conferirgli privilegi aggiuntivi:
Ora, l'utente può uscire dal container utilizzando una qualsiasi delle tecniche precedentemente discusse e aumentare i privilegi all'interno dell'host.
Montare una cartella scrivibile
In questo caso, l'amministratore di sistema ha impedito agli utenti di eseguire container con il flag --privileged
o di fornire qualsiasi capacità extra al container, e ha consentito solo il montaggio della cartella /tmp
:
Nota che potresti non essere in grado di montare la cartella /tmp
, ma puoi montare una diversa cartella scrivibile. Puoi trovare directory scrivibili usando: find / -writable -type d 2>/dev/null
Nota che non tutte le directory in una macchina Linux supporteranno il bit suid! Per verificare quali directory supportano il bit suid, esegui mount | grep -v "nosuid"
. Ad esempio, di solito /dev/shm
, /run
, /proc
, /sys/fs/cgroup
e /var/lib/lxcfs
non supportano il bit suid.
Nota anche che se puoi montare /etc
o qualsiasi altra cartella contenente file di configurazione, puoi modificarli dal container Docker come root per sfruttarli nell'host ed elevare i privilegi (ad esempio modificando /etc/shadow
).
Endpoint API non controllato
La responsabilità dell'amministratore di sistema che configura questo plugin sarebbe quella di controllare quali azioni e con quali privilegi ogni utente può eseguire. Pertanto, se l'amministratore adotta un approccio blacklist con gli endpoint e gli attributi, potrebbe dimenticarne alcuni che potrebbero consentire a un attaccante di elevare i privilegi.
Puoi controllare l'API di Docker su https://docs.docker.com/engine/api/v1.40/#
Struttura JSON non controllata
Binds in root
È possibile che quando l'amministratore di sistema ha configurato il firewall di Docker abbia dimenticato un parametro importante dell'API come "Binds". Nell'esempio seguente è possibile sfruttare questa errata configurazione per creare ed eseguire un container che monta la cartella root (/) dell'host:
Nota come in questo esempio stiamo utilizzando il parametro Binds
come chiave di livello radice nel JSON, ma nell'API appare sotto la chiave HostConfig
Binds in HostConfig
Seguire le stesse istruzioni come con Binds in root eseguendo questa richiesta all'API di Docker:
Montaggi nella root
Segui le stesse istruzioni come per Montaggi nella root eseguendo questa richiesta all'API di Docker:
Montaggi in HostConfig
Segui le stesse istruzioni come con Binds in root eseguendo questa richiesta all'API di Docker:
Attributo JSON non controllato
È possibile che quando l'amministratore di sistema ha configurato il firewall di Docker, abbia dimenticato un attributo importante di un parametro dell'API come "Capabilities" all'interno di "HostConfig". Nell'esempio seguente è possibile sfruttare questa errata configurazione per creare ed eseguire un container con la capacità SYS_MODULE:
Il HostConfig
è la chiave che di solito contiene i privilegi interessanti per evadere dal container. Tuttavia, come abbiamo discusso in precedenza, nota come l'utilizzo di Binds al di fuori di esso funzioni anche e potrebbe consentirti di aggirare le restrizioni.
Disabilitazione del plugin
Se l'amministratore di sistema ha dimenticato di proibire la possibilità di disabilitare il plugin, puoi approfittarne per disabilitarlo completamente!
Ricorda di riattivare il plugin dopo l'escalation, altrimenti un riavvio del servizio docker non funzionerà!
Auth Plugin Bypass writeups
Riferimenti
Last updated