Docker Security Exploits: Real Attack Paths, Practical Defenses, and What to Monitor By CyberDudeBivash — Founder, CyberDudeBivash | Cybersecurity & AI

Executive summary

Most “Docker hacks” are not kernel 0-days—they’re misconfiguration, exposed daemons, over-privileged containers, and poisoned images. When attackers win, they usually:

  1. hit an exposed Docker API,
  2. abuse a mounted Docker socket,
  3. exploit --privileged / capabilities / unsafe mounts, or
  4. leverage a malicious image/supply-chain.
    This article maps each exploit class, shows how compromises unfold, and gives copy-paste hardening, detections, and IR playbooks you can apply today.

1) Threat model & attack surface

Docker stack: image → containerd → runc → kernel; host exposes dockerd (optionally on TCP); containers talk via docker0 bridge / user-defined networks; volumes bind host paths.

High-risk boundaries

  • Docker API (/var/run/docker.sock, TCP 2375 no-TLS, 2376 TLS).
  • Host filesystem mounts (-v /:/hosthostPath in K8s).
  • Privileges/Capabilities (--privilegedCAP_SYS_ADMINSYS_MODULE, etc.).
  • Supply chain (public registries, mutable tags, CI/CD tokens).
  • Runtime bugs (runc/containerd), less common but high impact.

2) Exploit classes & how they work

A) Exposed Docker daemon (TCP 2375/2376)

Exploit: unauthenticated 2375 or weak-TLS 2376 → attacker runs:

bashCopyEditdocker -H tcp://victim:2375 run --privileged -v /:/host alpine chroot /host /bin/sh

Impact: host root, persistence (SSH keys, systemd units), crypto-mining, lateral movement.

B) Docker socket mount inside a container

Mounting /var/run/docker.sock makes the container root-equivalent on the host:

bashCopyEdit# from inside the compromised container:
docker run --privileged -v /:/host alpine chroot /host /bin/sh

Typical path: “helper sidecar” gets popped → attacker spawns sibling container with host mount → full host.

C) Over-privileged containers & capabilities

  • --privileged disables most isolation.
  • Dangerous caps: CAP_SYS_ADMINSYS_MODULESYS_PTRACENET_ADMIN.
  • Devices: mapping /dev/kmsg/dev/mem, or raw disk → host abuse.
  • With no seccomp/AppArmor/SELinux, syscalls like ptracebpfmount are open.

D) Host filesystem & mount tricks

  • Bind mounting sensitive dirs (-v /etc:/etc) or -v /:/host → direct host writes.
  • Symlink/TOCTOU on volume paths can redirect writes to protected files.
  • OverlayFS quirks + setuid bits may enable privilege escalation on the host.

E) runc/containerd vulnerabilities

  • runc FD/exec races (e.g., families like CVE-2019-5736 & later variants): malicious container overwrites the host runc binary during docker exec, gaining host code execution.
  • containerd/CRI parser/manifest issues leading to unexpected host access.

F) Image & registry supply-chain

  • Typosquatted images on public registries, mutable tags (:latest) silently changing.
  • Dockerfiles with curl | bash, backdoored ENTRYPOINTs, secrets baked into layers.
  • Compromised CI pushing trojaned images to your registry.

G) Networking & credentials

  • Over-exposed ports (-p 0.0.0.0:…), weak firewall → direct internet reachability.
  • Stolen ~/.docker/config.json tokens; environment-variable secrets; cloud metadata access from containers.

3) What a real compromise looks like (chain example)

  1. Shodan finds 2375 open → attacker runs privileged container.
  2. Mounts host / and writes an SSH key to /root/.ssh/authorized_keys.
  3. Installs miner & persistence unit under /etc/systemd/system/….
  4. Harvests cloud creds from /root/.aws or metadata URL (if reachable).
  5. Lateral movement using harvested keys and registry tokens.

4) Hardening that actually works (copy-paste)

4.1 Daemon settings (/etc/docker/daemon.json)

jsonCopyEdit{
  "icc": false,
  "userns-remap": "default",
  "no-new-privileges": true,
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "3" }
}
  • Never expose 2375 on the internet. If you must use TCP, 2376 with mutual TLS behind a firewall/VPN.
  • Prefer rootless Docker where feasible.

4.2 Safer container run/compose

docker run

bashCopyEditdocker run --read-only --user 10000:10000 \
  --cap-drop ALL --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges:true \
  --security-opt seccomp=default \
  --pids-limit 256 --memory 512m --cpu-quota 50000 \
  --tmpfs /tmp:rw,noexec,nosuid,nodev \
  --network app-net \
  --health-cmd='curl -f http://127.0.0.1:8080/health || exit 1' \
  registry.example.com/app@sha256:<immutable-digest>

Compose snippet

