SUID, SGID, sticky & umask
The special bits attackers look for.
Ordinary Linux permissions (read, write, and execute) answer one question about a file: what are you allowed to do to it? Three extra bits sit alongside the ones you already know, and they answer a stranger question. They can change who you get to be while a program runs, and who is allowed to delete things out of a shared folder. Two of them are near the top of an attacker's checklist the moment they land on a machine. So a security or operations engineer has to know them cold.
SUID: Borrowing the Owner's Powers
Here is the everyday version. A bank teller can't open the vault on their own say-so. But the bank gives them a controlled procedure that, for one specific task, acts with the bank's authority instead of the teller's. SUID (Set User ID) is that procedure in software form. When the SUID bit is set on a program, the program runs with the privileges of the file's owner, not the person who started it. Is the owner root? Then any user who runs it is briefly root.
The classic example ships on every Linux machine: passwd, the command you use to change your password. Changing a password means writing into /etc/shadow, a file only root is allowed to touch. You are not root. So passwd is owned by root and wears the SUID bit. The instant you run it, it runs as root, edits that one protected file under tight rules, and exits. You borrowed root's power for a few milliseconds without ever being handed the keys.
Read the permission string left to right. After the leading file-type dash come three groups of three: owner, group, others. Normally the owner's third character is x for execute. Here it's s. That lowercase s is the SUID bit sitting on top of the execute bit, and it is the whole story: this program, run by anyone, executes as root.
Every SUID-root file on a host is a door that leads from ordinary-user to root. Most of those doors are meant to be there. Your job is to know exactly which ones exist and to notice the day a new one appears. One command lists them all:
On a fresh Ubuntu or Debian box that list is short and boring, which is the point. Learn your baseline so the boring list stays boring. One name on it, pkexec, is worth remembering. A security flaw in it, catalogued as CVE-2021-4034 (a CVE, or Common Vulnerabilities and Exposures, number is the public tracking ID every serious bug gets) and nicknamed PwnKit, handed local users an instant root shell on millions of machines in 2022. And a surprising number of ordinary commands turn into root shells the moment they carry the SUID bit by mistake. A public catalog called GTFOBins documents exactly which standard binaries can be abused this way and how. Attackers read it. So should you. To sweep for SUID and SGID in one pass, use find / -perm /6000 -type f.
SGID: The Same Trick, Aimed at Groups
SGID (Set Group ID) is the group-flavored version, and it has two jobs depending on where it lands. On a program it works like SUID but for the group: the program runs with the file's group identity. That one is rare. The genuinely useful job is on a directory. Think of a shared project folder as a filing cabinet that belongs to a team. Without SGID, every document someone drops in is stamped with that person's own group, and the team quickly loses track of who can read what. Put SGID on the folder and every new file inside is automatically stamped with the folder's group instead.
See the s where the group's execute character would be. Now watch what happens when Alice, whose own default group is alice, creates a file inside:
The file's group is devs, inherited from the folder, not alice. That is the payoff of SGID on a directory. One catch worth understanding: SGID fixes the group owner, not the group's write permission. Under the standard umask the file is still -rw-r--r--, so teammates can read it but not edit it. If you want a truly shared, editable folder, you also lower the umask (covered next) to 002 so the group keeps its write bit.
The Sticky Bit: Everyone Writes, You Only Delete Your Own
The office fridge problem: it's shared, anyone can put their lunch in, but nobody should be able to throw out someone else's. A plain world-writable folder can't manage that. If a directory is writable by everyone, then by default everyone can also delete anything inside it, including files they never created, because in Linux the right to delete a file comes from write permission on the folder, not on the file. The sticky bit fixes exactly this. Set it on a directory and the rule changes: you can delete or rename a file inside it only if you own that file. The folder's owner and root can too, but nobody else.
This is why /tmp, a scratch space the whole system shares, is safe to leave world-writable. Look at its final character:
That trailing t is the sticky bit. Everyone can create files in /tmp, but user sam cannot delete a file that belongs to user alice. You set it with a leading 1, and you want it on any drop-box style folder you make world-writable:
umask: The Stencil That Decides New Permissions
Every file you create is born with some default permissions. What sets them? Not the special bits, but the umask (user file-creation mode mask). Picture a stencil laid over fresh permissions: wherever the stencil is solid, that permission gets blocked out. The umask is a list of permissions to withhold from new files. A umask of 022 means 'withhold write from group and others.'
The starting point before the mask is 666 for files (read and write for everyone, never execute) and 777 for directories. Clear the 022 bits and files land at 644 (rw-r--r--) and directories at 755 (rwxr-xr-x). That is the common desktop default, and it means new files are readable by everyone on the machine. Fine for a laptop. Not always fine for a server holding other people's data.
On a system handling sensitive data, tighten it. A umask of 027 withholds write from the group and every permission from others, so new files come out 640 (rw-r-----) and nothing is world-readable by accident. It is a quiet, real hardening step that costs nothing:
Setting umask in a shell lasts only for that shell. To make it stick for every login on a Debian or Ubuntu system, set it where the login process reads it, in /etc/login.defs (applied by PAM, the Pluggable Authentication Modules, the system that handles logins):
# Default umask applied to new login sessions via pam_umask.UMASK 027
When a Special Bit Is a Backdoor
Flip the SUID story around and you see why attackers love it. Someone who briefly gains root wants a way back to root that survives losing their original foothold. A tidy trick: copy a shell, give the copy to root, and stamp it SUID. From then on any ordinary account can run that copy and become root on demand, with no password and no exploit to re-run.
The -p flag tells bash not to drop the borrowed privileges on startup. Read the id output closely. The real UID (user ID, the fixed number Linux assigns your account) is still 1000 (sam), but the euid (effective user ID, the identity the kernel, the core of the operating system that enforces every access decision, actually checks) is 0. That is root, for every practical purpose. The file hides in /tmp under a name that looks like harmless junk, and it will keep handing out root shells until someone notices it.
Baseline first, react second. A host whose SUID and SGID files you have already written down is a host where a planted backdoor stands out the instant it lands. Run the find sweep on a schedule, diff it against your known-good list, and treat every new line as guilty until you have explained it.
Try this
Work through “When a Special Bit Is a Backdoor” yourself on a sandbox you can throw away, following the commands above in order. Then break one step deliberately and re-run, so you have seen the failure before it finds you.
Takeaway
The trap worth remembering here: lowercase means live, uppercase means idle. Check that on your own systems before you need to, because it is cheaper to find on a quiet afternoon than during an incident.