Vi serve il cloud computing? Iniziate subito

Che cluster! Vulnerabilità dei volumi locali in Kubernetes

Tomer Peled

scritto da

Tomer Peled

March 13, 2024

Tomer Peled

scritto da

Tomer Peled

Tomer Peled è Security Researcher in Akamai. Nell'ambito delle sue mansioni quotidiane, si occupa di condurre ricerche su vari argomenti, dalla vulnerabilità ai componenti interni dei sistemi operativi. Nel tempo libero, adora cucinare, praticare il Krav Maga e giocare al PC.

La mancata sanificazione dell'input nel codice sorgente di Kubernetes indica la possibilità di prendere precauzioni esterne per evitare un serio impatto sulla sicurezza.
La mancata sanificazione dell'input nel codice sorgente di Kubernetes indica la possibilità di prendere precauzioni esterne per evitare un serio impatto sulla sicurezza.

Editoriale e commenti aggiuntivi di Tricia Howard

Analisi riassuntiva

  • Tomer Peled, ricercatore della sicurezza di Akamai, ha recentemente scoperto una vulnerabilità molto grave in Kubernetes, a cui è stato assegnato il codice CVE-2023-5528 con un punteggio CVSS di 7,2.

  • La vulnerabilità consente l'esecuzione remota del codice con privilegi di SISTEMA su tutti gli endpoint Windows all'interno di un cluster Kubernetes. Per sfruttare questa vulnerabilità, l'autore dell'attacco deve applicare file YAML dannosi sul cluster.

  • Questa vulnerabilità può portare al controllo completo di tutti i nodi di Windows in un cluster.

  • Questa vulnerabilità può essere sfruttata nelle installazioni predefinite di Kubernetes (precedenti alla versione 1.28.4) ed è stata testata sia nelle distribuzioni on-premise sia in Azure Kubernetes Service.

  • In questo blog, forniamo un file YAML PoC (Proof-of-Concept) e una regola OPA (Open Policy Agent) in grado di risolvere questa vulnerabilità.

Introduzione

Kubernetes e i container in generale sono diventati una forza predominante nel settore della sicurezza e, in quanto tale, un punto di interesse per i ricercatori in tutto il mondo (noi inclusi). Il percorso della nostra ricerca inizialmente ci ha condotto alla vulnerabilità CVE-2023-3676 (CVSS of 8.8): una vulnerabilità di tipo Command Injection che può essere sfruttata applicando un file YAML dannoso sul cluster. Poiché il framework di Kubernetes utilizza i file YAML praticamente per tutto, dalla configurazione della CNI (Container Network Interface) alla gestione dei pod fino alla manipolazione dei segreti, uno sfruttamento di questa vulnerabilità potrebbe avere delle conseguenze disastrose.

La scoperta di questa vulnerabilità ha portato al rilevamento di altre due vulnerabilità che condividono la stessa causa principale: chiamata di funzione non sicura e mancata sanificazione dell'input utente. 

La mancata sanificazione del parametro subPath nei file YAML che crea i pod con i volumi apre una nuova opportunità per sferrare un attacco di tipo injection. Questo era il risultato originale, tuttavia, alla fine della ricerca, abbiamo notato un potenziale posto nel codice che sembrava portare ad un'altra vulnerabilità Command Injection. Dopo vari tentativi, siamo riusciti ad ottenere un risultato simile: l'esecuzione di comandi, come il servizio "kubelet"  (privilegi di SISTEMA). Da qui inizia oggi il nostro percorso con la vulnerabilità CVE-2023-5528.

In questo blog, descriveremo in dettaglio la vulnerabilità e i problemi nel codice sorgente di Kubernetes che l'hanno consentita, oltre ad analizzare la patch del team di Kubernetes e la sua efficacia. Anche se l'applicazione tempestiva delle patch è consigliata, abbiamo incluso delle brevi guide su come cercare i nodi interessati e come applicare una regola OPA (Open Policy Agent) per rilevare e bloccare questo tipo di comportamento.

Questo post evidenzia ancora una volta quanto sia fondamentale verificare le regole di configurazione YAML in Kubernetes poiché la sanificazione dell'input non è presente in varie aree del codice in Kubernetes e nei suoi progetti correlati (come gli ingressi, ad esempio).

Dettagli della vulnerabilità

Prima di trattare le specifiche di questa vulnerabilità, dobbiamo prima comprendere alcuni componenti di Kubernetes.

Che cosa sono i volumi di Kubernetes?

