Why do adversaries use setuid and setgid?
Once an adversary gains access to a machine, they need to make sure they have enough permissions to persist, evade defensive controls, steal credentials, and more. Adversaries abuse setuid and setgid bits to elevate their privilege levels on macOS and Linux, potentially accessing both cloud-hosted and physical on-premise machines. With elevated privileges, adversaries can modify system configurations, install software, access sensitive files, perform credential theft, disable security products, and much more. Adversaries may also set the setuid or setgid bit on binaries that wouldn’t normally have them, enabling them to so that they can easily elevate privileges in the future.
Setuid and setgid binaries are executable files with a special permission bit that allows the binary to run as either the owner (setting the user ID) or the owning group (setting the group ID) of the file. For example, if a user named
bob runs a file with the following permissions, then the process would actually run as if
root ran the binary instead of
Permissions | Owner | Group | Filename
s in place of where an
x would normally be for user permissions. The same is true of the setgid bit, except it sets the owning group of the file instead of the user. Normally this is benign, expected behavior that allows a non-privileged user like
bob to run a binary that needs elevated privileges. However, if there’s a bug in the binary that an adversary can exploit, they can act with all of the privileges of the owning user or group, which most often is root or some other privileged account. These sorts of bugs may seem rare, but they are in fact surprisingly common.
How do adversaries use setuid and setgid?
Adversaries most often leverage this technique by finding native binaries that have the setuid or setgid bit set and are owned by
root or some other privileged user. After finding such a binary, they attempt to exploit a flaw in the binary in order to gain execution or, at the very least, perform an action as the privileged user.
One notable example of this technique is the PwnKit vulnerability discovered in January 2022, which exemplifies how setuid binaries can be dangerous when adversaries abuse them. PwnKit was a bug in the pkexec utility that ships with polkit, a component that sets system-wide permission levels and is included by default in many Linux distributions. The
pkexec binary was owned by
root and had the setuid bit set. It also had a bug in it that allowed an unprivileged user to load a shared object file that would run with root privileges. This bug made it trivial for an unprivileged user to elevate privileges. DataDog has a great write-up on PwnKit if you’re looking for additional details.