AuthZ& AuthN - Docker Access Authorization Plugin
El modelo de autorización de Docker fuera de la caja es todo o nada. Cualquier usuario con permiso para acceder al daemon de Docker puede ejecutar cualquier comando del cliente de Docker. Lo mismo es cierto para los llamadores que utilizan la API del Engine de Docker para contactar al daemon. Si necesitas un mayor control de acceso, puedes crear plugins de autorización y agregarlos a la configuración de tu daemon de Docker. Usando un plugin de autorización, un administrador de Docker puede configurar políticas de acceso granulares para gestionar el acceso al daemon de Docker.
Arquitectura básica
Los plugins de autenticación de Docker son plugins externos que puedes usar para permitir/denegar acciones solicitadas al daemon de Docker dependiendo del usuario que la solicitó y de la acción solicitada.
La siguiente información es de la documentación
Cuando se realiza una solicitud HTTP al daemon de Docker a través de la CLI o mediante la API del Engine, el sub-sistema de autenticación pasa la solicitud a los plugins de autenticación instalados. La solicitud contiene el usuario (llamador) y el contexto del comando. El plugin es responsable de decidir si permitir o denegar la solicitud.
Los diagramas de secuencia a continuación representan un flujo de autorización de permitir y denegar:
Cada solicitud enviada al plugin incluye el usuario autenticado, los encabezados HTTP y el cuerpo de la solicitud/respuesta. Solo se pasan al plugin el nombre de usuario y el método de autenticación utilizado. Lo más importante, no se pasan credenciales o tokens de usuario. Finalmente, no todos los cuerpos de solicitud/respuesta se envían al plugin de autorización. Solo se envían aquellos cuerpos de solicitud/respuesta donde el Content-Type
es text/*
o application/json
.
Para comandos que pueden potencialmente secuestrar la conexión HTTP (HTTP Upgrade
), como exec
, el plugin de autorización solo se llama para las solicitudes HTTP iniciales. Una vez que el plugin aprueba el comando, la autorización no se aplica al resto del flujo. Específicamente, los datos de transmisión no se pasan a los plugins de autorización. Para comandos que devuelven respuestas HTTP en fragmentos, como logs
y events
, solo se envía la solicitud HTTP a los plugins de autorización.
Durante el procesamiento de solicitudes/respuestas, algunos flujos de autorización pueden necesitar realizar consultas adicionales al daemon de Docker. Para completar tales flujos, los plugins pueden llamar a la API del daemon de manera similar a un usuario regular. Para habilitar estas consultas adicionales, el plugin debe proporcionar los medios para que un administrador configure políticas de autenticación y seguridad adecuadas.
Varios Plugins
Eres responsable de registrar tu plugin como parte del inicio del daemon de Docker. Puedes instalar múltiples plugins y encadenarlos. Esta cadena puede ser ordenada. Cada solicitud al daemon pasa en orden a través de la cadena. Solo cuando todos los plugins otorgan acceso al recurso, se concede el acceso.
Ejemplos de Plugins
Twistlock AuthZ Broker
El plugin authz te permite crear un archivo JSON simple que el plugin estará leyendo para autorizar las solicitudes. Por lo tanto, te da la oportunidad de controlar muy fácilmente qué endpoints de API pueden alcanzar a cada usuario.
Este es un ejemplo que permitirá a Alice y Bob crear nuevos contenedores: {"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}
En la página route_parser.go puedes encontrar la relación entre la URL solicitada y la acción. En la página types.go puedes encontrar la relación entre el nombre de la acción y la acción.
Tutorial de Plugin Simple
Puedes encontrar un plugin fácil de entender con información detallada sobre instalación y depuración aquí: https://github.com/carlospolop-forks/authobot
Lee el README
y el código de plugin.go
para entender cómo funciona.
Bypass del Plugin de Autenticación de Docker
Enumerar acceso
Las principales cosas a verificar son qué endpoints están permitidos y qué valores de HostConfig están permitidos.
Para realizar esta enumeración puedes usar la herramienta https://github.com/carlospolop/docker_auth_profiler.
run --privileged
no permitido
run --privileged
no permitidoPrivilegios Mínimos
Ejecutando un contenedor y luego obteniendo una sesión privilegiada
En este caso, el sysadmin no permitió a los usuarios montar volúmenes y ejecutar contenedores con la bandera --privileged
o dar cualquier capacidad extra al contenedor:
Sin embargo, un usuario puede crear un shell dentro del contenedor en ejecución y darle los privilegios adicionales:
Ahora, el usuario puede escapar del contenedor utilizando cualquiera de las técnicas discutidas anteriormente y escalar privilegios dentro del host.
Montar Carpeta Escribible
En este caso, el sysadmin no permitió a los usuarios ejecutar contenedores con la bandera --privileged
ni otorgar ninguna capacidad extra al contenedor, y solo permitió montar la carpeta /tmp
:
Nota que tal vez no puedas montar la carpeta /tmp
, pero puedes montar una carpeta escribible diferente. Puedes encontrar directorios escribibles usando: find / -writable -type d 2>/dev/null
¡Nota que no todos los directorios en una máquina linux soportarán el bit suid! Para verificar qué directorios soportan el bit suid, ejecuta mount | grep -v "nosuid"
Por ejemplo, generalmente /dev/shm
, /run
, /proc
, /sys/fs/cgroup
y /var/lib/lxcfs
no soportan el bit suid.
Nota también que si puedes montar /etc
o cualquier otra carpeta que contenga archivos de configuración, puedes cambiarlos desde el contenedor de docker como root para abusar de ellos en el host y escalar privilegios (tal vez modificando /etc/shadow
)
Endpoint API No Verificado
La responsabilidad del sysadmin que configura este plugin sería controlar qué acciones y con qué privilegios cada usuario puede realizar. Por lo tanto, si el administrador adopta un enfoque de lista negra con los endpoints y los atributos, podría olvidar algunos de ellos que podrían permitir a un atacante escalar privilegios.
Puedes consultar la API de docker en https://docs.docker.com/engine/api/v1.40/#
Estructura JSON No Verificada
Montajes en root
Es posible que cuando el sysadmin configuró el firewall de docker, olvidó algún parámetro importante de la API como "Binds". En el siguiente ejemplo, es posible abusar de esta mala configuración para crear y ejecutar un contenedor que monta la carpeta raíz (/) del host:
Nota cómo en este ejemplo estamos usando el parámetro Binds
como una clave de nivel raíz en el JSON, pero en la API aparece bajo la clave HostConfig
Binds en HostConfig
Sigue la misma instrucción que con Binds en raíz realizando esta solicitud a la API de Docker:
Mounts en root
Siga las mismas instrucciones que con Binds en root realizando esta solicitud a la API de Docker:
Mounts en HostConfig
Siga las mismas instrucciones que con Binds en root realizando esta solicitud a la API de Docker:
Atributo JSON No Verificado
Es posible que cuando el sysadmin configuró el firewall de docker se olvidó de algún atributo importante de un parámetro de la API como "Capabilities" dentro de "HostConfig". En el siguiente ejemplo es posible abusar de esta mala configuración para crear y ejecutar un contenedor con la capacidad SYS_MODULE:
El HostConfig
es la clave que generalmente contiene los privilegios interesantes para escapar del contenedor. Sin embargo, como hemos discutido anteriormente, ten en cuenta que usar Binds fuera de él también funciona y puede permitirte eludir restricciones.
Deshabilitando el Plugin
Si el sysadmin olvidó prohibir la capacidad de deshabilitar el plugin, ¡puedes aprovechar esto para deshabilitarlo completamente!
Recuerda volver a habilitar el plugin después de escalar, o un reinicio del servicio de docker no funcionará!
Informes de Bypass del Plugin de Autenticación
Last updated