← Back to all writeups

Misconfigured find SUID — GTFOBins Abuse to Root

The SUID bit set on /usr/bin/find turned a routine enumeration pass into an instant root shell, no exploit development required.

findsuidgtfobinslinuxprivilege-escalation

Not every privilege escalation needs a CVE number or a custom exploit chain. Sometimes the fastest path to root is a standard Unix utility that somebody set the SUID bit on and forgot about. find is one of the most dangerous binaries to leave SUID-enabled, precisely because it’s designed to spawn other processes — including a shell.

I had a low-privilege shell on a Linux box and, as always, my first move after landing was a SUID sweep.


The Setup

find / -perm -4000 2>/dev/null

This is the standard first pass on any fresh Linux foothold: search the entire filesystem for binaries with the SUID bit set, suppressing permission-denied noise so the output stays readable. Most of what comes back is expected — passwd, su, mount, ping. Those are supposed to be SUID; they need elevated privileges for a narrow, well-defined reason.

/usr/bin/find showing up in that list is not expected. find has no legitimate reason to run with the file owner’s privileges — its entire job is searching directory trees and optionally acting on what it finds, which is exactly what makes it dangerous once it inherits root ownership.


Why find With SUID Is Instant Root

find supports an -exec flag that runs an arbitrary command against each matched result — a completely standard, everyday feature for batch operations like find . -name "*.log" -exec rm {} \;. If the find binary itself is owned by root and has the SUID bit set, whatever it executes via -exec inherits that elevated privilege too, because the process is running as root regardless of which user invoked it.

GTFOBins documents this exact abuse path. The payload spawns a shell as the -exec target, matching on . so it always finds at least one result to trigger on:

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

Exploitation

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

Breaking it down:

  • find . — search the current directory; the actual search scope barely matters here, since the goal is just to trigger -exec once
  • -exec /bin/sh -p \; — for the first matched entry, execute /bin/sh with the -p flag
  • -quit — stop searching after the first match, so find doesn’t spawn a new shell for every file in the directory

The shell dropped immediately with an elevated effective UID. id confirmed full root:

uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user)

euid=0 — the real UID is still the unprivileged account, but the effective UID, which is what the kernel actually checks for privilege enforcement, is root.


Why This Works

The -p flag on /bin/sh is doing the real work here, same as it does for every other SUID-shell-spawn technique. Under normal circumstances, if a shell detects that its real UID and effective UID don’t match, it treats that as a security-relevant condition and drops the elevated effective UID before doing anything else — this is a deliberate safeguard against exactly this kind of privilege leakage. The -p flag tells the shell to skip that check and keep the inherited privileges intact.

Since find was SUID root, the child process it spawned via -exec started life with euid=0. Without -p, that shell would have immediately dropped back down to the real UID. With it, the elevated privilege survives, and the interactive shell that lands is a genuine root shell.


Root Cause

The SUID bit had been set on /usr/bin/find, almost certainly by accident — the same failure mode that shows up across nearly every SUID misconfiguration lab: a permissions script applied too broadly, a binary copied between systems without stripping its extended attributes, or a one-off debugging change that never got reverted.

Fix: Remove the SUID bit from find immediately — no legitimate deployment needs it:

chmod u-s /usr/bin/find

Then audit every SUID binary on the system against a known-good baseline (find / -perm -4000 2>/dev/null compared against the distro’s default package manifest), rather than assuming SUID bits are only ever set intentionally.


Key Takeaways

  • find / -perm -4000 2>/dev/null should be one of the first commands run on any new foothold — SUID misconfigurations are common and frequently trivial to exploit
  • Any utility that supports spawning child processes (find, vim, less, awk, python) is a potential instant-root path the moment it’s SUID and owned by root
  • The -p flag on /bin/sh is what preserves an elevated effective UID after a privileged process spawns a shell — without it, the privilege is dropped before you can use it
  • Cross-reference unexpected SUID binaries against GTFOBins before assuming they’re benign — most common utilities are already documented there

Questions? Hit me up on X.