Kubernetes Pivoting to Clouds
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Si estás ejecutando un clúster de k8s dentro de GCP, probablemente querrás que alguna aplicación que se ejecute dentro del clúster tenga acceso a GCP. Hay 2 formas comunes de hacerlo:
Una forma común de dar acceso a una aplicación de kubernetes a GCP es:
Crear una Cuenta de Servicio de GCP
Asignarle los permisos deseados
Descargar una clave json de la SA creada
Montarla como un secreto dentro del pod
Establecer la variable de entorno GOOGLE_APPLICATION_CREDENTIALS apuntando a la ruta donde se encuentra el json.
Por lo tanto, como atacante, si comprometes un contenedor dentro de un pod, deberías verificar esa variable env y los archivos json con credenciales de GCP.
Una forma de dar acceso a un GSA a un clúster de GKE es vinculándolos de esta manera:
Crea una cuenta de servicio de Kubernetes en el mismo espacio de nombres que tu clúster de GKE usando el siguiente comando:
Crea un Secret de Kubernetes que contenga las credenciales de la cuenta de servicio de GCP a la que deseas otorgar acceso al clúster de GKE. Puedes hacer esto utilizando la herramienta de línea de comandos gcloud
, como se muestra en el siguiente ejemplo:
Vincula el Secret de Kubernetes a la cuenta de servicio de Kubernetes utilizando el siguiente comando:
En el segundo paso se configuraron las credenciales de la GSA como secreto de la KSA. Entonces, si puedes leer ese secreto desde dentro del clúster GKE, puedes escalar a esa cuenta de servicio de GCP.
Con la Identidad de Carga de Trabajo, podemos configurar una cuenta de servicio de Kubernetes para actuar como una cuenta de servicio de Google. Los Pods que se ejecutan con la cuenta de servicio de Kubernetes se autenticarán automáticamente como la cuenta de servicio de Google al acceder a las API de Google Cloud.
La primera serie de pasos para habilitar este comportamiento es habilitar la Identidad de Carga de Trabajo en GCP (pasos) y crear la SA de GCP que deseas que k8s imite.
Habilitar la Identidad de Carga de Trabajo en un nuevo clúster
Crear/Actualizar un nuevo grupo de nodos (los clústeres Autopilot no necesitan esto)
Crea la Cuenta de Servicio de GCP para suplantar desde K8s con permisos de GCP:
Conéctese al clúster y cree la cuenta de servicio para usar
Vincular el GSA con el KSA
Ejecuta un pod con el KSA y verifica el acceso al GSA:
Verifica el siguiente comando para autenticarte en caso de ser necesario:
Como atacante dentro de K8s, deberías buscar SAs con la anotación iam.gke.io/gcp-service-account
ya que eso indica que la SA puede acceder a algo en GCP. Otra opción sería intentar abusar de cada KSA en el clúster y verificar si tiene acceso.
Desde GCP, siempre es interesante enumerar los bindings y saber qué acceso estás dando a las SAs dentro de Kubernetes.
Este es un script para iterar fácilmente sobre todas las definiciones de pods buscando esa anotación:
Una forma (desactualizada) de otorgar roles IAM a los Pods es usar un Kiam o un Kube2IAM servidor. Básicamente, necesitarás ejecutar un daemonset en tu clúster con un tipo de rol IAM privilegiado. Este daemonset será el que otorgue acceso a los roles IAM a los pods que lo necesiten.
Primero que nada, necesitas configurar qué roles pueden ser accedidos dentro del namespace, y lo haces con una anotación dentro del objeto namespace:
Una vez que el espacio de nombres está configurado con los roles de IAM que los Pods pueden tener, puedes indicar el rol que deseas en cada definición de pod con algo como:
Como atacante, si encuentras estas anotaciones en pods o namespaces o un servidor kiam/kube2iam en ejecución (probablemente en kube-system) puedes suplantar cada rol que ya está usado por pods y más (si tienes acceso a la cuenta de AWS, enumera los roles).
El rol IAM que se debe indicar debe estar en la misma cuenta de AWS que el rol kiam/kube2iam y ese rol debe poder acceder a él.
Esta es la manera recomendada por AWS.
Primero que nada, necesitas crear un proveedor OIDC para el clúster.
Luego, creas un rol IAM con los permisos que el SA requerirá.
Crea una relación de confianza entre el rol IAM y el SA nombre (o los namespaces que dan acceso al rol a todos los SAs del namespace). La relación de confianza principalmente verificará el nombre del proveedor OIDC, el nombre del namespace y el nombre del SA.
Finalmente, crea un SA con una anotación que indique el ARN del rol, y los pods que se ejecuten con ese SA tendrán acceso al token del rol. El token está escrito dentro de un archivo y la ruta se especifica en AWS_WEB_IDENTITY_TOKEN_FILE
(predeterminado: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
)
Para obtener aws usando el token de /var/run/secrets/eks.amazonaws.com/serviceaccount/token
, ejecuta:
Como atacante, si puedes enumerar un clúster de K8s, verifica las cuentas de servicio con esa anotación para escalar a AWS. Para hacerlo, simplemente exec/create un pod utilizando una de las cuentas de servicio privilegiadas de IAM y roba el token.
Además, si estás dentro de un pod, verifica las variables de entorno como AWS_ROLE_ARN y AWS_WEB_IDENTITY_TOKEN.
A veces, la Política de Confianza de un rol puede estar mal configurada y en lugar de dar acceso a AssumeRole a la cuenta de servicio esperada, se lo da a todas las cuentas de servicio. Por lo tanto, si eres capaz de escribir una anotación en una cuenta de servicio controlada, puedes acceder al rol.
Consulta la siguiente página para más información:
Este es un script para iterar fácilmente sobre todos los pods y definiciones de cuentas de servicio buscando esa anotación:
La sección anterior trataba sobre cómo robar roles de IAM con pods, pero ten en cuenta que un Nodo del clúster K8s va a ser una instancia dentro de la nube. Esto significa que es muy probable que el Nodo tenga un nuevo rol de IAM que puedes robar (ten en cuenta que generalmente todos los nodos de un clúster K8s tendrán el mismo rol de IAM, por lo que puede que no valga la pena intentar verificar en cada nodo).
Sin embargo, hay un requisito importante para acceder al endpoint de metadatos desde el nodo, necesitas estar en el nodo (¿sesión ssh?) o al menos tener la misma red:
Anteriormente hemos discutido cómo adjuntar Roles IAM a Pods o incluso cómo escapar al Nodo para robar el Rol IAM que la instancia tiene adjunto.
Puedes usar el siguiente script para robar tus nuevas y arduamente trabajadas credenciales del rol IAM:
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)