mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-30 14:40:37 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -7,7 +7,7 @@ Ricorda che puoi ottenere tutte le risorse supportate con `kubectl api-resources
|
||||
|
||||
## **Privilege Escalation**
|
||||
|
||||
Si riferisce all'arte di ottenere **accesso a un diverso principale** all'interno del cluster **con privilegi diversi** (all'interno del cluster kubernetes o a cloud esterni) rispetto a quelli che già possiedi; in Kubernetes ci sono fondamentalmente **4 tecniche principali per escalare i privilegi**:
|
||||
Si riferisce all'arte di ottenere **accesso a un diverso principale** all'interno del cluster **con privilegi diversi** (all'interno del cluster kubernetes o a cloud esterni) rispetto a quelli che già possiedi. In Kubernetes ci sono fondamentalmente **4 tecniche principali per escalare i privilegi**:
|
||||
|
||||
- Essere in grado di **impersonare** altri utenti/gruppi/SAs con privilegi migliori all'interno del cluster kubernetes o a cloud esterni
|
||||
- Essere in grado di **creare/patchare/eseguire pod** dove puoi **trovare o allegare SAs** con privilegi migliori all'interno del cluster kubernetes o a cloud esterni
|
||||
@@ -33,7 +33,7 @@ verbs: ["*"]
|
||||
|
||||
In RBAC, alcune autorizzazioni comportano rischi significativi:
|
||||
|
||||
1. **`create`:** Concede la possibilità di creare qualsiasi risorsa del cluster, rischiando un'escursione dei privilegi.
|
||||
1. **`create`:** Concede la possibilità di creare qualsiasi risorsa del cluster, rischiando un'escursione di privilegi.
|
||||
2. **`list`:** Consente di elencare tutte le risorse, potenzialmente rivelando dati sensibili.
|
||||
3. **`get`:** Permette di accedere ai segreti degli account di servizio, costituendo una minaccia per la sicurezza.
|
||||
```yaml
|
||||
@@ -49,7 +49,7 @@ verbs: ["create", "list", "get"]
|
||||
```
|
||||
### Pod Create - Steal Token
|
||||
|
||||
Un attaccante con i permessi per creare un pod potrebbe allegare un Service Account privilegiato nel pod e rubare il token per impersonare il Service Account. In effetti, aumentando i privilegi.
|
||||
Un attaccante con i permessi per creare un pod potrebbe allegare un Service Account privilegiato nel pod e rubare il token per impersonare il Service Account. Efficacemente, aumentando i privilegi.
|
||||
|
||||
Esempio di un pod che ruberà il token del Service Account `bootstrap-signer` e lo invierà all'attaccante:
|
||||
```yaml
|
||||
@@ -72,13 +72,13 @@ serviceAccountName: bootstrap-signer
|
||||
automountServiceAccountToken: true
|
||||
hostNetwork: true
|
||||
```
|
||||
### Creazione e Fuga del Pod
|
||||
### Creazione e fuga del Pod
|
||||
|
||||
Il seguente indica tutti i privilegi che un container può avere:
|
||||
Quanto segue indica tutti i privilegi che un container può avere:
|
||||
|
||||
- **Accesso privilegiato** (disabilitando le protezioni e impostando le capacità)
|
||||
- **Disabilitare i namespace hostIPC e hostPid** che possono aiutare ad elevare i privilegi
|
||||
- **Disabilitare il namespace hostNetwork**, dando accesso per rubare i privilegi cloud dei nodi e un accesso migliore alle reti
|
||||
- **Disabilitare il namespace hostNetwork**, dando accesso per rubare i privilegi cloud dei nodi e un migliore accesso alle reti
|
||||
- **Montare gli host / all'interno del container**
|
||||
```yaml:super_privs.yaml
|
||||
apiVersion: v1
|
||||
@@ -151,7 +151,7 @@ pod-escape-privileges.md
|
||||
|
||||
È possibile abusare di questi permessi per **creare un nuovo pod** e stabilire privilegi come nell'esempio precedente.
|
||||
|
||||
Il seguente yaml **crea un daemonset e esfiltra il token del SA** all'interno del pod:
|
||||
Il seguente yaml **crea un daemonset ed esfiltra il token del SA** all'interno del pod:
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
@@ -214,7 +214,7 @@ Il servizio Kubelet espone l'endpoint `/logs/` che è fondamentalmente **l'espos
|
||||
|
||||
Pertanto, un attaccante con **accesso in scrittura nella cartella /var/log/** del container potrebbe abusare di questo comportamento in 2 modi:
|
||||
|
||||
- Modificando il file `0.log` del suo container (di solito situato in `/var/logs/pods/namespace_pod_uid/container/0.log`) per essere un **symlink che punta a `/etc/shadow`** per esempio. Poi, sarai in grado di esfiltrare il file shadow degli host facendo:
|
||||
- Modificando il file `0.log` del proprio container (di solito situato in `/var/logs/pods/namespace_pod_uid/container/0.log`) per essere un **symlink che punta a `/etc/shadow`** per esempio. Poi, sarai in grado di esfiltrare il file shadow degli host facendo:
|
||||
```bash
|
||||
kubectl logs escaper
|
||||
failed to get parse function: unsupported log format: "root::::::::\n"
|
||||
@@ -250,7 +250,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
Che doveva prevenire le fughe come quelle precedenti utilizzando, invece di un mount hostPath, un PersistentVolume e un PersistentVolumeClaim per montare una cartella dell'host nel contenitore con accesso in scrittura:
|
||||
Che era destinato a prevenire le fughe come quelle precedenti, utilizzando invece di un mount hostPath, un PersistentVolume e un PersistentVolumeClaim per montare una cartella dell'host nel contenitore con accesso in scrittura:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -313,13 +313,13 @@ curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
|
||||
-H "Accept: application/json" \
|
||||
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### Elenco dei Segreti
|
||||
### Elencare i segreti
|
||||
|
||||
Il permesso di **elencare i segreti potrebbe consentire a un attaccante di leggere effettivamente i segreti** accedendo all'endpoint API REST:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### Creazione e Lettura dei Segreti
|
||||
### Creazione e Lettura di Segreti
|
||||
|
||||
Esiste un tipo speciale di segreto Kubernetes di tipo **kubernetes.io/service-account-token** che memorizza i token degli account di servizio. Se hai i permessi per creare e leggere segreti, e conosci anche il nome dell'account di servizio, puoi creare un segreto come segue e poi rubare il token dell'account di servizio della vittima da esso:
|
||||
```yaml
|
||||
@@ -384,13 +384,72 @@ Nota che se ti è permesso creare e leggere segreti in un certo namespace, il se
|
||||
|
||||
### Lettura di un segreto – forzatura dei token ID
|
||||
|
||||
Mentre un attaccante in possesso di un token con permessi di lettura richiede il nome esatto del segreto per utilizzarlo, a differenza del privilegio più ampio di _**elencare i segreti**_, ci sono ancora vulnerabilità. Gli account di servizio predefiniti nel sistema possono essere enumerati, ciascuno associato a un segreto. Questi segreti hanno una struttura di nome: un prefisso statico seguito da un token alfanumerico casuale di cinque caratteri (escludendo alcuni caratteri) secondo il [codice sorgente](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83).
|
||||
Mentre un attaccante in possesso di un token con permessi di lettura richiede il nome esatto del segreto per utilizzarlo, a differenza del privilegio più ampio di _**elencare segreti**_, ci sono ancora vulnerabilità. Gli account di servizio predefiniti nel sistema possono essere enumerati, ciascuno associato a un segreto. Questi segreti hanno una struttura di nome: un prefisso statico seguito da un token alfanumerico casuale di cinque caratteri (escludendo alcuni caratteri) secondo il [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83).
|
||||
|
||||
Il token è generato da un set limitato di 27 caratteri (`bcdfghjklmnpqrstvwxz2456789`), piuttosto che dall'intero intervallo alfanumerico. Questa limitazione riduce il numero totale di combinazioni possibili a 14.348.907 (27^5). Di conseguenza, un attaccante potrebbe ragionevolmente eseguire un attacco di forza bruta per dedurre il token in poche ore, potenzialmente portando a un'escalation dei privilegi accedendo a account di servizio sensibili.
|
||||
|
||||
### Richieste di Firma del Certificato
|
||||
### EncrpytionConfiguration in chiaro
|
||||
|
||||
Se hai i verbi **`create`** nella risorsa `certificatesigningrequests` (o almeno in `certificatesigningrequests/nodeClient`). Puoi **creare** un nuovo CeSR di un **nuovo nodo.**
|
||||
È possibile trovare chiavi in chiaro per crittografare i dati a riposo in questo tipo di oggetto come:
|
||||
```yaml
|
||||
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
|
||||
|
||||
#
|
||||
# CAUTION: this is an example configuration.
|
||||
# Do not use this for your own cluster!
|
||||
#
|
||||
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
- pandas.awesome.bears.example # a custom resource API
|
||||
providers:
|
||||
# This configuration does not provide data confidentiality. The first
|
||||
# configured provider is specifying the "identity" mechanism, which
|
||||
# stores resources as plain text.
|
||||
#
|
||||
- identity: {} # plain text, in other words NO encryption
|
||||
- aesgcm:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZQ==
|
||||
- name: key2
|
||||
secret: dGhpcyBpcyBwYXNzd29yZA==
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZQ==
|
||||
- name: key2
|
||||
secret: dGhpcyBpcyBwYXNzd29yZA==
|
||||
- secretbox:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
|
||||
- resources:
|
||||
- events
|
||||
providers:
|
||||
- identity: {} # do not encrypt Events even though *.* is specified below
|
||||
- resources:
|
||||
- '*.apps' # wildcard match requires Kubernetes 1.27 or later
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key2
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg==
|
||||
- resources:
|
||||
- '*.*' # wildcard match requires Kubernetes 1.27 or later
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key3
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==
|
||||
```
|
||||
### Certificate Signing Requests
|
||||
|
||||
Se hai il verbo **`create`** nella risorsa `certificatesigningrequests` (o almeno in `certificatesigningrequests/nodeClient`). Puoi **creare** un nuovo CeSR di un **nuovo nodo.**
|
||||
|
||||
Secondo la [documentazione è possibile approvare automaticamente queste richieste](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), quindi in quel caso **non hai bisogno di permessi extra**. Se no, dovresti essere in grado di approvare la richiesta, il che significa aggiornare in `certificatesigningrequests/approval` e `approve` in `signers` con resourceName `<signerNameDomain>/<signerNamePath>` o `<signerNameDomain>/*`
|
||||
|
||||
@@ -436,7 +495,7 @@ Il modo per bypassare questo è semplicemente **creare una credenziale del nodo
|
||||
```
|
||||
### AWS EKS aws-auth configmaps
|
||||
|
||||
I principali che possono modificare **`configmaps`** nello spazio dei nomi kube-system su cluster EKS (devono essere in AWS) possono ottenere privilegi di amministratore del cluster sovrascrivendo il **configmap** **aws-auth**.\
|
||||
I principi che possono modificare **`configmaps`** nello spazio dei nomi kube-system sui cluster EKS (devono essere in AWS) possono ottenere privilegi di amministratore del cluster sovrascrivendo il configmap **aws-auth**.\
|
||||
I verbi necessari sono **`update`** e **`patch`**, o **`create`** se il configmap non è stato creato:
|
||||
```bash
|
||||
# Check if config map exists
|
||||
@@ -477,7 +536,7 @@ groups:
|
||||
- system:masters
|
||||
```
|
||||
> [!WARNING]
|
||||
> Puoi usare **`aws-auth`** per la **persistenza** dando accesso a utenti di **altri account**.
|
||||
> Puoi usare **`aws-auth`** per la **persistenza** dando accesso agli utenti di **altri account**.
|
||||
>
|
||||
> Tuttavia, `aws --profile other_account eks update-kubeconfig --name <cluster-name>` **non funziona da un account diverso**. Ma in realtà `aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` funziona se metti l'ARN del cluster invece del solo nome.\
|
||||
> Per far funzionare `kubectl`, assicurati di **configurare** il **kubeconfig della vittima** e negli argomenti di esecuzione di aws aggiungi `--profile other_account_role` in modo che kubectl utilizzi il profilo dell'altro account per ottenere il token e contattare AWS.
|
||||
@@ -486,9 +545,9 @@ groups:
|
||||
|
||||
Se hai i permessi per modificare il **`coredns` configmap** nel namespace `kube-system`, puoi modificare gli indirizzi a cui i domini verranno risolti per poter eseguire attacchi MitM per **rubare informazioni sensibili o iniettare contenuti malevoli**.
|
||||
|
||||
I verbi necessari sono **`update`** e **`patch`** sul **`coredns`** configmap (o su tutte le config maps).
|
||||
I verbi necessari sono **`update`** e **`patch`** sul **`coredns`** configmap (o su tutte le config map).
|
||||
|
||||
Un normale **file coredns** contiene qualcosa di simile:
|
||||
Un normale **file coredns** contiene qualcosa del genere:
|
||||
```yaml
|
||||
data:
|
||||
Corefile: |
|
||||
@@ -540,15 +599,15 @@ Il secondo metodo è **assegnare permessi K8s all'interno del cluster** identifi
|
||||
|
||||
### Creare token serviceaccounts
|
||||
|
||||
Principi che possono **creare TokenRequests** (`serviceaccounts/token`) quando si parla con l'endpoint API K8s SAs (info da [**qui**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)).
|
||||
Principi che possono **creare TokenRequests** (`serviceaccounts/token`) Quando si parla con l'endpoint API K8s SAs (info da [**qui**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego)).
|
||||
|
||||
### ephemeralcontainers
|
||||
|
||||
I principi che possono **`update`** o **`patch`** **`pods/ephemeralcontainers`** possono ottenere **esecuzione di codice su altri pod**, e potenzialmente **uscire** al loro nodo aggiungendo un contenitore effimero con un securityContext privilegiato.
|
||||
Principi che possono **`update`** o **`patch`** **`pods/ephemeralcontainers`** possono ottenere **esecuzione di codice su altri pod**, e potenzialmente **uscire** al loro nodo aggiungendo un contenitore effimero con un securityContext privilegiato.
|
||||
|
||||
### ValidatingWebhookConfigurations o MutatingWebhookConfigurations
|
||||
|
||||
I principi con uno dei verbi `create`, `update` o `patch` su `validatingwebhookconfigurations` o `mutatingwebhookconfigurations` potrebbero essere in grado di **creare una di queste webhookconfigurations** per poter **escalare i privilegi**.
|
||||
Principi con uno dei verbi `create`, `update` o `patch` su `validatingwebhookconfigurations` o `mutatingwebhookconfigurations` potrebbero essere in grado di **creare una di queste webhookconfigurations** per poter **escalare i privilegi**.
|
||||
|
||||
Per un [`mutatingwebhookconfigurations` esempio controlla questa sezione di questo post](#malicious-admission-controller).
|
||||
|
||||
@@ -559,7 +618,7 @@ Allora può aggiornare/creare nuovi ruoli, clusterroles con permessi migliori di
|
||||
|
||||
### Nodes proxy
|
||||
|
||||
I principi con accesso alla **`nodes/proxy`** subrisorsa possono **eseguire codice su pod** tramite l'API Kubelet (secondo [**questo**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Maggiori informazioni sull'autenticazione Kubelet in questa pagina:
|
||||
Principi con accesso alla **`nodes/proxy`** subrisorsa possono **eseguire codice su pod** tramite l'API Kubelet (secondo [**questo**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Maggiori informazioni sull'autenticazione Kubelet in questa pagina:
|
||||
|
||||
{{#ref}}
|
||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||
@@ -569,7 +628,7 @@ Hai un esempio di come ottenere [**RCE parlando autorizzato a un'API Kubelet qui
|
||||
|
||||
### Eliminare pod + nodi non pianificabili
|
||||
|
||||
I principi che possono **eliminare pod** (`delete` verb su `pods` resource), o **evictare pod** (`create` verb su `pods/eviction` resource), o **cambiare lo stato del pod** (accesso a `pods/status`) e possono **rendere altri nodi non pianificabili** (accesso a `nodes/status`) o **eliminare nodi** (`delete` verb su `nodes` resource) e hanno il controllo su un pod, potrebbero **rubare pod da altri nodi** in modo che vengano **eseguiti** nel **nodo compromesso** e l'attaccante può **rubare i token** da quei pod.
|
||||
Principi che possono **eliminare pod** (`delete` verbo su `pods` risorsa), o **evict pod** (`create` verbo su `pods/eviction` risorsa), o **cambiare lo stato del pod** (accesso a `pods/status`) e possono **rendere altri nodi non pianificabili** (accesso a `nodes/status`) o **eliminare nodi** (`delete` verbo su `nodes` risorsa) e hanno il controllo su un pod, potrebbero **rubare pod da altri nodi** in modo che vengano **eseguiti** nel **nodo compromesso** e l'attaccante può **rubare i token** da quei pod.
|
||||
```bash
|
||||
patch_node_capacity(){
|
||||
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
|
||||
@@ -594,7 +653,7 @@ Kubernetes ha un [meccanismo integrato](https://kubernetes.io/docs/reference/acc
|
||||
|
||||
Questo sistema garantisce che **gli utenti non possano elevare i propri privilegi modificando ruoli o binding di ruoli**. L'applicazione di questa regola avviene a livello API, fornendo una protezione anche quando l'autorizzatore RBAC è inattivo.
|
||||
|
||||
La regola stabilisce che un **utente può creare o aggiornare un ruolo solo se possiede tutti i permessi di cui il ruolo è composto**. Inoltre, l'ambito dei permessi esistenti dell'utente deve allinearsi a quello del ruolo che sta tentando di creare o modificare: o a livello cluster-wide per i ClusterRoles o confinato allo stesso namespace (o cluster-wide) per i Roles.
|
||||
La regola stabilisce che un **utente può creare o aggiornare un ruolo solo se possiede tutti i permessi di cui il ruolo è composto**. Inoltre, l'ambito dei permessi esistenti dell'utente deve allinearsi a quello del ruolo che sta tentando di creare o modificare: o a livello di cluster per i ClusterRoles o limitato allo stesso namespace (o a livello di cluster) per i Roles.
|
||||
|
||||
> [!WARNING]
|
||||
> C'è un'eccezione a questa regola precedente. Se un principio ha il **verbo `escalate`** su **`roles`** o **`clusterroles`**, può aumentare i privilegi di ruoli e clusterroles anche senza avere i permessi lui stesso.
|
||||
@@ -602,7 +661,7 @@ La regola stabilisce che un **utente può creare o aggiornare un ruolo solo se p
|
||||
### **Ottieni & Patch RoleBindings/ClusterRoleBindings**
|
||||
|
||||
> [!CAUTION]
|
||||
> **Apparentemente questa tecnica funzionava prima, ma secondo i miei test non funziona più per lo stesso motivo spiegato nella sezione precedente. Non puoi creare/modificare un rolebinding per darti o dare a un altro SA alcuni privilegi se non li hai già.**
|
||||
> **Apparentemente questa tecnica funzionava prima, ma secondo i miei test non funziona più per lo stesso motivo spiegato nella sezione precedente. Non puoi creare/modificare un rolebinding per darti o dare a un diverso SA alcuni privilegi se non li hai già.**
|
||||
|
||||
Il privilegio di creare Rolebindings consente a un utente di **associare ruoli a un account di servizio**. Questo privilegio può potenzialmente portare a un'escalation dei privilegi perché **consente all'utente di associare privilegi di amministratore a un account di servizio compromesso.**
|
||||
|
||||
@@ -626,7 +685,7 @@ image: nginx
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
Ad esempio, per inserire un backdoor in un pod esistente con un nuovo container, potresti semplicemente aggiungere un nuovo container nella specifica. Nota che potresti **dare più permessi** al secondo container che il primo non avrà.
|
||||
Ad esempio, per inserire un backdoor in un pod esistente con un nuovo container, puoi semplicemente aggiungere un nuovo container nella specifica. Nota che puoi **dare più permessi** al secondo container che il primo non avrà.
|
||||
|
||||
Maggiore informazione su: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
@@ -689,7 +748,7 @@ Il frammento sopra sostituisce la prima immagine del container in ogni pod con `
|
||||
- **Pods e Account di Servizio**: Per impostazione predefinita, i pod montano un token di account di servizio. Per migliorare la sicurezza, Kubernetes consente di disabilitare questa funzionalità di automount.
|
||||
- **Come Applicare**: Imposta `automountServiceAccountToken: false` nella configurazione degli account di servizio o dei pod a partire dalla versione 1.6 di Kubernetes.
|
||||
|
||||
### **Assegnazione Ristretta degli Utenti in RoleBindings/ClusterRoleBindings**
|
||||
### **Assegnazione Utente Ristretto in RoleBindings/ClusterRoleBindings**
|
||||
|
||||
- **Inclusione Selettiva**: Assicurati che solo gli utenti necessari siano inclusi in RoleBindings o ClusterRoleBindings. Esegui audit regolari e rimuovi utenti irrilevanti per mantenere una sicurezza rigorosa.
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
In Kubernetes, si osserva che un comportamento predefinito consente l'instaurazione di connessioni tra **tutti i container che risiedono sullo stesso nodo**. Questo si applica indipendentemente dalle distinzioni di namespace. Tale connettività si estende fino al **Layer 2** (Ethernet). Di conseguenza, questa configurazione espone potenzialmente il sistema a vulnerabilità. In particolare, apre la possibilità per un **container malevolo** di eseguire un **attacco di ARP spoofing** contro altri container situati sullo stesso nodo. Durante un attacco di questo tipo, il container malevolo può ingannevolmente intercettare o modificare il traffico di rete destinato ad altri container.
|
||||
|
||||
Gli attacchi di ARP spoofing coinvolgono l'**attaccante che invia messaggi ARP falsificati** (Address Resolution Protocol) su una rete locale. Questo porta al collegamento dell'**indirizzo MAC dell'attaccante con l'indirizzo IP di un computer o server legittimo sulla rete**. Dopo l'esecuzione con successo di un attacco di questo tipo, l'attaccante può intercettare, modificare o persino fermare i dati in transito. L'attacco viene eseguito sul Layer 2 del modello OSI, motivo per cui la connettività predefinita in Kubernetes a questo livello solleva preoccupazioni di sicurezza.
|
||||
Gli attacchi di ARP spoofing coinvolgono l'**attaccante che invia messaggi ARP falsificati** (Address Resolution Protocol) su una rete locale. Questo porta al collegamento del **MAC address dell'attaccante con l'indirizzo IP di un computer o server legittimo sulla rete**. Dopo l'esecuzione con successo di un attacco di questo tipo, l'attaccante può intercettare, modificare o persino fermare i dati in transito. L'attacco viene eseguito sul Layer 2 del modello OSI, motivo per cui la connettività predefinita in Kubernetes a questo livello solleva preoccupazioni di sicurezza.
|
||||
|
||||
Nel scenario verranno create 4 macchine:
|
||||
Nello scenario verranno create 4 macchine:
|
||||
|
||||
- ubuntu-pe: macchina privilegiata per scappare al nodo e controllare le metriche (non necessaria per l'attacco)
|
||||
- **ubuntu-attack**: **container malevolo** nel namespace predefinito
|
||||
- **ubuntu-victim**: macchina **vittima** nel namespace kube-system
|
||||
- **mysql**: macchina **vittima** nel namespace predefinito
|
||||
- ubuntu-pe: Macchina privilegiata per evadere al nodo e controllare le metriche (non necessaria per l'attacco)
|
||||
- **ubuntu-attack**: **Container malevolo** nel namespace predefinito
|
||||
- **ubuntu-victim**: Macchina **vittima** nel namespace kube-system
|
||||
- **mysql**: Macchina **vittima** nel namespace predefinito
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -96,7 +96,7 @@ kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools
|
||||
kubectl exec -it ubuntu-victim -n kube-system -- bash -c "apt update; apt install -y net-tools curl netcat mysql-client; bash"
|
||||
kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; bash"
|
||||
```
|
||||
## Rete Kubernetes di Base
|
||||
## Rete di Base di Kubernetes
|
||||
|
||||
Se desideri maggiori dettagli sugli argomenti di rete introdotti qui, vai ai riferimenti.
|
||||
|
||||
@@ -145,7 +145,7 @@ nameserver 10.96.0.10
|
||||
```
|
||||
Tuttavia, il pod **non sa** come arrivare a quell'**indirizzo** perché il **pod range** in questo caso è 172.17.0.10/26.
|
||||
|
||||
Pertanto, il pod invierà le **richieste DNS all'indirizzo 10.96.0.10** che sarà **tradotto** dal cbr0 **in** **172.17.0.2**.
|
||||
Pertanto, il pod invierà le **richieste DNS all'indirizzo 10.96.0.10** che sarà **tradotto** da cbr0 **in** **172.17.0.2**.
|
||||
|
||||
> [!WARNING]
|
||||
> Questo significa che una **richiesta DNS** di un pod andrà **sempre** al **bridge** per **tradurre** l'**IP del servizio nell'IP dell'endpoint**, anche se il server DNS si trova nella stessa subnet del pod.
|
||||
@@ -237,7 +237,7 @@ Come già accennato, se **comprometti un pod nello stesso nodo del pod del serve
|
||||
|
||||
Hai un ottimo **tool** e **tutorial** per testare questo in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
Nel nostro scenario, **scarica** il **tool** nel pod attaccante e crea un \*\*file chiamato `hosts` \*\* con i **domini** che vuoi **spoofare** come:
|
||||
Nel nostro scenario, **scarica** il **tool** nel pod attaccante e crea un **file chiamato `hosts`** con i **domini** che vuoi **spoofare** come:
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
@@ -261,12 +261,44 @@ google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> Se provi a creare il tuo script di spoofing DNS, se **modifichi solo la risposta DNS** questo **non** funzionerà, perché la **risposta** avrà un **src IP** l'indirizzo IP del **pod** **maligno** e **non sarà** **accettata**.\
|
||||
> Devi generare un **nuovo pacchetto DNS** con il **src IP** del **DNS** a cui la vittima invia la richiesta DNS (che è qualcosa come 172.16.0.2, non 10.96.0.10, quello è l'IP del servizio DNS K8s e non l'IP del server DNS, di più su questo nell'introduzione).
|
||||
> Devi generare un **nuovo pacchetto DNS** con il **src IP** del **DNS** dove la vittima invia la richiesta DNS (che è qualcosa come 172.16.0.2, non 10.96.0.10, quello è l'IP del servizio DNS K8s e non l'IP del server DNS, maggiori informazioni su questo nell'introduzione).
|
||||
|
||||
## Catturare il Traffico
|
||||
## DNS Spoofing tramite configmap coreDNS
|
||||
|
||||
Un utente con permessi di scrittura sulla configmap `coredns` nel namespace kube-system può modificare le risposte DNS del cluster.
|
||||
|
||||
Controlla ulteriori informazioni su questo attacco in:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/README.md
|
||||
{{/ref}}
|
||||
|
||||
## Abusare dei servizi di gestione kubernetes esposti
|
||||
|
||||
Servizi come Apache NiFi, Kubeflow, Argo Workflows, Weave Scope e il dashboard di Kubernetes sono spesso esposti sia a Internet che all'interno della rete kubernetes. Un attaccante che riesce a **trovare qualsiasi piattaforma utilizzata per gestire kubernetes e accedervi** può abusarne per ottenere accesso all'API di kubernetes e compiere azioni come creare nuovi pod, modificare quelli esistenti o persino eliminarli.
|
||||
|
||||
## Enumerare le politiche di rete kubernetes
|
||||
|
||||
Ottieni le **networkpolicies** configurate:
|
||||
```bash
|
||||
kubectl get networkpolicies --all-namespaces
|
||||
```
|
||||
Ottieni le politiche di rete **Callico**:
|
||||
```bash
|
||||
kubectl get globalnetworkpolicy --all-namespaces
|
||||
```
|
||||
Ottieni le politiche di rete **Cillium**:
|
||||
```bash
|
||||
kubectl get ciliumnetworkpolicy --all-namespaces
|
||||
```
|
||||
Ottieni altre CRD relative alle politiche installate dal tuo plugin di rete o soluzione di sicurezza:
|
||||
```bash
|
||||
kubectl get crd | grep -i policy
|
||||
```
|
||||
## Cattura del Traffico
|
||||
|
||||
Lo strumento [**Mizu**](https://github.com/up9inc/mizu) è un visualizzatore di traffico API **semplice ma potente per Kubernetes** che ti consente di **visualizzare tutta la comunicazione API** tra microservizi per aiutarti a debug e risolvere regressioni.\
|
||||
Installerà agenti nei pod selezionati e raccoglierà le loro informazioni sul traffico e te le mostrerà in un server web. Tuttavia, avrai bisogno di elevate autorizzazioni K8s per questo (e non è molto furtivo).
|
||||
Installerà agenti nei pod selezionati e raccoglierà le loro informazioni sul traffico, mostrandole in un server web. Tuttavia, avrai bisogno di elevate autorizzazioni K8s per questo (e non è molto furtivo).
|
||||
|
||||
## Riferimenti
|
||||
|
||||
|
||||
Reference in New Issue
Block a user