yamlCopyEditservices:
  api:
    image: registry.example.com/api@sha256:3c1f...
    read_only: true
    user: "10000:10000"
    cap_drop: ["ALL"]
    security_opt:
      - no-new-privileges:true
      - seccomp:default
    pids_limit: 256
    tmpfs: ["/tmp:rw,noexec,nosuid,nodev"]
    networks: [app]
    healthcheck: { test: ["CMD","/healthcheck.sh"], interval: 30s, retries: 3 }

Do not: use --privileged, mount /var/run/docker.sock, or bind host / paths.

4.3 MAC & syscall policy

  • Enforce AppArmor/SELinux (e.g., docker-default AppArmor profile).
  • Keep seccomp default (or stricter local profile) to block dangerous syscalls.

4.4 Supply-chain controls

  • Sign images (Sigstore cosign) and enforce signatures in admission/webhooks.
  • Pin digests, not tags.
  • Generate SBOMs (Syft) and scan with Trivy/Grype on build & deploy.
  • Lock down registries; restrict to allow-listed registries/namespaces.

4.5 Network & secrets

  • Publish only necessary ports; firewall the host; use user-defined networks for micro-segmentation.
  • Use secret managers or Docker secrets/Swarm/K8s Secrets; avoid env vars where possible.
  • Block cloud metadata endpoints from app containers (IMDSv2 hop-limit / iptables).

5) Detections you should deploy (ready-to-use)

5.1 Falco (container breakout attempts)

yamlCopyEdit- rule: Docker Socket Mount
  desc: Container accessed /var/run/docker.sock
  condition: fd.name startswith /var/run/docker.sock
  output: "Docker socket access (proc=%proc.name user=%user.name file=%fd.name)"
  priority: CRITICAL

- rule: Write Below Root
  desc: Container writing to sensitive host paths
  condition: write_to_known_sensitive_file
  output: "Write to sensitive file (proc=%proc.name file=%fd.name)"
  priority: CRITICAL

5.2 Watch Docker events (quick hunt)

bashCopyEditdocker events --filter 'event=create' --filter 'event=exec_create' \
| grep -E 'privileged|/var/run/docker.sock|--cap-add|host|volume=/'

5.3 SIEM hunts

  • Process tree: dockerd → launches container → unexpected host process (crypto miner, bash).
  • Network: sudden outbound to mining pools; container contacting 169.254.169.254 (cloud metadata).
  • Filesystem: writes under /etc/systemd/system/root/.ssh/authorized_keys.

6) Incident response playbook (short & practical)

  1. Contain
    • iptables -A INPUT -p tcp --dport 2375 -j DROP (if exposed).
    • docker pause <id> or systemctl stop docker (consider business impact).
    • Snapshot host (disk + memory) before cleanup for forensics.
  2. Triage
    • docker ps -adocker inspect <id>docker logs <id>.
    • docker image inspect <img> for digest and provenance; retrieve SBOM, scan with Trivy.
    • journalctl -u dockerdocker events --since ....
    • Check /var/lib/docker/overlay2/*/diff for dropped binaries/scripts.
  3. Scope
    • Search for privileged containers, docker-sock mounts, unknown images, suspicious systemd units, new users/SSH keys.
  4. Eradicate & Recover
    • Remove malicious containers/images; rotate registry and CI tokens; rebuild from signed, scanned images.
    • Patch Docker/runc/containerd; disable 2375; enforce TLS/VPN.
  5. Lessons learned
    • Block docker-sock mounts, enforce image signatures, set daemon baseline, add Falco/SIEM rules.

7) 30-60-90 day security program

Days 1–30 (Baseline):

  • Disable 2375; move to TLS or socket-only; firewall host.
  • Enforce seccomp default, AppArmor/SELinux; enable userns-remap.
  • Ban --privileged and docker-sock mounts by policy.

Days 31–60 (Supply chain & policy):

  • Sign all images (cosign); enforce digest pinning.
  • SBOM + vulnerability scan gates in CI.
  • Implement admission controls (if on Swarm/K8s) to deny unsafe options.

Days 61–90 (Detection & drills):

  • Deploy Falco/eBPF sensors → SIEM; build dashboards for privileged runs, socket access, host mounts.
  • Red-team exercise: exposed 2375, docker-sock breakout, poisoned image → verify containment and recovery time.

Quick checklist

  •  No 2375 on the internet; 2376 TLS/VPN only
  •  No --privileged or dangerous caps; seccomp + AppArmor/SELinux on
  •  Never mount /var/run/docker.sock in app containers
  •  Pin digestssign imagesscan SBOMs
  •  Default-deny egress/ingress where possible; block metadata access
  •  Falco/SIEM rules for privileged runs, socket access, host writes
  •  IR runbook tested; tokens & keys rotated post-incident

Key takeaways

  • Misconfig is the exploit. Close 2375, kill --privileged, and stop mounting the Docker socket.
  • Treat images as untrusted code—sign, pin, and scan them.
  • Add runtime sensors and policies so breakouts are noisy and short-lived.

Leave a comment

Design a site like this with WordPress.com
Get started