Right, so you’ve got a system, and you want to know what’s on it that has the potential to elevate your privileges. The most straightforward way to do this is by asking the filesystem itself. The find command is our go-to tool for this; it’s the grumpy, hyper-efficient librarian who knows exactly where every book is and isn’t afraid to tell you.

The magic lies in the -perm (permissions) test. We’re looking for two specific permission sets: the SUID bit (4000) and the SGID bit (2000). The numbers might seem arbitrary, but they’re not. Think of the standard 755 permissions (user, group, other). These special bits live in the prefix to that number. A 4755 means “this has the permissions 755 and the SUID bit is set.”

The Basic, No-Frills Hunt

Let’s start with the classic incantation. We’re going to search from the root directory (/), ignore any errors (because we’re not root and can’t read everything, and find loves to complain about it), and look for files (-type f) with either (/) the SUID or the SGID bit set.

find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null

Let’s break that down because it’s important:

  • \( ... \): The parentheses group our permission conditions together. The backslashes are needed to escape them from the shell.
  • -perm -4000: The dash (-) here is crucial. It means “match any file that has at least the SUID bit (4000) set.” The other permissions can be anything. If you used -perm 4000, it would only match files that have exactly 4000 permissions (e.g., ---S------), which is useless and would miss almost everything (like rwsr-xr-x).
  • -o: This is the logical OR operator. We want files that meet either condition.
  • 2>/dev/null: This shoves all those pesky “Permission denied” errors into the void so we can actually see our results. It’s not being lazy; it’s being practical.

Why the Dash in -perm -4000 Matters

This is a classic “trap for young players” moment. The -perm test behaves very differently based on whether you use a slash (/), a dash (-), or nothing.

  • -perm 4000: Exact mode. Matches only if the file’s permissions are exactly ---S------ (which is 4000). You will almost never want this.
  • -perm -4000: Minimum mode (at least). Matches if the file has all the bits in 4000 set. Since 4000 is just the SUID bit, it matches any file where the SUID bit is set, regardless of its other permissions. This is what we almost always want.
  • -perm /4000: Any match mode. Matches if the file has any of the bits in 4000 set. This is less common for SUID/SGID hunting.

The takeaway: Always use the dash (-) for this. Using the wrong form is the number one reason your find command returns nothing or returns garbage.

Getting Fancy: Formatting Your Output

The default find output is… functional. It’s just a pathname. If you’re on a system with GNU find (like most Linux distributions), you can get much more useful information by using the -ls action. This gives you details like permissions, owner, size, and timestamp all at once.

find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null -ls

The output will look something like this: 132456 12K -rwsr-xr-x 1 root root 12345 Sep 10 2022 /usr/bin/sudo

Now you can immediately see it’s owned by root and has the SUID bit set (rws). This is infinitely more useful.

What You’ll Find (And What to Do With It)

When you run this, you’ll get a list. On a typical system, it will include expected things like sudo, passwd, ping, and su. These are there for a reason—they need elevated privileges to perform their specific tasks (e.g., passwd needs to write to /etc/shadow).

Your job is to audit this list. Is that binary owned by root? Is it a standard system utility? Or is it some weird script in /tmp owned by a user? The latter is a blazing red flag. A common best practice is to maintain a known-good list of SUID/SGID binaries on a clean system and compare against it periodically. Any new, unexpected entry deserves immediate scrutiny.

The Pitfall of World-Writable Directories

Here’s a sneaky one. The find command is powerful, but it has a subtle weakness: if a directory above the file is world-writable, an attacker could theoretically rename the binary and replace it with a malicious one between the moment find traverses the directory and the moment you go to inspect the file. It’s a race condition, but a possible one.

For a truly paranoid (and thorough) audit, you might want to boot from a clean live OS and scan your main disk, ensuring nothing can interfere with the scanning tool itself. For 99% of use cases, the standard find command is perfectly sufficient, but it’s good to know the limits of your tools. It reminds you that in security, nothing is ever truly simple.