diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9d6bc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/.venv +/.env +/dist +/build +/out +/target +/node_modules +/.DS_Store +Thumbs.db +*.pyc +*.swp +/.idea +/.vscode diff --git a/COURSE_SUMMARY.md b/COURSE_SUMMARY.md new file mode 100644 index 0000000..9efd9fd --- /dev/null +++ b/COURSE_SUMMARY.md @@ -0,0 +1,24 @@ +# Hands-on Docker Hacking +_summary for editorial board_ + +## Modules +1. Privileged Container +2. Exposed Container APIs +3. Container Escape +4. Container Image Tampering +5. Insecure Container Configuration +6. Denial-of-Service (DoS) +7. Kernel Vulnerabilities +8. Shared Kernel Exploitation +9. Insecure Container Orchestration +10. Insecure Container Images +11. What Seccomp, AppArmor, and SELinux Actually Do + +## Deliverables included +- `course/modules/` — one markdown module per topic with lab steps +- `course/quizzes/` — module and final assessments +- `README` update for GitHub course homepage + +## Format notes +- Each module contains: intro, attack scenario, compliant vs noncompliant example, remediation, and hands-on lab. +- Sample 60–90 second module intro video scripts are embedded where practical. diff --git a/README.md b/README.md index e472de7..1cabf6b 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,7 @@ # Docker Hacking Lab -### EC-Council | Hands-on Docker Hacking Course -**Author: Adonis Jimenez | BizDevStudio** +Hands-on Docker Hacking course repo. -> Warning: This lab contains intentional vulnerabilities. Run in an isolated environment only. - -## Quick Start -``` -git clone https://github.com/donny-devops/docker-hacking-lab -cd docker-hacking-lab -docker compose up -d -``` - -## Course Modules -- Module 0: Lab Setup -- Module 1: Docker Internals and Attack Surface -- Module 2: Enumeration and Reconnaissance -- Module 3: Escape via Privileged Flag -- Module 4: Escape via Host Path Mount -- Module 5: Docker Socket Exploitation -- Module 6: TCP Daemon Exploitation -- Module 7: Image and Registry Attacks -- Module 8: Supply Chain Attacks -- Module 9: Network Attacks and Lateral Movement -- Module 10: Runtime Defense +## Course structure +- `course/modules/` — topic lessons and labs +- `course/quizzes/` — assessment questions +- `COURSE_SUMMARY.md` — editorial board summary diff --git a/course/modules/02-exposed-apis.md b/course/modules/02-exposed-apis.md new file mode 100644 index 0000000..1f4035d --- /dev/null +++ b/course/modules/02-exposed-apis.md @@ -0,0 +1,22 @@ +# Exposed Container APIs +Covers Docker daemon socket/API exposure, auth bypass, TLS, and network exposure risks. + +## Attack scenario +Exposing `2375/2376` without auth allows remote host takeover. + +## Noncompliant +docker run -d -p 2375:2375 docker:dind + +## Compliant +docker run -d -p 127.0.0.1:2376:2376 ` + --tlsverify --tlscacert ca.pem --tlscert cert.pem --tlskey key.pem docker:dind + +## Remediation +- Bind to localhost or VPN only. +- Enforce TLS client auth on 2376. +- Firewall-restrict daemon ports. + +## Hands-on lab +1. Inspect Docker socket listeners. +2. Confirm remote API auth requirements. +3. Harden with TLS/localhost binding. diff --git a/course/modules/03-container-escape.md b/course/modules/03-container-escape.md new file mode 100644 index 0000000..60e6583 --- /dev/null +++ b/course/modules/03-container-escape.md @@ -0,0 +1,21 @@ +# Container Escape +Covers breakouts via docker socket, --privileged, host namespaces, and dangerous mounts. + +## Attack scenario +A container with /var/run/docker.sock can create privileged sibling containers. + +## Noncompliant +docker run -v /var/run/docker.sock:/var/run/docker.sock alpine + +## Compliant +docker run --user 1000:1000 --read-only --cap-drop ALL alpine + +## Remediation +- Avoid host namespace sharing. +- Drop capabilities; avoid --privileged. +- Use rootless Docker where possible. + +## Hands-on lab +1. Run noncompliant container. +2. Attempt docker ps inside. +3. Harden and verify escape path blocked. diff --git a/course/modules/04-image-tampering.md b/course/modules/04-image-tampering.md new file mode 100644 index 0000000..22c2f63 --- /dev/null +++ b/course/modules/04-image-tampering.md @@ -0,0 +1,21 @@ +# Container Image Tampering +Covers supply-chain attacks, tag mutation, untrusted registries, and image signing. + +## Attack scenario +Attacker pushes backdoored tag to public registry; CI auto-deploys it. + +## Noncompliant +docker build -t app:latest . + +## Compliant +cosign sign --key cosign.key app@sha256:... + +## Remediation +- Pin images by digest. +- Sign images with cosign/Sigstore. +- Scan in CI with Trivy/Grype. + +## Hands-on lab +1. Inspect image history/layers. +2. Re-pin by digest. +3. Verify provenance/signature. diff --git a/course/modules/05-insecure-config.md b/course/modules/05-insecure-config.md new file mode 100644 index 0000000..a1e9dc9 --- /dev/null +++ b/course/modules/05-insecure-config.md @@ -0,0 +1,21 @@ +# Insecure Container Configuration +Covers excessive permissions, writable rootfs, dangerous sysctls, and insecure defaults. + +## Attack scenario +Root-owned writable rootfs enables cron/kmodule persistence. + +## Noncompliant +docker run --cap-add SYS_ADMIN --read-only=false ubuntu + +## Compliant +docker run --user 65532:65532 --read-only --tmpfs /tmp ubuntu + +## Remediation +- Run as nonroot. +- Use --read-only with tmpfs. +- Drop capabilities by default. + +## Hands-on lab +1. Inspect docker inspect config. +2. Harden runtime flags. +3. Verify no root writable paths. diff --git a/course/modules/06-dos.md b/course/modules/06-dos.md new file mode 100644 index 0000000..8153d2a --- /dev/null +++ b/course/modules/06-dos.md @@ -0,0 +1,21 @@ +# Denial-of-Service (DoS) +Covers CPU/memory/PIDs/I/O exhaustion and runtime limits. + +## Attack scenario +Fork bomb or memory hog crashes neighboring containers/host. + +## Noncompliant +docker run -d --name stress docker-stress + +## Compliant +docker run -d --name stress --cpus 0.5 --memory 256m --pids-limit 64 docker-stress + +## Remediation +- Set --cpus --memory --pids-limit. +- Use --restart on-failure:5. +- Monitor with cAdvisor/Prometheus. + +## Hands-on lab +1. Run stress unconstrained. +2. Observe impact. +3. Apply limits and compare. diff --git a/course/modules/07-kernel-vulns.md b/course/modules/07-kernel-vulns.md new file mode 100644 index 0000000..4499425 --- /dev/null +++ b/course/modules/07-kernel-vulns.md @@ -0,0 +1,21 @@ +# Kernel Vulnerabilities +Covers host/runtime CVEs, patching cadence, and isolation limitations. + +## Attack scenario +Unpatched kernel enables container-to-host privilege escalation. + +## Noncompliant +uname -r # old unpatched kernel + +## Compliant +sudo apt install linux-generic-hwe-22.04 + +## Remediation +- Patch host/runtime on SLA. +- Minimize host kernel modules. +- Evaluate gVisor/Kata for stronger isolation. + +## Hands-on lab +1. Check kernel against CVE advisories. +2. Review runtime changelog. +3. Document upgrade plan. diff --git a/course/modules/08-shared-kernel.md b/course/modules/08-shared-kernel.md new file mode 100644 index 0000000..476bee0 --- /dev/null +++ b/course/modules/08-shared-kernel.md @@ -0,0 +1,21 @@ +# Shared Kernel Exploitation +Covers namespace mistakes, /proc exposure, pid=host, and cross-container access. + +## Attack scenario +Host PID namespace exposes other containers'/host process data. + +## Noncompliant +docker run --pid=host --cap-add SYS_ADMIN alpine + +## Compliant +docker run --user nonroot --pid container --cap-drop ALL alpine + +## Remediation +- Avoid --pid=host. +- Use container-scoped PID namespaces. +- Enable dmesg_restrict. + +## Hands-on lab +1. Run two containers. +2. Inspect /proc with/without host PID. +3. Harden namespace usage. diff --git a/course/modules/09-orchestration.md b/course/modules/09-orchestration.md new file mode 100644 index 0000000..c5ea6fb --- /dev/null +++ b/course/modules/09-orchestration.md @@ -0,0 +1,22 @@ +# Insecure Container Orchestration +Covers K8s/Compose misconfigs, default SAs, broad RBAC, and exposed APIs. + +## Attack scenario +Default SA has secret-read; app bug leaks cluster secrets. + +## Noncompliant +serviceAccountName: default + +## Compliant +serviceAccountName: app-sa +automountServiceAccountToken: false + +## Remediation +- Dedicated SA per workload. +- Least-privilege RBAC. +- Scan configs with Polaris/Kubesec. + +## Hands-on lab +1. Inspect current SA/roles. +2. Create restricted SA. +3. Update deployment and confirm denial. diff --git a/course/modules/10-insecure-images.md b/course/modules/10-insecure-images.md new file mode 100644 index 0000000..cd93c5a --- /dev/null +++ b/course/modules/10-insecure-images.md @@ -0,0 +1,21 @@ +# Insecure Container Images +Covers outdated bases, malware images, vulnerable packages, and registry hygiene. + +## Attack scenario +Malicious image appears as trusted name; CI builds and deploys it. + +## Noncompliant +docker build -t app:latest . + +## Compliant +trivy image app@sha256:... + +## Remediation +- Pin by digest/provenance. +- Scan in CI and deploy gate. +- Trust only approved registries. + +## Hands-on lab +1. Build latest-tagged image. +2. Inspect layers/history. +3. Rebuild pinned and scan. diff --git a/course/modules/11-lsm.md b/course/modules/11-lsm.md new file mode 100644 index 0000000..3928b79 --- /dev/null +++ b/course/modules/11-lsm.md @@ -0,0 +1,27 @@ +# What Seccomp, AppArmor, and SELinux Actually Do +Covers LSM roles, Docker defaults, custom profiles, and operational pitfalls. + +## Seccomp +Restricts syscalls. Docker default blocks ~44 dangerous syscalls. + +## AppArmor +Path-based confinement. Uses docker-default on Debian/Ubuntu. + +## SELinux +Label-based MAC. Stronger; enabled on RHEL/Fedora. + +## Noncompliant +docker run --security-opt seccomp=unconfined ubuntu + +## Compliant +docker run --security-opt seccomp=default --security-opt apparmor=docker-default ubuntu + +## Remediation +- Keep defaults unless app breaks. +- Trace syscalls before narrowing. +- Combine seccomp + AppArmor/SELinux + capabilities. + +## Hands-on lab +1. Inspect container security opts. +2. strace app process. +3. Build minimal custom seccomp JSON and test. diff --git a/course/quizzes/container-escape-final.md b/course/quizzes/container-escape-final.md new file mode 100644 index 0000000..0751de8 --- /dev/null +++ b/course/quizzes/container-escape-final.md @@ -0,0 +1,8 @@ +# Final assessment: Container Escape +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/container-escape.md b/course/quizzes/container-escape.md new file mode 100644 index 0000000..822a759 --- /dev/null +++ b/course/quizzes/container-escape.md @@ -0,0 +1,10 @@ +# Quiz: Container Escape +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/dos-final.md b/course/quizzes/dos-final.md new file mode 100644 index 0000000..00809d7 --- /dev/null +++ b/course/quizzes/dos-final.md @@ -0,0 +1,8 @@ +# Final assessment: Denial-of-Service (DoS) +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/dos.md b/course/quizzes/dos.md new file mode 100644 index 0000000..954c92a --- /dev/null +++ b/course/quizzes/dos.md @@ -0,0 +1,10 @@ +# Quiz: Denial-of-Service (DoS) +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/exposed-apis-final.md b/course/quizzes/exposed-apis-final.md new file mode 100644 index 0000000..e920887 --- /dev/null +++ b/course/quizzes/exposed-apis-final.md @@ -0,0 +1,8 @@ +# Final assessment: Exposed Container APIs +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/exposed-apis.md b/course/quizzes/exposed-apis.md new file mode 100644 index 0000000..e5a7233 --- /dev/null +++ b/course/quizzes/exposed-apis.md @@ -0,0 +1,10 @@ +# Quiz: Exposed Container APIs +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/image-tampering-final.md b/course/quizzes/image-tampering-final.md new file mode 100644 index 0000000..91600d4 --- /dev/null +++ b/course/quizzes/image-tampering-final.md @@ -0,0 +1,8 @@ +# Final assessment: Container Image Tampering +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/image-tampering.md b/course/quizzes/image-tampering.md new file mode 100644 index 0000000..9ed27e0 --- /dev/null +++ b/course/quizzes/image-tampering.md @@ -0,0 +1,10 @@ +# Quiz: Container Image Tampering +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/insecure-config-final.md b/course/quizzes/insecure-config-final.md new file mode 100644 index 0000000..343d739 --- /dev/null +++ b/course/quizzes/insecure-config-final.md @@ -0,0 +1,8 @@ +# Final assessment: Insecure Container Configuration +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/insecure-config.md b/course/quizzes/insecure-config.md new file mode 100644 index 0000000..7692977 --- /dev/null +++ b/course/quizzes/insecure-config.md @@ -0,0 +1,10 @@ +# Quiz: Insecure Container Configuration +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/insecure-images-final.md b/course/quizzes/insecure-images-final.md new file mode 100644 index 0000000..7869ecc --- /dev/null +++ b/course/quizzes/insecure-images-final.md @@ -0,0 +1,8 @@ +# Final assessment: Insecure Container Images +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/insecure-images.md b/course/quizzes/insecure-images.md new file mode 100644 index 0000000..03439f1 --- /dev/null +++ b/course/quizzes/insecure-images.md @@ -0,0 +1,10 @@ +# Quiz: Insecure Container Images +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/kernel-vulns-final.md b/course/quizzes/kernel-vulns-final.md new file mode 100644 index 0000000..8e51b8e --- /dev/null +++ b/course/quizzes/kernel-vulns-final.md @@ -0,0 +1,8 @@ +# Final assessment: Kernel Vulnerabilities +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/kernel-vulns.md b/course/quizzes/kernel-vulns.md new file mode 100644 index 0000000..db89272 --- /dev/null +++ b/course/quizzes/kernel-vulns.md @@ -0,0 +1,10 @@ +# Quiz: Kernel Vulnerabilities +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/lsm-final.md b/course/quizzes/lsm-final.md new file mode 100644 index 0000000..0d7aba9 --- /dev/null +++ b/course/quizzes/lsm-final.md @@ -0,0 +1,8 @@ +# Final assessment: What Seccomp, AppArmor, and SELinux Actually Do +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/lsm.md b/course/quizzes/lsm.md new file mode 100644 index 0000000..df018f5 --- /dev/null +++ b/course/quizzes/lsm.md @@ -0,0 +1,10 @@ +# Quiz: What Seccomp, AppArmor, and SELinux Actually Do +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/orchestration-final.md b/course/quizzes/orchestration-final.md new file mode 100644 index 0000000..4b60b14 --- /dev/null +++ b/course/quizzes/orchestration-final.md @@ -0,0 +1,8 @@ +# Final assessment: Insecure Container Orchestration +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/orchestration.md b/course/quizzes/orchestration.md new file mode 100644 index 0000000..051c047 --- /dev/null +++ b/course/quizzes/orchestration.md @@ -0,0 +1,10 @@ +# Quiz: Insecure Container Orchestration +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/course/quizzes/shared-kernel-final.md b/course/quizzes/shared-kernel-final.md new file mode 100644 index 0000000..ecc8181 --- /dev/null +++ b/course/quizzes/shared-kernel-final.md @@ -0,0 +1,8 @@ +# Final assessment: Shared Kernel Exploitation +## Questions +1. Which option most directly reduces runtime breakout surface? + A) --privileged B) drop caps + seccomp + read-only C) expose 2375 D) host network +2. Which is a reliable signal of insecure images? + A) pinned digest + signed provenance B) latest tag from unknown registry C) small image size D) alpine base +## Answers +1. B 2. B diff --git a/course/quizzes/shared-kernel.md b/course/quizzes/shared-kernel.md new file mode 100644 index 0000000..d9b2e4b --- /dev/null +++ b/course/quizzes/shared-kernel.md @@ -0,0 +1,10 @@ +# Quiz: Shared Kernel Exploitation +## Questions +1. Which control is most specific to syscall filtering? + A) AppArmor B) SELinux C) seccomp D) cgroups +2. Exposing Docker API without auth primarily risks: + A) slower builds B) disk usage C) full host compromise D) image pulls failing +3. The strongest container isolation boundary is: + A) shared kernel B) VM parity C) namespace + cgroup + LSM D) Docker socket +## Answers +1. C 2. C 3. C diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..017cb83 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,5 @@ +# Tests +Add test files here. Suggested runners: +- Python: `pytest` +- Node/TS: `vitest` or `jest` +- Rust: `cargo test`