Docker Breakout / Privilege Escalation
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)
Use Trickest para construir y automatizar flujos de trabajo fácilmente, impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
linpeas: También puede enumerar contenedores
CDK: Esta herramienta es bastante útil para enumerar el contenedor en el que estás e incluso intentar escapar automáticamente
amicontained: Herramienta útil para obtener los privilegios que tiene el contenedor con el fin de encontrar formas de escapar de él
deepce: Herramienta para enumerar y escapar de contenedores
grype: Obtén los CVEs contenidos en el software instalado en la imagen
Si de alguna manera encuentras que el socket de docker está montado dentro del contenedor de docker, podrás escapar de él. Esto suele ocurrir en contenedores de docker que por alguna razón necesitan conectarse al demonio de docker para realizar acciones.
En este caso, puedes usar comandos de docker regulares para comunicarte con el daemon de docker:
En caso de que el socket de docker esté en un lugar inesperado, aún puedes comunicarte con él usando el docker
comando con el parámetro -H unix:///path/to/docker.sock
El daemon de Docker también podría estar escuchando en un puerto (por defecto 2375, 2376) o en sistemas basados en Systemd, la comunicación con el daemon de Docker puede ocurrir a través del socket de Systemd fd://
.
Además, presta atención a los sockets de tiempo de ejecución de otros runtimes de alto nivel:
dockershim: unix:///var/run/dockershim.sock
containerd: unix:///run/containerd/containerd.sock
cri-o: unix:///var/run/crio/crio.sock
frakti: unix:///var/run/frakti.sock
rktlet: unix:///var/run/rktlet.sock
...
Debes verificar las capacidades del contenedor, si tiene alguna de las siguientes, podrías ser capaz de escapar de él: CAP_SYS_ADMIN
, CAP_SYS_PTRACE
, CAP_SYS_MODULE
, DAC_READ_SEARCH
, DAC_OVERRIDE, CAP_SYS_RAWIO
, CAP_SYSLOG
, CAP_NET_RAW
, CAP_NET_ADMIN
Puedes verificar las capacidades actuales del contenedor usando herramientas automáticas mencionadas anteriormente o:
En la siguiente página puedes aprender más sobre las capacidades de linux y cómo abusar de ellas para escapar/escalar privilegios:
Linux CapabilitiesUn contenedor privilegiado puede ser creado con la bandera --privileged
o deshabilitando defensas específicas:
--cap-add=ALL
--security-opt apparmor=unconfined
--security-opt seccomp=unconfined
--security-opt label:disable
--pid=host
--userns=host
--uts=host
--cgroupns=host
Montar /dev
La bandera --privileged
reduce significativamente la seguridad del contenedor, ofreciendo acceso irrestricto a dispositivos y eludiendo varias protecciones. Para un desglose detallado, consulta la documentación sobre los impactos completos de --privileged
.
Con estos permisos puedes simplemente moverte al espacio de nombres de un proceso que se ejecuta en el host como root como init (pid:1) solo ejecutando: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Prueba esto en un contenedor ejecutando:
Solo con la bandera privilegiada puedes intentar acceder al disco del host o intentar escapar abusando de release_agent u otras escapatorias.
Prueba los siguientes bypasses en un contenedor ejecutando:
Los contenedores de docker bien configurados no permitirán comandos como fdisk -l. Sin embargo, en comandos de docker mal configurados donde se especifica la bandera --privileged
o --device=/dev/sda1
con mayúsculas, es posible obtener los privilegios para ver la unidad del host.
Así que para tomar el control de la máquina host, es trivial:
Y voilà ! Ahora puedes acceder al sistema de archivos del host porque está montado en la carpeta /mnt/hola
.
Dentro del contenedor, un atacante puede intentar obtener un acceso adicional al sistema operativo subyacente del host a través de un volumen hostPath escribible creado por el clúster. A continuación se presentan algunas cosas comunes que puedes verificar dentro del contenedor para ver si puedes aprovechar este vector de ataque:
Encuentra una explicación de la técnica en:
Docker release_agent cgroups escapeEn los exploits anteriores, se divulga la ruta absoluta del contenedor dentro del sistema de archivos del host. Sin embargo, este no siempre es el caso. En casos donde no conoces la ruta absoluta del contenedor dentro del host, puedes usar esta técnica:
release_agent exploit - Relative Paths to PIDsEjecutar el PoC dentro de un contenedor privilegiado debería proporcionar una salida similar a:
Hay varios archivos que pueden estar montados que dan información sobre el host subyacente. Algunos de ellos pueden incluso indicar algo que debe ser ejecutado por el host cuando sucede algo (lo que permitirá a un atacante escapar del contenedor). El abuso de estos archivos puede permitir que:
release_agent (ya cubierto antes)
Sin embargo, puedes encontrar otros archivos sensibles para verificar en esta página:
Sensitive MountsEn varias ocasiones encontrarás que el contenedor tiene algún volumen montado desde el host. Si este volumen no fue configurado correctamente, podrías ser capaz de acceder/modificar datos sensibles: Leer secretos, cambiar ssh authorized_keys…
Si tienes acceso como root dentro de un contenedor que tiene alguna carpeta del host montada y has escapado como un usuario no privilegiado al host y tienes acceso de lectura sobre la carpeta montada. Puedes crear un archivo suid de bash en la carpeta montada dentro del contenedor y ejecutarlo desde el host para escalar privilegios.
Si tienes acceso como root dentro de un contenedor y has escapado como un usuario no privilegiado al host, puedes abusar de ambas shells para privesc dentro del host si tienes la capacidad MKNOD dentro del contenedor (es por defecto) como se explica en este post. Con tal capacidad, el usuario root dentro del contenedor puede crear archivos de dispositivos de bloque. Los archivos de dispositivos son archivos especiales que se utilizan para acceder al hardware subyacente y a los módulos del kernel. Por ejemplo, el archivo de dispositivo de bloque /dev/sda da acceso a leer los datos en bruto en el disco del sistema.
Docker protege contra el uso indebido de dispositivos de bloque dentro de los contenedores al hacer cumplir una política de cgroup que bloquea las operaciones de lectura/escritura de dispositivos de bloque. Sin embargo, si un dispositivo de bloque es creado dentro del contenedor, se vuelve accesible desde fuera del contenedor a través del directorio /proc/PID/root/. Este acceso requiere que el propietario del proceso sea el mismo tanto dentro como fuera del contenedor.
Ejemplo de explotación de este escrito:
Si puedes acceder a los procesos del host, podrás acceder a mucha información sensible almacenada en esos procesos. Ejecuta el laboratorio de pruebas:
Por ejemplo, podrás listar los procesos usando algo como ps auxn
y buscar detalles sensibles en los comandos.
Luego, como puedes acceder a cada proceso del host en /proc/ simplemente puedes robar sus secretos de entorno ejecutando:
También puedes acceder a los descriptores de archivo de otros procesos y leer sus archivos abiertos:
Puedes también matar procesos y causar un DoS.
Si de alguna manera tienes acceso privilegiado sobre un proceso fuera del contenedor, podrías ejecutar algo como nsenter --target <pid> --all
o nsenter --target <pid> --mount --net --pid --cgroup
para ejecutar un shell con las mismas restricciones de ns (esperemos que ninguna) que ese proceso.
Si un contenedor fue configurado con el controlador de red de Docker host networking driver (--network=host
), la pila de red de ese contenedor no está aislada del host de Docker (el contenedor comparte el espacio de nombres de red del host), y el contenedor no recibe su propia dirección IP asignada. En otras palabras, el contenedor vincula todos los servicios directamente a la IP del host. Además, el contenedor puede interceptar TODO el tráfico de red que el host está enviando y recibiendo en la interfaz compartida tcpdump -i eth0
.
Por ejemplo, puedes usar esto para esnifar e incluso suplantar tráfico entre el host y la instancia de metadatos.
Como en los siguientes ejemplos:
También podrás acceder a servicios de red vinculados a localhost dentro del host o incluso acceder a los permisos de metadatos del nodo (que pueden ser diferentes a los que un contenedor puede acceder).
Con hostIPC=true
, obtienes acceso a los recursos de comunicación entre procesos (IPC) del host, como memoria compartida en /dev/shm
. Esto permite leer/escribir donde los mismos recursos IPC son utilizados por otros procesos del host o del pod. Usa ipcs
para inspeccionar estos mecanismos IPC más a fondo.
Inspeccionar /dev/shm - Busca archivos en esta ubicación de memoria compartida: ls -la /dev/shm
Inspeccionar instalaciones IPC existentes – Puedes verificar si se están utilizando instalaciones IPC con /usr/bin/ipcs
. Verifícalo con: ipcs -a
Si la syscall unshare
no está prohibida, puedes recuperar todas las capacidades ejecutando:
La segunda técnica explicada en la publicación https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ indica cómo puedes abusar de los montajes vinculados con espacios de nombres de usuario, para afectar archivos dentro del host (en ese caso específico, eliminar archivos).
Usa Trickest para construir y automatizar flujos de trabajo fácilmente impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
En caso de que puedas ejecutar docker exec
como root (probablemente con sudo), intenta escalar privilegios escapando de un contenedor abusando de CVE-2019-5736 (exploit aquí). Esta técnica básicamente sobrescribirá el /bin/sh binario del host desde un contenedor, por lo que cualquier persona que ejecute docker exec puede activar la carga útil.
Cambia la carga útil en consecuencia y construye el main.go con go build main.go
. El binario resultante debe colocarse en el contenedor de docker para su ejecución.
Al ejecutarlo, tan pronto como muestre [+] Overwritten /bin/sh successfully
, necesitas ejecutar lo siguiente desde la máquina host:
docker exec -it <container-name> /bin/sh
Esto activará la carga útil que está presente en el archivo main.go.
Para más información: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Hay otras CVEs a las que el contenedor puede ser vulnerable, puedes encontrar una lista en https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list
Espacios de nombres: El proceso debe estar completamente separado de otros procesos a través de espacios de nombres, por lo que no podemos escapar interactuando con otros procesos debido a los espacios de nombres (por defecto no pueden comunicarse a través de IPCs, sockets unix, servicios de red, D-Bus, /proc
de otros procesos).
Usuario root: Por defecto, el usuario que ejecuta el proceso es el usuario root (sin embargo, sus privilegios son limitados).
Capacidades: Docker deja las siguientes capacidades: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
Syscalls: Estas son las syscalls que el usuario root no podrá llamar (debido a la falta de capacidades + Seccomp). Las otras syscalls podrían usarse para intentar escapar.
If you are in userspace (no kernel exploit involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
Find the path of the containers filesystem inside the host
You can do this via mount, or via brute-force PIDs as explained in the second release_agent exploit
Find some functionality where you can indicate the path of a script to be executed by a host process (helper) if something happens
You should be able to execute the trigger from inside the host
You need to know where the containers files are located inside the host to indicate a script you write inside the host
Have enough capabilities and disabled protections to be able to abuse that functionality
You might need to mount things o perform special privileged actions you cannot do in a default docker container
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)