diff --git a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md index 78c9d26ba..d97a50d82 100644 --- a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md +++ b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md @@ -7,12 +7,12 @@ Recuerda que puedes obtener todos los recursos soportados con `kubectl api-resou ## **Escalación de Privilegios** -Se refiere al arte de obtener **acceso a un principal diferente** dentro del clúster **con diferentes privilegios** (dentro del clúster de kubernetes o a nubes externas) que los que ya tienes. En Kubernetes, hay básicamente **4 técnicas principales para escalar privilegios**: +Se refiere al arte de obtener **acceso a un principal diferente** dentro del clúster **con diferentes privilegios** (dentro del clúster de Kubernetes o a nubes externas) que los que ya tienes. En Kubernetes, hay básicamente **4 técnicas principales para escalar privilegios**: -- Poder **suplantar** a otros usuarios/grupos/SAs con mejores privilegios dentro del clúster de kubernetes o a nubes externas -- Poder **crear/parchear/ejecutar pods** donde puedes **encontrar o adjuntar SAs** con mejores privilegios dentro del clúster de kubernetes o a nubes externas +- Poder **suplantar** a otros usuarios/grupos/SAs con mejores privilegios dentro del clúster de Kubernetes o a nubes externas +- Poder **crear/parchear/ejecutar pods** donde puedes **encontrar o adjuntar SAs** con mejores privilegios dentro del clúster de Kubernetes o a nubes externas - Poder **leer secretos** ya que los tokens de SAs se almacenan como secretos -- Poder **escapar al nodo** desde un contenedor, donde puedes robar todos los secretos de los contenedores que se ejecutan en el nodo, las credenciales del nodo y los permisos del nodo dentro de la nube en la que se está ejecutando (si hay alguna) +- Poder **escapar al nodo** desde un contenedor, donde puedes robar todos los secretos de los contenedores que se ejecutan en el nodo, las credenciales del nodo y los permisos del nodo dentro de la nube en la que se está ejecutando (si los hay) - Una quinta técnica que merece mención es la capacidad de **ejecutar port-forward** en un pod, ya que podrías acceder a recursos interesantes dentro de ese pod. ### Acceso a Cualquier Recurso o Verbo (Wildcard) @@ -72,11 +72,11 @@ serviceAccountName: bootstrap-signer automountServiceAccountToken: true hostNetwork: true ``` -### Creación y Escape de Pod +### Creación y Escape de Pods Lo siguiente indica todos los privilegios que un contenedor puede tener: -- **Acceso privilegiado** (deshabilitando protecciones y configurando capacidades) +- **Acceso privilegiado** (deshabilitando protecciones y estableciendo capacidades) - **Deshabilitar los namespaces hostIPC y hostPid** que pueden ayudar a escalar privilegios - **Deshabilitar el namespace hostNetwork**, dando acceso para robar privilegios de nube de nodos y mejor acceso a redes - **Montar hosts / dentro del contenedor** @@ -238,7 +238,7 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https:// ``` **Un laboratorio y un exploit automatizado se pueden encontrar en** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) -#### Eludir la protección de solo lectura +#### Bypass de la protección readOnly Si tienes la suerte de que la capacidad altamente privilegiada `CAP_SYS_ADMIN` está disponible, puedes simplemente volver a montar la carpeta como rw: ```bash @@ -307,7 +307,7 @@ Solo usa el parámetro `--as=` en el comando `kubectl` para suplantar kubectl get pods --as=system:serviceaccount:kube-system:default kubectl get secrets --as=null --as-group=system:masters ``` -O utiliza la API REST: +O use la API REST: ```bash curl -k -v -XGET -H "Authorization: Bearer " \ -H "Impersonate-Group: system:masters"\ @@ -382,7 +382,7 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso "type": "kubernetes.io/service-account-token" } ``` -Tenga en cuenta que si se le permite crear y leer secretos en un cierto namespace, la cuenta de servicio de la víctima también debe estar en ese mismo namespace. +Note que si se le permite crear y leer secretos en un cierto namespace, la cuenta de servicio de la víctima también debe estar en ese mismo namespace. ### Lectura de un secreto – fuerza bruta de IDs de token @@ -390,11 +390,70 @@ Mientras que un atacante en posesión de un token con permisos de lectura requie El token se genera a partir de un conjunto limitado de 27 caracteres (`bcdfghjklmnpqrstvwxz2456789`), en lugar del rango alfanumérico completo. Esta limitación reduce el total de combinaciones posibles a 14,348,907 (27^5). En consecuencia, un atacante podría ejecutar razonablemente un ataque de fuerza bruta para deducir el token en cuestión de horas, lo que podría llevar a una escalada de privilegios al acceder a cuentas de servicio sensibles. -### Solicitudes de Firma de Certificados +### EncrpytionConfiguration en texto claro -Si tiene los verbos **`create`** en el recurso `certificatesigningrequests` (o al menos en `certificatesigningrequests/nodeClient`). Puede **crear** un nuevo CeSR de un **nuevo nodo.** +Es posible encontrar claves en texto claro para cifrar datos en reposo en este tipo de objeto como: +```yaml +# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ -De acuerdo con la [documentación, es posible aprobar automáticamente estas solicitudes](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), por lo que en ese caso **no necesita permisos adicionales**. Si no, necesitaría poder aprobar la solicitud, lo que significa actualizar en `certificatesigningrequests/approval` y `approve` en `signers` con resourceName `/` o `/*` +# +# CAUTION: this is an example configuration. +# Do not use this for your own cluster! +# + +apiVersion: apiserver.config.k8s.io/v1 +kind: EncryptionConfiguration +resources: +- resources: +- secrets +- configmaps +- pandas.awesome.bears.example # a custom resource API +providers: +# This configuration does not provide data confidentiality. The first +# configured provider is specifying the "identity" mechanism, which +# stores resources as plain text. +# +- identity: {} # plain text, in other words NO encryption +- aesgcm: +keys: +- name: key1 +secret: c2VjcmV0IGlzIHNlY3VyZQ== +- name: key2 +secret: dGhpcyBpcyBwYXNzd29yZA== +- aescbc: +keys: +- name: key1 +secret: c2VjcmV0IGlzIHNlY3VyZQ== +- name: key2 +secret: dGhpcyBpcyBwYXNzd29yZA== +- secretbox: +keys: +- name: key1 +secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY= +- resources: +- events +providers: +- identity: {} # do not encrypt Events even though *.* is specified below +- resources: +- '*.apps' # wildcard match requires Kubernetes 1.27 or later +providers: +- aescbc: +keys: +- name: key2 +secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg== +- resources: +- '*.*' # wildcard match requires Kubernetes 1.27 or later +providers: +- aescbc: +keys: +- name: key3 +secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== +``` +### Certificate Signing Requests + +Si tienes el verbo **`create`** en el recurso `certificatesigningrequests` (o al menos en `certificatesigningrequests/nodeClient`). Puedes **crear** un nuevo CeSR de un **nuevo nodo.** + +Según la [documentación es posible aprobar automáticamente estas solicitudes](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), así que en ese caso **no necesitas permisos adicionales**. Si no, necesitarías poder aprobar la solicitud, lo que significa actualizar en `certificatesigningrequests/approval` y `approve` en `signers` con resourceName `/` o `/*` Un **ejemplo de un rol** con todos los permisos requeridos es: ```yaml @@ -429,7 +488,7 @@ verbs: ``` Entonces, con el nuevo CSR de nodo aprobado, puedes **abusar** de los permisos especiales de los nodos para **robar secretos** y **escalar privilegios**. -En [**esta publicación**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) y [**esta otra**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/), la configuración de GKE K8s TLS Bootstrap está configurada con **firma automática** y se abusa de ella para generar credenciales de un nuevo nodo K8s y luego abusar de esas para escalar privilegios robando secretos.\ +En [**esta publicación**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) y [**esta otra**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/), la configuración de GKE K8s TLS Bootstrap está configurada con **firma automática** y se abusa para generar credenciales de un nuevo nodo K8s y luego abusar de ellas para escalar privilegios robando secretos.\ Si **tienes los privilegios mencionados, podrías hacer lo mismo**. Ten en cuenta que el primer ejemplo elude el error que impide que un nuevo nodo acceda a secretos dentro de contenedores porque un **nodo solo puede acceder a los secretos de los contenedores montados en él.** La forma de eludir esto es simplemente **crear credenciales de nodo para el nombre del nodo donde el contenedor con los secretos interesantes está montado** (pero solo verifica cómo hacerlo en la primera publicación): @@ -438,7 +497,7 @@ La forma de eludir esto es simplemente **crear credenciales de nodo para el nomb ``` ### AWS EKS aws-auth configmaps -Los principales que pueden modificar **`configmaps`** en el espacio de nombres kube-system en clústeres EKS (necesitan estar en AWS) pueden obtener privilegios de administrador del clúster al sobrescribir el configmap **aws-auth**.\ +Los principales que pueden modificar **`configmaps`** en el espacio de nombres kube-system en clústeres EKS (deben estar en AWS) pueden obtener privilegios de administrador del clúster al sobrescribir el configmap **aws-auth**.\ Los verbos necesarios son **`update`** y **`patch`**, o **`create`** si el configmap no fue creado: ```bash # Check if config map exists @@ -490,7 +549,7 @@ Si tienes los permisos para modificar el **`coredns` configmap** en el espacio d Los verbos necesarios son **`update`** y **`patch`** sobre el **`coredns`** configmap (o todos los config maps). -Un **archivo coredns** regular contiene algo como esto: +Un archivo **coredns** regular contiene algo como esto: ```yaml data: Corefile: | @@ -561,7 +620,7 @@ Entonces puede actualizar/crear nuevos roles, clusterroles con mejores permisos ### Proxy de nodos -Principales con acceso al **`nodes/proxy`** subrecurso pueden **ejecutar código en pods** a través de la API de Kubelet (según [**esto**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Más información sobre la autenticación de Kubelet en esta página: +Principales con acceso al subrecurso **`nodes/proxy`** pueden **ejecutar código en pods** a través de la API de Kubelet (según [**esto**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)). Más información sobre la autenticación de Kubelet en esta página: {{#ref}} ../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md @@ -571,7 +630,7 @@ Tienes un ejemplo de cómo obtener [**RCE hablando autorizado a una API de Kubel ### Eliminar pods + nodos no programables -Principales que pueden **eliminar pods** (`delete` verbo sobre `pods` recurso), o **desalojar pods** (`create` verbo sobre `pods/eviction` recurso), o **cambiar el estado del pod** (acceso a `pods/status`) y pueden **hacer que otros nodos no sean programables** (acceso a `nodes/status`) o **eliminar nodos** (`delete` verbo sobre `nodes` recurso) y tienen control sobre un pod, podrían **robar pods de otros nodos** para que sean **ejecutados** en el **nodo comprometido** y el atacante pueda **robar los tokens** de esos pods. +Principales que pueden **eliminar pods** (verbo `delete` sobre el recurso `pods`), o **desalojar pods** (verbo `create` sobre el recurso `pods/eviction`), o **cambiar el estado del pod** (acceso a `pods/status`) y pueden **hacer que otros nodos no sean programables** (acceso a `nodes/status`) o **eliminar nodos** (verbo `delete` sobre el recurso `nodes`) y tienen control sobre un pod, podrían **robar pods de otros nodos** para que sean **ejecutados** en el **nodo comprometido** y el atacante pueda **robar los tokens** de esos pods. ```bash patch_node_capacity(){ curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]' @@ -586,13 +645,13 @@ kubectl delete pods -n kube-system Los principales que pueden **modificar** **`services/status`** pueden establecer el campo `status.loadBalancer.ingress.ip` para explotar el **CVE-2020-8554 sin corregir** y lanzar **ataques MiTM contra el clúster**. La mayoría de las mitigaciones para CVE-2020-8554 solo previenen servicios ExternalIP (según [**esto**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). -### Estado de nodos y pods +### Estado de los nodos y pods Los principales con permisos de **`update`** o **`patch`** sobre `nodes/status` o `pods/status`, podrían modificar etiquetas para afectar las restricciones de programación impuestas. -## Prevención de escalación de privilegios incorporada +## Prevención de escalada de privilegios incorporada -Kubernetes tiene un [mecanismo incorporado](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) para prevenir la escalación de privilegios. +Kubernetes tiene un [mecanismo incorporado](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) para prevenir la escalada de privilegios. Este sistema asegura que **los usuarios no pueden elevar sus privilegios modificando roles o vinculaciones de roles**. La aplicación de esta regla ocurre a nivel de API, proporcionando una salvaguarda incluso cuando el autorizador RBAC está inactivo. @@ -604,15 +663,15 @@ La regla estipula que un **usuario solo puede crear o actualizar un rol si posee ### **Obtener y parchear RoleBindings/ClusterRoleBindings** > [!CAUTION] -> **Aparentemente, esta técnica funcionó antes, pero según mis pruebas, ya no está funcionando por la misma razón explicada en la sección anterior. No puedes crear/modificar un rolebinding para darte a ti mismo o a una SA diferente algunos privilegios si no los tienes ya.** +> **Aparentemente, esta técnica funcionaba antes, pero según mis pruebas, ya no está funcionando por la misma razón explicada en la sección anterior. No puedes crear/modificar un rolebinding para darte a ti mismo o a una SA diferente algunos privilegios si no los tienes ya.** -El privilegio de crear Rolebindings permite a un usuario **vincular roles a una cuenta de servicio**. Este privilegio puede llevar potencialmente a la escalación de privilegios porque **permite al usuario vincular privilegios de administrador a una cuenta de servicio comprometida.** +El privilegio de crear Rolebindings permite a un usuario **vincular roles a una cuenta de servicio**. Este privilegio puede llevar potencialmente a la escalada de privilegios porque **permite al usuario vincular privilegios de administrador a una cuenta de servicio comprometida.** ## Otros ataques ### Aplicación de proxy sidecar -Por defecto, no hay ninguna encriptación en la comunicación entre pods. Autenticación mutua, bidireccional, pod a pod. +Por defecto, no hay ninguna encriptación en la comunicación entre pods. Autenticación mutua, bidireccional, de pod a pod. #### Crear una aplicación de proxy sidecar diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md index b2fe51717..de7ff2e60 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md @@ -4,16 +4,16 @@ ## 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 namespace. 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. +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, por lo que la conectividad predeterminada en Kubernetes en esta capa plantea preocupaciones de seguridad. +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 namespace predeterminado -- **ubuntu-victim**: Máquina **víctima** en el namespace kube-system -- **mysql**: Máquina **víctima** en el namespace predeterminado +- **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 ```yaml echo 'apiVersion: v1 kind: Pod @@ -154,7 +154,7 @@ Por lo tanto, el pod enviará las **solicitudes DNS a la dirección 10.96.0.10** > > 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. -## Suplantación ARP en pods en el mismo Nodo +## ARP Spoofing en pods en el mismo Nodo Nuestro objetivo es **robar al menos la comunicación del ubuntu-victim al mysql**. @@ -237,7 +237,7 @@ Como ya se mencionó, si **comprometes un pod en el mismo nodo del pod del servi Tienes una muy buena **herramienta** y **tutorial** para probar esto en [**https://github.com/danielsagi/kube-dnsspoof/**](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: +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 @@ -260,13 +260,45 @@ dig google.com 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 **IP de origen** la dirección IP del **pod** **malicioso** y **no será** **aceptada**.\ -> Necesitas generar un **nuevo paquete DNS** con la **IP de origen** 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). +> 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: +```bash +kubectl get networkpolicies --all-namespaces +``` +Obtener políticas de red de **Callico**: +```bash +kubectl get globalnetworkpolicy --all-namespaces +``` +Obtener políticas de red de **Cillium**: +```bash +kubectl get ciliumnetworkpolicy --all-namespaces +``` +Obtén otros CRDs relacionados con políticas instalados por tu complemento de red o solución de seguridad: +```bash +kubectl get crd | grep -i policy +``` ## Capturando Tráfico La herramienta [**Mizu**](https://github.com/up9inc/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 y te la mostrará en un servidor web. Sin embargo, necesitarás altos permisos de K8s para esto (y no es muy sigiloso). +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