SUID - Escalating Privilege
Welcome to the premier article at CyberSecurity.org.uk, this article covers the SUID bit and how it relates to system security. I have chosen a fairly well known about security area, though there maybe a few surprises for some. This article though serves as a foundation for other articles to be created on CyberSecurity.org.uk, a test article template if you will.
The Set User ID (SUID) bit, is used on unix style operating systems. It allows a program to execute as the owner of the program file, not as the user who invoked the program. SUID is often used to refer to SUID root, where a program in order to operate needs to have root privileges this is know as escalating privilege. But, SUID can also be used to change to any other user, in some instances it can be used to actually drop privileges. The more common use of SUID is SUID root though, and it is this form that unfortunately offers the higher level of security vulnerability.
SUID root is still used in most unix style Operating Systems (OSs), and is set on different programs for various reasons.
Most of the above programs need to be SUID root because they are either involved in the login system where only root (or a protected account) should have access to the password list, or for convenience; ping is used quite often and so is mount on desktop systems.
SUID only works when applied to an executable program, it will not work on an executable script (this is by enforcement not by design), when SUID was first introduced it did work on executable scripts. It also does not work with system(char*) in stdlib.h, as the author of this article discovered when creating an example, it does work with the exec functions of unistd.h though.
SUID was introduced to the unix operating system by Dennis M Ritchie, co-author of The C Programming Language Book, and of course the creator of the C language itself. The patent on Set User ID bit, has now been placed in the public domain.
SUID has also been backronymed as switch user ID, I only include this so people from that nomenclature may find this page.
The SUID bit was really introduced to solve some security dilemmas. To change your password on a system it generally requires read and write access to a centrally held password list. Under normal circumstances you often don't wish for someone to read the encrypted password list, let alone change it, unless they are the owner of the account or root. So, the file is normally given the permission of rw only to the owner (user perms) who is root. The passwd program is then SUID'd to allow access to the password list (normally /etc/shadow), only the passwd program has that access, the user does not. But, the problem comes if the passwd program itself has not been written securely. If the passwd program allows for any type of injection, or stack smashing it can leave the user with root capability on the host.
Most SUID programs are therefore checked very carefully before being allowed to be SUID'd, but mistakes do slip through the net. They are often the first files a cracker or security consultant will look for when either trying to penetrate or secure a system. It is a case of unathorised local privilege escalation, where a cracker uses a SUID root program to gain root and then expand their user privileges to root.
SUID could have been used to drop privileges, but because of the tightening of SUID it really cannot be advised anymore. Whilst it protects from the attacks used on SUID root, it is now vulnerable to the protections introduced for SUID root.
When you think SUID you should think SUID root, if something is not owned by root and is SUID'd then you probably need to drop the SUID bit on it.
SUID tends to sneak onto systems and distros, by admins and maintainers who want to create an easier day to day experience. Users want to mount their Compact Disks (CDs) or thumb drives, check they have net access etc. and SUID is the quick and dirty way to do it.
There does exist an alternative, that offers a little more security, and that is sudo (super user do). sudo offers an audit trail, and allows different levels of access. But, sudo itself is SUID'd.
Any file can have the SUID bit (s) set, this includes directories, but it only has an effect on native binary executables. There is the Set Group ID (SGID) bit as well, this does the same as the SUID bit for native binary executables but for groups. SGID though has a special effect on directories though, it causes the group of the directory to be applied to any files or subdirectories, added subsequently, to inherit the same group as the SGID'd directory.
The chmod (change mode) command is used to set the SUID or SGID bit. There are a couple of ways of using the chmod command, the numeric i(octal mode) or mnemonic way.
# # ++ numeric chmod (set) ++ # # set suid # chmod -v 4700 aprogram # # set sgid # chmod -v 2070 aprogram
# # ++ mnemonic chmod (set) ++ # # set suid # chmod -v u+s aprogram # # set sgid # chmod -v g+s aprogram
# # -- numeric chmod (remove) -- # # remove suid # chmod -v 0700 aprogram # # remove sgid # chmod -v 0070 aprogram
# # -- mnemonic chmod (remove) -- # # remove suid # chmod -v u-s # # remove sgid # chmod -v g-s
Detecting a SUID file is quite simple, the ls command with the long listing option does the trick. If colorization is on, then the suid files are normally shown in red.
# # -- detect suid files -- # ls -l
If the SUID bit of a file is set then a lower case s should be seen instead of an x in the rwx perms line.
It is often useful to find all the SUID files in one shot, and then go through the list and determine if the file should be SUID'd or not. find is the command that works the best for this.
# # -- find all suid and sgid files --
# find / -type f -a \( -perm /u+s -o -perm /g+s \) -exec ls -l {} \;
N.B. you may find (forgive the pun), that old versions of the above command used +u+s and +g+s; find has undergone some revision, man find for the latest details.
You should now have a list of all the files on your system that either represent potential penetration targets or programs to be desuid'd if possible.
To experiment with SUID, I have rolled a SUID wrapper. It can turn nearly any program into a program that is executed at root level. The argv[0], values has been hardcoded for a couple of reasons; I didn't want to include any string handling, and it also highlights how the argv[0] (program name) may get used in some programs.
// suidwrap.c - suid wrapper //---------------------------------------------------------- #include <stdio.h> #include <unistd.h> #include <sys/stat.h> //---------------------------------------------------------- int main(int argc, char* argv[]) { // suid wrapper char c; int pid; int execRet = 0; int chmodRet = 0; // welcome printf("SUID Wrapper - %s\n\n", argv[0]); if (argc == 1) { printf("No program file supplied.\n"); return 1; } printf("Program file : %s\n", argv[1]); if (argc > 2) printf("Parameters : %s\n", argv[2]); printf("\n"); // safety check printf("Do you wish to proceed (Y/N) ? "); c = getchar(); if (c != 'Y' && c != 'y') { printf("Exiting.\n"); return 1; } printf("\nProceeding ...\n\n"); if ( (pid = fork()) < 0) { printf("Fork error."); return 1; } else if (pid == 0) { // child if (argc == 2) execRet = execl(argv[1], "suidwrap", (char *) 0); else execRet = execl(argv[1], "suidwrap", argv[2], (char *) 0); if (execRet != 0) printf("Execution problem (%d).\n", execRet); } // remove suid on file 0700 chmodRet = chmod(argv[0], S_IRUSR | S_IWUSR | S_IXUSR); if (chmodRet == 0) printf ("suid bit removed."); else printf ("Problem removing suid bit."); printf("\n\n"); return 0; } //---------------------------------------------------------- // compile // gcc suidwrap.c -o suidwrap //---------------------------------------------------------- // usage // # su - // # cd ~<user>/ // # chown root suidwrap // Next move is dangerous // # chmod 4777 suidwrap // # exit // % ./suidwrap /usr/bin/whoami // # su - // # cd ~<user>/ // Remove root ownership and suid bit // # chown <user> suidwrap // # chmod 0700 suidwrap // # exit //----------------------------------------------------------
I have included code that removes the suid bit after use, but it is prudent to check for yourself as well. The program represents a security hole in your system if left in the suid state, so use with caution.
whoami is the program used to tell you who you are on a system, whereis whomai if your copy of whoami is not in /usr/bin/. You don't have to use whoami, cat /etc/shadow also acts as a good demonstration. It is possible to run shells as well, so /bin/sh and /bin/zsh make for an interesting experiment.
If you have found this site useful please consider linking to it @ http://www.cybersecurity.org.uk/articles/suid.htm
© Copyright Poised Solutions 2008 All Rights Reserved
Site Designed & Developed by
Poised Solutions
If you wish to discuss hiring Poised Solutions for an
information technology project please get in contact
or visit the main PoisedSolutions IT Consultancy Website.