A container does not need the full privileged flag to be escapable. A single capability, added with --cap-add or a Kubernetes securityContext.capabilities.add, can be enough, because each capability maps to a kernel code path that was never meant to be reachable by a semi-trusted workload. The default Docker capability set is already a trimmed list; the dangerous escapes come from capabilities that are added on top, or from a base image run with --cap-add=ALL.
Decode exactly what you hold before choosing a page:
grep CapEff /proc/self/status # hex bitmask of effective capabilities
capsh --decode=00000000a80425fb # => the Docker default set
capsh --print # human-readable current/bounding set
getpcaps $$ # same, via libcap
Match a bit in that mask to the capability name, then go to the matching page. The highest-value additions, roughly in order of how directly they escape:
Subtopics#
- CAP_SYS_ADMIN: mount, pivot_root, and the cgroup release_agent escape.
- CAP_SYS_MODULE: load a kernel module that runs code on the host.
- CAP_DAC_READ_SEARCH: read any host file by brute-forcing inode handles.
- CAP_DAC_OVERRIDE: bypass file permission checks to write host files.
- CAP_SYS_PTRACE: inject code into host processes when PID namespace is shared.
- CAP_SYS_RAWIO: raw port and physical-memory access to patch the kernel.
- CAP_BPF: load BPF programs that read and write kernel memory.
- CAP_NET_RAW: raw sockets for sniffing and spoofing on the container network.