Con i volumi di Kubernetes , ci si riferisce ad una funzione concepita con l'intento di supportare la condivisione dei dati tra i pod o l'archiviazione dei dati in modo permanente al oltre il ciclo di vita di un pod. Esistono molti tipi di volumi diversi che possono usare gli sviluppatori. Ad esempio, nella nostra precedente ricerca sulla vulnerabilità CVE-2023-3676, abbiamo usato i volumi hostPath . Per questa vulnerabilità, desideriamo focalizzarci sui volumi locali, un altro tipo di volume in Kubernetes. I volumi locali sono progettati per consentire agli utenti di montare le partizioni del disco all'interno di un pod, mentre i volumi hostPath sono progettati per consentire agli utenti di montare le directory dai relativi nodi (host) in un pod.

Durante la creazione di un pod che include un volume locale, il servizio kubelet raggiunge (prima o poi) la funzione "MountSensitive()", al cui interno si trova una chiamata della linea cmd alla funzione "exec.command", che crea un collegamento symlink tra la posizione del volume sul nodo e la posizione all'interno del pod (Figura 1).

Durante la creazione di un pod che include un volume locale, il servizio kubelet raggiunge (prima o poi) la funzione "MountSensitive()", al cui interno si trova una chiamata della linea cmd alla funzione "exec.command", che crea un collegamento symlink tra la posizione del volume sul nodo e la posizione all'interno del pod (Figura 1). Figura 1. Linea cmd vulnerabile

Molti terminali utilizzano alcune versioni della concatenazione di comandi (Figura 2) nelle loro operazioni per praticità. Questo è anche il caso del prompt dei comandi di Windows (cmd) : utilizzando il token "&&", il terminale esegue due o più comandi uno dopo l'altro.

  C:\Users\user>echo "by using &&" && echo "we can execute multiple commands in the same command line"
  "by using &&"
  "we can execute multiple commands in the same command line"

  C:\Users\user>

Figura 2. Concatenazione di comandi in cmd

Se possiamo controllare uno dei parametri nel comando cmd , possiamo anche usare una vulnerabilità command injection. Tuttavia, esistono alcuni prerequisiti:  per utilizzare i volumi locali, è necessario specificare o creare un persistentVolume.

Che cosa sono i persistentVolume?

I persistentVolume sono risorse di storage che l'amministratore di un cluster può creare per fornire anticipatamente uno spazio di archiviazione di durata superiore al ciclo di vita del pod (Figura 3). Una volta creato un persistentVolume , un utente può richiedere dello spazio di archiviazione tramite un persistentVolumeClaim.

I persistentVolume sono risorse di storage che l'amministratore di un cluster può creare per fornire anticipatamente uno spazio di archiviazione di durata superiore al ciclo di vita del pod (Figure 3). Figura 3. Esempio di persistentVolume

È qui che è possibile sferrare un attacco di tipo injection. Un criminale può cambiare il valore del parametro "local.path" all'interno del file YAML persistentVolume per aggiungere un comando dannoso da eseguire durante il processo di montaggio..

Nella Figura 4, abbiamo usato il comando legittimo "&calc.exe&&" (che apre una calcolatrice sul nodo), tuttavia questo processo può essere usato per scopi ben più dannosi.

Nella Figura 4, abbiamo usato il comando legittimo "&calc.exe&&" (che apre una calcolatrice sul nodo), tuttavia questo processo può essere usato per scopi ben più dannosi. Figura 4. persistentVolume con il nostro comando "dannoso"

La Figura 5 mostra lo sfruttamento del nodo di un obiettivo dopo l'iniezione del nostro comando della calcolatrice "dannoso".

La Figura 5 mostra lo sfruttamento del nodo di un obiettivo dopo l'iniezione del nostro comando della calcolatrice "dannoso". Figura 5. PoC (Proof-of-Concept) dell'attacco

Analisi delle patch

Nell'intento di rimuovere l'opportunità di un attacco injection, il team Kubernetes ha deciso di eliminare la chiamata cmd  e di sostituirla con una funzione GO nativa che esegue la stessa operazione "os.Symlink()" (Figura 6).

Nell'intento di rimuovere l'opportunità di un attacco injection, il team Kubernetes ha deciso di eliminare la chiamata cmd e di sostituirla con una funzione GO nativa che esegue la stessa operazione "os.Symlink()" (Figura 6). Figura 6. Come appare la funzione dopo l'applicazione della patch

Ora la libreria "os" della funzione GO eseguirà solo un'operazione symlink, come era stato previsto inizialmente.

