Exposed Docker Daemon

Exposed Docker Daemon

A Docker daemon answering on the network without TLS is remote root on the host. Take a machine through the exposed API, then lock it down with TLS, client certificates, and a scoped socket proxy.

What Is Exposed Docker Daemon?

The Docker API is root-equivalent and ships with no authentication. A daemon bound to a network port without TLS lets anyone who can reach it start containers, mount the host, and read anything on the machine. Mounting the daemon socket into a container hands that container the same power. This exercise covers both: watch an attacker take a host through an exposed daemon, then lock it down with TLS, client certificates, and a scoped socket proxy.

What You'll Learn in Exposed Docker Daemon

Exposed Docker Daemon — Training Steps

  1. Reading the public status page

    Bob is not inside anything. He is on his own laptop, reading Palliston's public operations page. It is meant to reassure customers that the platform is healthy, and in doing so it names the production nodes, their public IPs, and the Docker engine each one runs. Take a look at what it exposes before Bob puts it to use.

  2. The line that says too much

    It only takes one line. A production node's public IP and the fact that it runs Docker are all Bob needs to try the cheapest attack there is.

  3. Knock on the daemon

    The Docker daemon can be told to listen on a network port instead of only the local socket. When it is, and TLS is off, it answers anyone. Bob points his own Docker CLI at that node's port 2375 and asks it the most harmless question there is: what version are you. If it answers, the game is already over.

  4. Read the production fleet

    The Docker API is not a narrow thing. It lists, starts, stops, and builds containers, and it does all of it as root. Bob's first move with it is simply to look: what is this host actually running.

  5. Mount the host, take the secrets

    Bob does not need to break into the running containers. The daemon will start a brand new one for him, and it will mount whatever he asks it to. He asks for the host's entire root filesystem at /host, then reads the production environment file straight through the mount. The container is his. The host is under it. There was never a wall between them.

  6. What made this possible

    One beat on the mechanism before the response begins.

  7. The daemon logs a stranger

    Palliston ships its Docker daemon logs to a central collector. It does not take an intrusion-detection product to notice what turned up: API calls to the daemon on ops-node-01, from an IP that belongs to no one at Palliston.

  8. Confirm the door is open

    Before changing anything, Alice reproduces what the logs describe. If an unauthenticated version probe from her own machine answers, the daemon is exposed exactly as Priya feared.

  9. Open the daemon config

    The daemon's behaviour is set in one file, /etc/docker/daemon.json. Whatever told it to listen on the network without TLS is a line in here.

  10. Find what opened the port

    Two settings, side by side, are the entire exposure. One puts the API on the network; the other tells it not to check who is calling.