Practical Security inside a Dockerized Network

Imagine you have a bash shell in a machine but you realize it’s a docker container. How would you proceed to go deeper?

Step 1. Understand your container

Usually you won’t be able to use 0-days against the kernel but you won’t find extra security measures either (expect when running a non-root user). Vectors attacks or methodologies haven’t changed at all but this context is a bit special.

You are in a container which can disappear at any moment. It’s probably stateless and has a single responsibility. The operative system is quite safe by default because it uses minimum capacities to operate. Forget to leave a bind shell (or reverse) and come back later. They only need to patch, build, push, pull and deploy. Maybe 10 minutes? Time runs against you.

As soon as you obtain a bash shell (somehow), you must reverse the definition of this container. There are 2 elements to guess:

Dockerfile: Instructions writes files, so you only need to diff against the original image. Even there is a public registry, using a basic image (ex. busybox, ubuntu, debian, fedora, …) could be enough.

$ find / -type f ! -path "/sys*" ! -path "/proc*" -exec md5sum {} +

docker arguments: These are the keys for pivoting. Try to rebuild the original “docker run …” execution line.

Volumes $ mount
$ df
Links $ net ip
$ cat /etc/hosts
Environment (+ports) $ env

STEP 2. Find the weakest point

The most common vulnerability, now and forever, will be default and wrong configurations: human mistakes. Understand the platform and try to extract sensitive data using the designed flow. Probably it’s so lose that you will be able to dump the full database.

I have seen several docker related projects use this line:

$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu

(or as a Host:Port with or without SSL). Install socat for connecting to the sock:

$ apt-get install socat
$ socat TCP4-LISTEN:1337,fork UNIX-CONNECT:/var/run/docker.sock &

Then, read the doc: https://docs.docker.com/reference/api/. You have several options. For example, you could export another containers as raw data or create a new container mounting the root directory as a folder. You can successfully compromise the full machine in this scenario and most importantly you will have a lot of critical information to use against the internal network.

Another far more complex vector is to take advantage of ephemeral processes that can be running in our compromised machine and open new vulnerabilities into another machines. For example, a Jenkins uses our compromised development machine to build and push a new image into the registry. You can use tools like `inotify`, detect this process, and if there is a shared volume (data-pattern), change the code before it’s pushed.

STEP 3. Complementary software

In real production environments it is not common to execute raw docker commands for starting processes. These tools are quickly identified as they don’t expect you there.

Docker-compose sets as environment variables all the linked containers with their ports. However, tools like this are going to be hell for an intruder. It’s pretty easy to set volumes as read-only, limit cpu, memory, etc.

Supervisord is a process control system which will work as pid 1 and manage the sub-processes in that container. If you are so lucky to have enough access you will find the logs of all running applications in /var/log/supervisor/ . In the case that the app was running directly as a command/entry-point I think you cannot obtain this information.

Docker-registry is a private repository and is without a doubt your goal. Maybe you can scan the whole internal network searching the default port 5000 open, or you can try to guess their backend (s3?) and retrieve the images, or you can access to the Redis instance used as cache, etc. The registry doesn’t provide directly Auth. It has to be provided by extra tools (nginx, ..) or what is called Index Auth service. So if you find the HTTP/s API, start with GET /v1/search and dump everything. You will also be able to push something.

An example of what I’m talking about: http://blog.programster.org/2015/03/17/run-your-own-private-docker-registry/ . It’s protected from outside (SSL + firewall) but once you are in one container you have free access to any image.

Consul provides information about domain resolution and a key/value storage. It has a security model for MITM and other attacks, but also an ACL feature. However, ACL are disabled by default. (It’s another great tool that needs to be mentioned)

There are a bunch of new tools appearing which use docker to optimize a specific kind of task. They use to have some kind of security in mind but must be enabled and properly configured. Quick and dirty feature development, not enough QA work, using beta or alpha version, etc are the keys for finding a bogus system.

bonus. Denial of Service

If you want to directly crash the machine (which uses more than your container), probably the easier option is:

$ dd if=/dev/zero of=/fileOrPartition (or /mounted_volume_file)

Docker is able to limit the resources of the CPU, Memory, SWAP, … but it still doesn’t let you limit the harddrive. Probably you are able to get it full and something will crash.

Conclusion

This article was quite simple but I don’t like when people talks about the security in docker from only a theoretical viewpoint. Hope you enjoyed it. (And yes, to obtain a shell in a container is NOT trivial).

More advice here: https://github.com/GDSSecurity/Docker-Secure-Deployment-Guidelines

Practical Security inside a Dockerized Network

Challenges

Desde siempre me han gustado los retos.

Empecé en http://hispabyte.net/ realizando lo más básico en el foro (Gracias @Cabrero1964)… Viví Boinas negras e Izhal… Continué con algunos más completos como http://www.hackthissite.org/… Colaboré en algunos mucho más currados como http://yoire.com/… Rompí mi cabeza en sitios como http://bright-shadows.net/ (Gracias @Phas, con quien intenté elaborar un sitio de retos)… y finalmente se me han pasado muchisimos otros, como los de SecurityByDefault, otros del Maligno, etc, etc, etc (no recuerdo el nombre de los que van por terminal… pero han sido siempre muy interesantes). Aún así, superé 0 retos en la última DEFCON CTF (olé!).

Estos últimos días estoy dedicando bastante tiempo a un nuevo site… http://securitytraps.no-ip.pl (Gracias al equipo Activalink http://blog.activalink.org/ (¡que buenos son los cabroncetes!)).

Lo que más me ha impacto respecto a muchos de los otros retos vividos es lo que llegas a aprender. A diferencia del resto de retos, los cuales son pasables sólo si tienes una idea feliz, es que estos son bastante sencillos y simples, pero necesitas ENTENDER y optimizar lo que estas haciendo. La mayoria de pruebas son con el código fuente y el objetivo es conseguir la excepción de ese pedazito de código.

A mi me ha enseñado a ser más paciente y persistente los retos más jodidos, yendo pasito a pasito, y finalmente, poder decir que has aprendido cosas nuevas. Es cuestión de leer bien, localizar los conceptos clave, y buscar información hasta entender perfectamente que esta sucediendo. Sí, es un RTFM bien grande. (RTFM=Read The Fuck Manual)

Lamentablemente, hacer retos, tener 2 papers que terminar, un servidor que configurar, y muchas más cosas que aprender no se puede hacer en un verano entero. ¡Espero postear mejores aportaciones la próxima! 🙂 ¡Sed pacientes!

Challenges