Sono vulnerabile?

 Questa vulnerabilità interessa gli utenti che dispongono di una versione di Kubernetes precedente  alla 1.28.4. Se non avete ancora applicato una patch per questa vulnerabilità, è una buona idea dare priorità a questa operazione. Ciò vale soprattutto per le organizzazioni con nodi di Windows che si trovano all'interno di un cluster, in cui risiede proprio la vulnerabilità.

Fortunatamente, non è un caso che si verifica sempre. Un amministratore può facilmente verificare se il cluster della propria organizzazione contiene nodi di Windows eseguendo il comando mostrato nella Figura 7 sul controller del cluster.

  root@controller:~/$ kubectl get nodes -o wide --show-labels | grep “os=windows”

  akswin000000                        Ready    agent   4d17h   v1.26.6   agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…
  akswin000001                        Ready    agent   4d17h   v1.26.6   agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…
  root@controller:~/$

Figura 7. Comando che consente di visualizzare eventuali nodi di Windows presenti in un cluster

È semplice stabilire se la vostra azienda è vulnerabile. Considerate la parte "os=windows". Se non sono presenti nodi di Windows, il comando non avrà alcun effetto a indicare che la vostra azienda non è vulnerabile.

Mitigazione

L'unica mitigazione disponibile è applicare una patch alle versioni di Kubernetes precedenti alla 1.28.3.

Tuttavia, anche se ciò è vero, sappiamo che l'applicazione immediata di una patch non è un'operazione consentita in alcune organizzazioni e reti. Pertanto, per evitare i rischi correlati ad una mancata applicazione di una patch, abbiamo fornito una regola OPA che consente di rilevare e bloccare questo tipo di comportamento. 

  package kubernetes.admission

  deny[msg] {                                                                 
    input.request.kind.kind == "PersistentVolume"
    path := input.request.object.spec.local.path                 
    contains(path, "&")                                     
    msg := sprintf("malicious path: %v was found", [path])     
}

L'OPA è un agente open-source che consente agli utenti di ricevere dati sul traffico in entrata e in uscita dai nodi e di eseguire azioni sui dati ricevuti in base a determinate policy.

Tenete presente che questa vulnerabilità non riguarda solo i nodi di Windows. Se il cluster di Kubernetes non contiene nodi di Windows, non dovete affrettarvi ad applicare la patch a questa specifica vulnerabilità. Tuttavia, è importante applicare la patch comunque quando avete tempo a disposizione.

Poiché il problema risiede nel codice sorgente, questa minaccia rimarrà attiva e lo sfruttamento della vulnerabilità è destinato a crescere. Ecco perché consigliamo vivamente di applicare la patch al cluster anche se non contiene nodi di Windows.

Conclusione

Questa vulnerabilità è un ottimo esempio del motivo per cui il modello di responsabilità condivisa è cruciale per la sicurezza. La mancata sanificazione dell'input nel codice sorgente di Kubernetes indica la possibilità di prendere precauzioni esterne per evitare un serio impatto sulla sicurezza. 

Soltanto nel 2023, sono state scoperte sette diverse vulnerabilità di tipo Command Injection, con maggiori opportunità in altre aree del codice. I team addetti alla sicurezza e le relative organizzazioni devono vigilare maggiormente su questa crescente tendenza e cercare di monitorare i contenuti dei file YAML poiché possono contenere minacce nascoste. La regola OPA che abbiamo fornito in questo post può aiutare a tale scopo.

L'Akamai Security Intelligence Group continuerà a monitorare questa minaccia e altre minacce simili e pubblicherà i risultati delle sue ricerche. Per tenervi aggiornati su questa vulnerabilità e su altre ricerche sulla sicurezza, seguiteci su X (in precedenza Twitter).

Desideriamo ringraziare il team di Kubernetes per la risposta rapida e la comunicazione efficace.

Cronologia delle divulgazioni

  • 01/11/2023 - Vulnerabilità segnalata al team di Kubernetes

  • 11/11/2023 - Il team di Kubernetes assegna i numeri CVE

  • 14/11/2023 - Kubernetes rilascia le correzioni CVE 

  • 13/03/2024 - Pubblicazione di questo blog



Tomer Peled

scritto da

Tomer Peled

March 13, 2024

Tomer Peled

scritto da

Tomer Peled

Tomer Peled è Security Researcher in Akamai. Nell'ambito delle sue mansioni quotidiane, si occupa di condurre ricerche su vari argomenti, dalla vulnerabilità ai componenti interni dei sistemi operativi. Nel tempo libero, adora cucinare, praticare il Krav Maga e giocare al PC.