Finding setuid binaries on Linux and BSD
Finding setuid binaries
for Linux and BSD systems
Binaries with the setuid bit enabled, are being executed as if they were running under the context of the root user. This enables normal (non-privileged) users to use special privileges, like opening sockets. While this seems unnecessary for a normal user, it is actually needed for simple commands like ping.
Finding files with setuid bit
To discover all files with the setuid bit, we can use the find command. Depending on the distribution, you can use some specific parameters and special options. For example on Linux you can use -perm with slash notation (e.g. /4000). This means that if any of the file permission bits match, the result will be displayed. However, this option does not work for BSD systems, like NetBSD.
One of the best alternatives we discovered is using the -perm parameter with the octal value. However, just providing the value, would mean we have to search for the specific mode (like 4555 in the example below).
This exact match can be useful to fix files which got incorrect permissions and are very specific. In our case this is not the case. We want all files with the setuid bit set, which means effectively “4***”. To get this type of search, we can add a dash before the octal mode. This will also match the file if the first bit is found.
As can be seen in the example, the file rcmd will match. However, instead of using -4555, we can simplify the search to -4000. The zeros tell the find command that any of the values are fine for the other permission bits. So it will also include files which have normally 755 (or 4755).
# find /bin -perm -4000 /bin/rcmd
Exclude other devices/mounts
Another useful addition to discovering the right binaries, is searching from the root. We are interested in directories like /bin, /sbin and /usr/(s)bin. Since we are not interested in files from other file systems mounted below /, we can exclude those first. This is done with the -xdev parameter.
Now we want just the files owned by the root user. Files with root as owner in combination with setuid, are executed with root privileges. All other files are not interesting. So for to be true, we add the -user root parameter.
Setgid bit as well
To complete our search, we also want to discover files which have the similar setgid bit set. This would execute files with the permission of the group. We can do this with a logical “or” statement. So we want files with the first bit to be 4 or 2.
find / -xdev -user root \( -perm -4000 -o -perm -2000 \)
This is one of the quickest ways to search through the file system, skipping any files which are not owned by the root user and skipping device files.
What to do with the results?
Most systems will reveal a few files with the setuid or setgid bit set. So having a few on your system is not an issue, but still room for improvement. Let’s have a look at the options:
Remove the package
Sometimes we come across files which we simply don’t need on our system.
Debian / Ubuntu: dpkg -s /path/to/binary or dpkg-query -S /path/to/binary
Red Hat based systems: rpm -qf /path/to/binary
For Debian based systems with the dpkg utility, the output looks like this:
# dpkg -S /bin/mount mount: /bin/mount
Remove the bit
Another logical option is removing the bit from the system. For example when the system has no normal users, why allow any software to use special rights? With chmod u-s we can strip the setuid bit off the file permissions. Similarly chmod g-s will remove the setgid bit.
Linux: Monitor usage with audit
If you don’t want to alter your system yet, another option would be to add the system to a Linux audit rule. This way we can track the the usage of the file.
An example to monitor the execution of binaries is with the follow Linux audit rule:
-a always,exit -F path=/bin/ps -F path=/bin/ls -F perm=x -k binaries
This rule will monitor files /bin/ps and /bin/ls and trigger an event when being executed (perm=x), with the tag binaries (k=binaries). For more information about auditing with the Audit framework, have a look at our previous post: