container-forensics
Investigates containerized environments for signs of compromise, misconfiguration, or container escape. Covers standalone Docker hosts and Kubernetes clusters. Produces a structured findings document with severity tagging.
Triggers
Alternate expressions and non-obvious activations (primary phrases are matched automatically from the skill description):
- "Falco" / "Tetragon" / "Tracee" → eBPF runtime monitoring tools
- "dive" → Docker image layer analysis
- "crictl" → containerd/CRI-O environment forensics
- "escape" → container escape investigation
Purpose
Container environments introduce unique attack surfaces: privileged containers, host namespace access, writable image layers, and overpermissioned service accounts. Standard host forensics misses these vectors. This skill applies container-aware investigation procedures and maps findings to MITRE ATT&CK for Containers.
Behavior
When triggered, this skill:
Detect environment type:
- Check for Docker:
docker info 2>/dev/null
- Check for Kubernetes:
kubectl cluster-info 2>/dev/null or presence of /var/run/secrets/kubernetes.io/
- Check for containerd-only (no Docker):
ctr version 2>/dev/null
- Check for CRI-O or containerd via CRI:
crictl version 2>/dev/null
- Determine if running inside a container: check for
/.dockerenv, inspect cgroup paths
Container inventory and privilege audit:
- List all containers (running and stopped):
docker ps -a --format '{{json .}}'
- For containerd/CRI-O environments:
crictl pods and crictl ps -a
- Inspect individual containers:
crictl inspect <id> (equivalent of docker inspect)
- List images on CRI nodes:
crictl images and crictl inspecti <image-id>
- Pull container logs via CRI:
crictl logs <container-id>
- Flag containers with dangerous flags:
--privileged: docker inspect <id> | jq '.[].HostConfig.Privileged'
- Host network mode:
NetworkMode == "host"
- Host PID namespace:
PidMode == "host"
- Dangerous capability additions:
CapAdd containing SYS_ADMIN, NET_ADMIN, SYS_PTRACE
- Enumerate bind mounts of sensitive host paths (
/, /etc, /var/run/docker.sock, /proc, /sys)
Docker — image verification:
- List all local images with digests:
docker images --digests
- Check image provenance: compare
RepoDigests against expected registry
- Flag images tagged
latest without a pinned digest
- Inspect image build history for suspicious
RUN layers: docker history --no-trunc <image>
- Check for images not associated with any running or stopped container (orphaned images)
Image layer analysis with dive:
- Run
dive <image> --ci for non-interactive efficiency and layer summary
- Identify layers that delete files immediately after downloading them (evidence wiping pattern)
- Flag layers installing unexpected tooling (
curl, nc, nmap, socat, python)
- Identify unusually large layers inconsistent with the image's declared purpose
- Check for world-writable permissions set in later layers after a trusted base image
Docker — volume and filesystem inspection:
- List named volumes:
docker volume ls
- Inspect volumes mounted into containers for sensitive data paths
- Examine container overlay filesystem changes:
docker diff <container_id>
- Flag containers with writable root filesystems where
ReadonlyRootfs is false
Docker — socket and API exposure:
- Check if Docker socket is bind-mounted into any container — this grants effective root on the host
- Check for TCP Docker API exposure:
ss -tlnp | grep ':2375\|:2376'
- Review Docker daemon configuration:
/etc/docker/daemon.json
Container escape indicators:
- Processes running in container namespaces that share host PID/network: compare namespace inodes in
/proc/1/ns/ vs /proc/<container-pid>/ns/
- Unexpected cgroup escape patterns in
/proc/<pid>/cgroup
- Files written to host paths from within container overlay mounts
runc or containerd-shim process anomalies in host process tree
eBPF runtime monitoring:
- Check for Falco service and alert logs:
journalctl -u falco and /var/log/falco.log
- Review active Falco rules for coverage gaps (shell-in-container, outbound connections, writes below root)
- Collect Tetragon execution traces via
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon or tetra getevents
- Review active Tetragon
TracingPolicy resources: kubectl get tracingpolicies -A
- Collect Tracee event logs from container or systemd deployment
- If no eBPF tooling was active during the incident, document this gap in the findings
Kubernetes — cluster-level audit:
- List all pods across all namespaces:
kubectl get pods -A -o json
- Flag pods running as root:
.spec.containers[].securityContext.runAsUser == 0 or unset
- Flag pods with
hostPID, hostNetwork, or hostIPC set to true
- Flag pods mounting the Docker socket or host paths
- List privileged containers across the cluster
Kubernetes — RBAC audit:
- List ClusterRoleBindings granting
cluster-admin: kubectl get clusterrolebindings -o json | jq '...'
- Identify service accounts with wildcard permissions or
* verbs on sensitive resources
- Check for default service account token automounting:
automountServiceAccountToken: true
- List RoleBindings in high-value namespaces (kube-system, kube-public)
Kubernetes — pod security and network policy:
- Check for absent NetworkPolicies (pods with unrestricted egress/ingress)
- Review PodSecurityAdmission or OPA/Gatekeeper policy coverage
- List nodes and check for unauthorized node additions:
kubectl get nodes -o wide
etcd security audit (Kubernetes control-plane only):
- Verify etcd is not listening on a non-loopback address:
ps aux | grep etcd | grep listen-client-urls
- Confirm
--client-cert-auth=true is set in the etcd process flags
- Check for encryption-at-rest configuration in the API server manifest (
--encryption-provider-config)
- List etcd client certificates in
/etc/kubernetes/pki/etcd/ and flag any unexpected certs
- Take a read-only snapshot with
etcdctl snapshot save for offline analysis
- Enumerate etcd key paths for secrets and serviceaccount tokens using
etcdctl get / --prefix --keys-only
K8s API server audit log analysis (if audit logging is enabled):
- Locate audit log path from
kube-apiserver.yaml (--audit-log-path)
- Summarize request activity by user and verb to identify outliers
- Detect anonymous (
system:anonymous) API calls to non-public endpoints
- Flag ServiceAccount tokens used outside their home namespace
- Identify bulk
list/get on secrets resources (credential harvesting pattern)
- Flag
exec subresource calls from non-operator users during the incident window
- Detect rapid
create/delete sequences on the same resource (attacker covering tracks)
Write findings document:
- Save to
.aiwg/forensics/findings/container-forensics.md
- Group by: Docker/containerd findings, eBPF runtime events, Kubernetes findings, etcd/API server findings, escape indicators
- Tag each finding: INFO, SUSPICIOUS, MALICIOUS
Usage Examples
Example 1 — Docker host
docker investigation
Audits the local Docker daemon.
Example 2 — Kubernetes cluster
kubernetes forensics
Requires kubectl configured with appropriate credentials.
Example 3 — Inside a container
container forensics
Detects the container context and adjusts collection accordingly.
Output Locations
- Findings:
.aiwg/forensics/findings/container-forensics.md
- Raw Docker inspection:
.aiwg/forensics/evidence/docker-inspect.json
- crictl inspection output:
.aiwg/forensics/evidence/crictl-inspect.json
- K8s pod manifest dump:
.aiwg/forensics/evidence/k8s-pods.json
- Falco alert log:
.aiwg/forensics/evidence/falco-alerts.log
- Tetragon events:
.aiwg/forensics/evidence/tetragon-events.json
- Tracee events:
.aiwg/forensics/evidence/tracee-events.json
- etcd snapshot:
.aiwg/forensics/evidence/etcd-snapshot-<timestamp>.db
- K8s API server audit log (copy):
.aiwg/forensics/evidence/k8s-audit.log
Configuration
container_forensics:
dangerous_capabilities:
- SYS_ADMIN
- NET_ADMIN
- SYS_PTRACE
- SYS_MODULE
sensitive_host_paths:
- /
- /etc
- /var/run/docker.sock
- /proc
- /sys
- /root
high_value_namespaces:
- kube-system
- kube-public
- default
References
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/research-before-decision.md — Detect environment type (Docker, containerd, Kubernetes) before applying collection procedures
- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/non-destructive.md — Do not stop or remove containers until all artifacts are collected and hashed
- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/red-flag-escalation.md — Escalate immediately when container escape, Docker socket exposure, or privileged escape is confirmed
- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/evidence-integrity.md — Hash container logs and filesystem exports immediately after collection
- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/skills/linux-forensics/SKILL.md — Investigate the underlying host after container forensics; container escapes leave traces on the host
1---2name: container-forensics3description: Docker, containerd/CRI-O, and Kubernetes forensic investigation covering container inventory (docker and crictl), privilege checks, image verification, layer analysis (dive), escape detection, eBPF runtime monitoring (Falco, Tetragon, Tracee), K8s RBAC audit, etcd security audit, and API server audit log analysis4---5
6# container-forensics
7
8Investigates containerized environments for signs of compromise, misconfiguration, or container escape. Covers standalone Docker hosts and Kubernetes clusters. Produces a structured findings document with severity tagging.
9
10## Triggers
11
12
13Alternate expressions and non-obvious activations (primary phrases are matched automatically from the skill description):
14
15- "Falco" / "Tetragon" / "Tracee" → eBPF runtime monitoring tools
16- "dive" → Docker image layer analysis
17- "crictl" → containerd/CRI-O environment forensics
18- "escape" → container escape investigation
19
20## Purpose
21
22Container environments introduce unique attack surfaces: privileged containers, host namespace access, writable image layers, and overpermissioned service accounts. Standard host forensics misses these vectors. This skill applies container-aware investigation procedures and maps findings to MITRE ATT&CK for Containers.
23
24## Behavior
25
26When triggered, this skill:
27
281. **Detect environment type**:
29 - Check for Docker: `docker info 2>/dev/null`
30 - Check for Kubernetes: `kubectl cluster-info 2>/dev/null` or presence of `/var/run/secrets/kubernetes.io/`
31 - Check for containerd-only (no Docker): `ctr version 2>/dev/null`
32 - Check for CRI-O or containerd via CRI: `crictl version 2>/dev/null`
33 - Determine if running inside a container: check for `/.dockerenv`, inspect cgroup paths
34
352. **Container inventory and privilege audit**:
36 - List all containers (running and stopped): `docker ps -a --format '{{json .}}'`
37 - For containerd/CRI-O environments: `crictl pods` and `crictl ps -a`
38 - Inspect individual containers: `crictl inspect <id>` (equivalent of `docker inspect`)
39 - List images on CRI nodes: `crictl images` and `crictl inspecti <image-id>`
40 - Pull container logs via CRI: `crictl logs <container-id>`
41 - Flag containers with dangerous flags:
42 - `--privileged`: `docker inspect <id> | jq '.[].HostConfig.Privileged'`
43 - Host network mode: `NetworkMode == "host"`
44 - Host PID namespace: `PidMode == "host"`
45 - Dangerous capability additions: `CapAdd` containing `SYS_ADMIN`, `NET_ADMIN`, `SYS_PTRACE`
46 - Enumerate bind mounts of sensitive host paths (`/`, `/etc`, `/var/run/docker.sock`, `/proc`, `/sys`)
47
483. **Docker — image verification**:
49 - List all local images with digests: `docker images --digests`
50 - Check image provenance: compare `RepoDigests` against expected registry
51 - Flag images tagged `latest` without a pinned digest
52 - Inspect image build history for suspicious `RUN` layers: `docker history --no-trunc <image>`
53 - Check for images not associated with any running or stopped container (orphaned images)
54
554. **Image layer analysis with dive**:
56 - Run `dive <image> --ci` for non-interactive efficiency and layer summary
57 - Identify layers that delete files immediately after downloading them (evidence wiping pattern)
58 - Flag layers installing unexpected tooling (`curl`, `nc`, `nmap`, `socat`, `python`)
59 - Identify unusually large layers inconsistent with the image's declared purpose
60 - Check for world-writable permissions set in later layers after a trusted base image
61
625. **Docker — volume and filesystem inspection**:
63 - List named volumes: `docker volume ls`
64 - Inspect volumes mounted into containers for sensitive data paths
65 - Examine container overlay filesystem changes: `docker diff <container_id>`
66 - Flag containers with writable root filesystems where `ReadonlyRootfs` is false
67
686. **Docker — socket and API exposure**:
69 - Check if Docker socket is bind-mounted into any container — this grants effective root on the host
70 - Check for TCP Docker API exposure: `ss -tlnp | grep ':2375\|:2376'`
71 - Review Docker daemon configuration: `/etc/docker/daemon.json`
72
737. **Container escape indicators**:
74 - Processes running in container namespaces that share host PID/network: compare namespace inodes in `/proc/1/ns/` vs `/proc/<container-pid>/ns/`
75 - Unexpected cgroup escape patterns in `/proc/<pid>/cgroup`
76 - Files written to host paths from within container overlay mounts
77 - `runc` or `containerd-shim` process anomalies in host process tree
78
798. **eBPF runtime monitoring**:
80 - Check for Falco service and alert logs: `journalctl -u falco` and `/var/log/falco.log`
81 - Review active Falco rules for coverage gaps (shell-in-container, outbound connections, writes below root)
82 - Collect Tetragon execution traces via `kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon` or `tetra getevents`
83 - Review active Tetragon `TracingPolicy` resources: `kubectl get tracingpolicies -A`
84 - Collect Tracee event logs from container or systemd deployment
85 - If no eBPF tooling was active during the incident, document this gap in the findings
86
879. **Kubernetes — cluster-level audit**:
88 - List all pods across all namespaces: `kubectl get pods -A -o json`
89 - Flag pods running as root: `.spec.containers[].securityContext.runAsUser == 0` or unset
90 - Flag pods with `hostPID`, `hostNetwork`, or `hostIPC` set to true
91 - Flag pods mounting the Docker socket or host paths
92 - List privileged containers across the cluster
93
9410. **Kubernetes — RBAC audit**:
95 - List ClusterRoleBindings granting `cluster-admin`: `kubectl get clusterrolebindings -o json | jq '...'`
96 - Identify service accounts with wildcard permissions or `*` verbs on sensitive resources
97 - Check for default service account token automounting: `automountServiceAccountToken: true`
98 - List RoleBindings in high-value namespaces (kube-system, kube-public)
99
10011. **Kubernetes — pod security and network policy**:
101 - Check for absent NetworkPolicies (pods with unrestricted egress/ingress)
102 - Review PodSecurityAdmission or OPA/Gatekeeper policy coverage
103 - List nodes and check for unauthorized node additions: `kubectl get nodes -o wide`
104
10512. **etcd security audit** (Kubernetes control-plane only):
106 - Verify etcd is not listening on a non-loopback address: `ps aux | grep etcd | grep listen-client-urls`
107 - Confirm `--client-cert-auth=true` is set in the etcd process flags
108 - Check for encryption-at-rest configuration in the API server manifest (`--encryption-provider-config`)
109 - List etcd client certificates in `/etc/kubernetes/pki/etcd/` and flag any unexpected certs
110 - Take a read-only snapshot with `etcdctl snapshot save` for offline analysis
111 - Enumerate etcd key paths for secrets and serviceaccount tokens using `etcdctl get / --prefix --keys-only`
112
11313. **K8s API server audit log analysis** (if audit logging is enabled):
114 - Locate audit log path from `kube-apiserver.yaml` (`--audit-log-path`)
115 - Summarize request activity by user and verb to identify outliers
116 - Detect anonymous (`system:anonymous`) API calls to non-public endpoints
117 - Flag ServiceAccount tokens used outside their home namespace
118 - Identify bulk `list`/`get` on `secrets` resources (credential harvesting pattern)
119 - Flag `exec` subresource calls from non-operator users during the incident window
120 - Detect rapid `create`/`delete` sequences on the same resource (attacker covering tracks)
121
12214. **Write findings document**:
123 - Save to `.aiwg/forensics/findings/container-forensics.md`
124 - Group by: Docker/containerd findings, eBPF runtime events, Kubernetes findings, etcd/API server findings, escape indicators
125 - Tag each finding: INFO, SUSPICIOUS, MALICIOUS
126
127## Usage Examples
128
129### Example 1 — Docker host
130```
131docker investigation
132```
133Audits the local Docker daemon.
134
135### Example 2 — Kubernetes cluster
136```
137kubernetes forensics
138```
139Requires `kubectl` configured with appropriate credentials.
140
141### Example 3 — Inside a container
142```
143container forensics
144```
145Detects the container context and adjusts collection accordingly.
146
147## Output Locations
148
149- Findings: `.aiwg/forensics/findings/container-forensics.md`
150- Raw Docker inspection: `.aiwg/forensics/evidence/docker-inspect.json`
151- crictl inspection output: `.aiwg/forensics/evidence/crictl-inspect.json`
152- K8s pod manifest dump: `.aiwg/forensics/evidence/k8s-pods.json`
153- Falco alert log: `.aiwg/forensics/evidence/falco-alerts.log`
154- Tetragon events: `.aiwg/forensics/evidence/tetragon-events.json`
155- Tracee events: `.aiwg/forensics/evidence/tracee-events.json`
156- etcd snapshot: `.aiwg/forensics/evidence/etcd-snapshot-<timestamp>.db`
157- K8s API server audit log (copy): `.aiwg/forensics/evidence/k8s-audit.log`
158
159## Configuration
160
161```yaml
162container_forensics:
163 dangerous_capabilities:
164 - SYS_ADMIN
165 - NET_ADMIN
166 - SYS_PTRACE
167 - SYS_MODULE
168 sensitive_host_paths:
169 - /
170 - /etc
171 - /var/run/docker.sock
172 - /proc
173 - /sys
174 - /root
175 high_value_namespaces:
176 - kube-system
177 - kube-public
178 - default
179```
180
181## References
182
183- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/research-before-decision.md — Detect environment type (Docker, containerd, Kubernetes) before applying collection procedures
184- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/non-destructive.md — Do not stop or remove containers until all artifacts are collected and hashed
185- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/red-flag-escalation.md — Escalate immediately when container escape, Docker socket exposure, or privileged escape is confirmed
186- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/rules/evidence-integrity.md — Hash container logs and filesystem exports immediately after collection
187- @$AIWG_ROOT/agentic/code/frameworks/forensics-complete/skills/linux-forensics/SKILL.md — Investigate the underlying host after container forensics; container escapes leave traces on the host