Kubernetes Enumeration
Tokens de Kubernetes
Si has comprometido el acceso a una máquina, el usuario puede tener acceso a alguna plataforma de Kubernetes. El token suele estar ubicado en un archivo señalado por la variable de entorno KUBECONFIG
o dentro de ~/.kube
.
En esta carpeta podrías encontrar archivos de configuración con tokens y configuraciones para conectarse al servidor API. En esta carpeta también puedes encontrar una carpeta de caché con información previamente recuperada.
Si has comprometido un pod dentro de un entorno de Kubernetes, hay otros lugares donde puedes encontrar tokens e información sobre el entorno actual de K8:
Tokens de Cuenta de Servicio
Antes de continuar, si no sabes qué es un servicio en Kubernetes, te sugeriría que sigas este enlace y leas al menos la información sobre la arquitectura de Kubernetes.
Tomado de la documentación de Kubernetes:
"Cuando creas un pod, si no especificas una cuenta de servicio, se le asigna automáticamente la cuenta de servicio predeterminada en el mismo espacio de nombres."
ServiceAccount es un objeto gestionado por Kubernetes y utilizado para proporcionar una identidad a los procesos que se ejecutan en un pod. Cada cuenta de servicio tiene un secreto relacionado con ella y este secreto contiene un token de portador. Este es un JSON Web Token (JWT), un método para representar afirmaciones de forma segura entre dos partes.
Usualmente uno de los directorios:
/run/secrets/kubernetes.io/serviceaccount
/var/run/secrets/kubernetes.io/serviceaccount
/secrets/kubernetes.io/serviceaccount
contiene los archivos:
ca.crt: Es el certificado ca para verificar las comunicaciones de Kubernetes
namespace: Indica el espacio de nombres actual
token: Contiene el token de servicio del pod actual.
Ahora que tienes el token, puedes encontrar el servidor API dentro de la variable de entorno KUBECONFIG
. Para más información ejecuta (env | set) | grep -i "kuber|kube
"
El token de la cuenta de servicio está firmado por la clave que reside en el archivo sa.key y validado por sa.pub.
Ubicación predeterminada en Kubernetes:
/etc/kubernetes/pki
Ubicación predeterminada en Minikube:
/var/lib/localkube/certs
Hot Pods
Los hot pods son pods que contienen un token de cuenta de servicio privilegiado. Un token de cuenta de servicio privilegiado es un token que tiene permiso para realizar tareas privilegiadas como listar secretos, crear pods, etc.
RBAC
Si no sabes qué es RBAC, lee esta sección.
Hoja de Trucos para Enumeración
Para enumerar un entorno K8s necesitas un par de cosas:
Un token de autenticación válido. En la sección anterior vimos dónde buscar un token de usuario y un token de cuenta de servicio.
La dirección (https://host:port) del API de Kubernetes. Esto se puede encontrar usualmente en las variables de entorno y/o en el archivo de configuración de kube.
Opcional: El ca.crt para verificar el servidor API. Esto se puede encontrar en los mismos lugares que el token. Esto es útil para verificar el certificado del servidor API, pero usando
--insecure-skip-tls-verify
conkubectl
o-k
concurl
no necesitarás esto.
Con esos detalles puedes enumerar Kubernetes. Si el API por alguna razón es accesible a través de Internet, puedes simplemente descargar esa información y enumerar la plataforma desde tu host.
Sin embargo, usualmente el servidor API está dentro de una red interna, por lo tanto, necesitarás crear un túnel a través de la máquina comprometida para acceder a él desde tu máquina, o puedes subir el binario kubectl, o usar curl/wget/cualquier cosa
para realizar solicitudes HTTP en bruto al servidor API.
Diferencias entre los verbos list
y get
list
y get
Con permisos de get
puedes acceder a información de activos específicos (opción describe
en kubectl
) API:
Si tienes el permiso list
, se te permite ejecutar solicitudes de API para listar un tipo de activo (opción get
en kubectl
):
Si tienes el permiso watch
, se te permite ejecutar solicitudes de API para monitorear activos:
Abren una conexión de transmisión que te devuelve el manifiesto completo de un Deployment cada vez que cambia (o cuando se crea uno nuevo).
Los siguientes comandos de kubectl
indican solo cómo listar los objetos. Si quieres acceder a los datos necesitas usar describe
en lugar de get
.
Usando curl
Desde dentro de un pod puedes usar varias variables de entorno:
Por defecto, el pod puede acceder al kube-api server en el nombre de dominio kubernetes.default.svc
y puedes ver la red de kube en /etc/resolv.config
, ya que aquí encontrarás la dirección del servidor DNS de kubernetes (el ".1" del mismo rango es el punto final del kube-api).
Usando kubectl
Teniendo el token y la dirección del servidor API puedes usar kubectl o curl para acceder a él como se indica aquí:
Por defecto, el APISERVER se comunica con el esquema https://
si no hay
https://
en la url, puedes obtener un error como Solicitud Incorrecta.
Puedes encontrar una hoja de trucos oficial de kubectl aquí. El objetivo de las siguientes secciones es presentar de manera ordenada diferentes opciones para enumerar y comprender el nuevo K8s al que has obtenido acceso.
Para encontrar la solicitud HTTP que envía kubectl
puedes usar el parámetro -v=8
MitM kubectl - Proxyficando kubectl
Configuración Actual
Si lograste robar algunas credenciales de usuarios puedes configurarlas localmente usando algo como:
Obtener Recursos Soportados
Con esta información sabrás todos los servicios que puedes listar
Obtener Privilegios Actuales
Otra forma de verificar tus privilegios es utilizando la herramienta: https://github.com/corneliusweig/rakkess****
Puedes aprender más sobre Kubernetes RBAC en:
pageKubernetes Role-Based Access Control(RBAC)Una vez que sepas qué privilegios tienes, consulta la siguiente página para averiguar si puedes abusar de ellos para escalar privilegios:
pageAbusing Roles/ClusterRoles in KubernetesObtener otros roles
Obtener namespaces
Kubernetes soporta múltiples clusters virtuales respaldados por el mismo cluster físico. Estos clusters virtuales se llaman namespaces.
Obtener secretos
Si puedes leer secretos, puedes usar las siguientes líneas para obtener los privilegios relacionados con cada token:
Obtener Cuentas de Servicio
Como se discutió al principio de esta página, cuando se ejecuta un pod, generalmente se le asigna una cuenta de servicio. Por lo tanto, listar las cuentas de servicio, sus permisos y dónde se están ejecutando puede permitir a un usuario escalar privilegios.
Obtener Despliegues
Los despliegues especifican los componentes que necesitan ser ejecutados.
Obtener Pods
Los Pods son los contenedores que se ejecutarán.
Obtener Servicios
Los servicios de Kubernetes se utilizan para exponer un servicio en un puerto e IP específicos (que actuarán como balanceador de carga para los pods que realmente ofrecen el servicio). Esto es interesante para saber dónde puedes encontrar otros servicios para intentar atacar.
Obtener nodos
Obtén todos los nodos configurados dentro del clúster.
Obtener DaemonSets
DaemonSets permite asegurar que un pod específico esté ejecutándose en todos los nodos del clúster (o en los seleccionados). Si eliminas el DaemonSet, los pods gestionados por él también se eliminarán.
Obtener cronjob
Los cron jobs permiten programar mediante una sintaxis similar a crontab el lanzamiento de un pod que realizará alguna acción.
Obtener configMap
configMap siempre contiene mucha información y archivos de configuración que proporcionan a las aplicaciones que se ejecutan en Kubernetes. Usualmente, puedes encontrar muchas contraseñas, secretos, tokens que se utilizan para conectar y validar con otros servicios internos/externos.
Obtener "todo"
Obtener consumo de Pods
Escapando del pod
Si puedes crear nuevos pods, podrías ser capaz de escapar de ellos al nodo. Para hacerlo necesitas crear un nuevo pod usando un archivo yaml, cambiar al pod creado y luego hacer chroot en el sistema del nodo. Puedes usar pods existentes como referencia para el archivo yaml ya que muestran imágenes y rutas existentes.
si necesitas crear un pod en un nodo específico, puedes usar el siguiente comando para obtener las etiquetas en el nodo
k get nodes --show-labels
Comúnmente, kubernetes.io/hostname y node-role.kubernetes.io/master son buenas etiquetas para seleccionar.
Luego creas tu archivo attack.yaml
Ahora puedes cambiar al pod creado de la siguiente manera
Y finalmente haces chroot en el sistema del nodo
Información obtenida de: Kubernetes Namespace Breakout using Insecure Host Path Volume — Parte 1 Atacando y Defendiendo Kubernetes: Bust-A-Kube – Episodio 1
Referencias
Última actualización