Grossa vulnerabilità trovata in Kubernetes ed OpenShift

0

Presentiamo gli attori coinvolti: Kubernetes (ancora non lo conoscete?) attualmente il re dei container orchestrator; seppur non sia l’unico attore in questo campo è sicuramente il più utilizzato. OpenShift, un prodotto Red Hat che ha Kubernetes come parte centrale, e su cui l’azienda ha costruito intorno una serie di capacità accessorie; se Kubernetes viene ancora utilizzato per orchestrare i container nella propria infrastruttura OpenShift, semplificando potremmo dire che quest’ultimo si occupa di gestire l’intero processo che porta dal codice all’immagine del container come poi viene gestito da Kubernetes.

La vulnerabilità in questione, identificata dalla CVE-2018-1002105, colpisce proprio Kubernetes e, questo colpo al suo cuore, fa vacillare di conseguenza anche OpenShift.

Ma di cosa stiamo parlando? Di un privilege escalation basato su una gestione errata delle richieste da parte di kube-apiserver. Senza entrare nel dettaglio dell’architettura di Kubernetes (tenete sotto controllo gli articoli tecnici in futuro su queste pagine), per capire l’impatto di questa vulnerabilità basti sapere che questo fantomatico “apiserver” è la componente a cui tutti parlano (utenti compresi) per pilotare l’intero cluster Kubernetes.

Un utente che sia già autorizzato ad eseguire una connessione ad un backend server tramite il Kubernetes API server può inviare ad esso nella stessa connessione richieste arbitrarie, bypassando le policy di sicurezza applicate allo stesso.

An API call to any aggregated API server endpoint can be escalated to perform any API request against that aggregated API server, as long as that aggregated API server is directly accessible from the Kubernetes API server’s network. In default configurations, all users (authenticated and unauthenticated) are allowed to perform discovery API calls that allow this escalation.

Una chiamata API ad un qualsiasi endpoint aggregato di un API server può essere scalata per eseguire una qualsiasi richiesta API all’API server aggregato, finché quell’API server è direttamente contattabile dalla rete dei Kubernetes API server. Nelle configurazioni di default tutti gli utenti (autenticati e non) sono abilitati ad eseguire chiamate API di ricerca che permettono questa scalata.

Articolato ma chiaro: se posso fare una query ad un api-server, posso eseguire una qualsiasi query ad uno qualsiasi degli api-server, purché quello che contatto possa accedere agli altri. Per default, questo avviene per tutti gli utenti (anche quelli non autenticati).

A pod exec/attach/portforward API call can be escalated to perform any API request against the kubelet API on the node specified in the pod spec (e.g. listing all pods on the node, running arbitrary commands inside those pods, and obtaining the command output). Pod exec/attach/portforward permissions are included in the admin/edit/view RBAC roles intended for namespace-constrained users.

Una chiamata API per esecuzione/connessione/inoltro porte di un pod può essere scalata per effettuare qualsiasi richiesta API al kubelet [agente di interscambio Kubernetes con l’api-server, ndt.] sul nodo presente nelle specifiche di quel Pod (ad esempio, avere una lista dei pod su quel nodo, eseguire comandi arbitrari all’interno di quei pod, ottenere output da questi). Le permission di esecuzione/connessione/inoltro di porte di un Pod sono incluse nei ruoli RBAC di admin/edit/view pensati per gli utenti limitati da namespace.

Semplifichiamo: se un utente ha la possibilità di eseguire, collegarsi o impostare l’inoltro delle porte di un Pod, quell’utente può eseguire una chiamata all’agent sul nodo in cui quel Pod sta girando, facendo praticamente qualsiasi cosa. Queste permission sono presenti nei ruoli di default sia per Amministratori ed Utenti, che anche per i soli ruoli di tipo Read Only.

Seppur alcune versioni di Kubernetes già non siano affette da questa vulnerabilità, nella issue presente sul GitHub di Kubernetes sono proposte delle mitigation per quelle ancora vulnerabili; il problema è che queste soluzioni possono portare a funzionamenti imprevisti, tra cui (per citarne una) l’impossibilità di aggiungere nuovi nodi al cluster tramite kubeadm join.

Ma come si riflette tutto questo in OpenShift? Beh, come dicevamo OpenShift ha Kubernetes come fulcro centrale ed attualmente tutte le versioni 3.x di OpenShift (l’attuale è la 3.11) sono vulnerabili; questa privilege escalation di Kubernetes si riflette su OpenShift permettendo l’accesso a livello cluster-admin a tutte le API presenti, includendo i servizi di metrica ed i cataloghi. In parole povere, è possibile anche agli utenti non autenticati creazione di di servizi in qualsiasi namespace ed in qualsiasi nodo, facendo si che l’attaccante possa sia effettuare il deploy di codice malevolo, che alterare servizi esistenti. L’accesso, inoltre, gli permetterebbe di leggere tutti i secrets, i pod, le variabili di ambiente ed i volumi persistenti; praticamente ha in mano l’intero cluster.

Brutta situazione per gli amministratori dunque, che si vedono costretti a prevedere un aggiornamento nel minor tempo possibile o ad applicare soluzioni temporanee che però limitano particolarmente l’uso della propria infrastruttura di orchestrazione.

La discussione è ancora aperta e su GitHub è ancora nel vivo. Attualmente il metodo migliore per risolvere il problema è l’upgrade a Kubernetes v1.12.3. Anche Red Hat ha rilasciato una serie di update per le versioni di OpenShift dalla 3.2 all’attuale 3.11, non ci resta che mettere mano ai cluster ed aggiornare.

Utente Linux/Unix da più di 20 anni, cerco sempre di condividere il mio know-how; occasionalmente, litigo con lo sviluppatore di Postfix e risolvo piccoli bug in GNOME. Adoro tutto ciò che può essere automatizzato e reso dinamico, l’HA e l’universo container. Autore dal 2011, provo a condividere quei piccoli tips&tricks che migliorano il lavoro e la giornata.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *