Shredding Access in the Name of Security: Set UID Audits

By Jay Beale jay@bastille-linux.org Lead Developer, Bastille Linux Project

June 26, 2000 - Almost every time I read an article on securing a Unix/Linux box, I find a glaring omission. They all discuss turning off unneeded services, like ftp and telnet, but rarely do they cover the next step of performing a SUID audit. Just as most services are a danger because they often run as root, SUID root programs always run as root. The danger here is that if someone obtains an account on your computer, legitimately or otherwise, SUID root programs present them a potential means for grabbing root access.

In this article, I'll introduce Linux/Unix file permissions, root privilege and the SUID path to root. Then I'll help you run a SUID audit on your system, using Red Hat 6.2 as an example. While Bastille Linux also runs an audit, there are some really great concepts and practices here for your everyday use; furthermore, you have more options doing this manually. Let's start by discussing Unix/Linux file permissions.

 

How do Unix/Linux File Permissions Work?

Unix file permissions are based entirely on the user construct. Each file on the system is owned by a user and a group. Each file also has a set of permission bits that denote what privileges the User owner has, what privileges the Group has, and finally, what privileges everyone else on the system has. Your personal mail file might allow only the User owner - you - read/write access, while your department "TO DO" list might be readable/writable by your boss, but read-only by people in your department. You'd define this group "ITdepartment" via the /etc/groups file. This access control, or method of setting who has what privileges on a file, is implemented via permission bits in the file's inode entry.


Each file has 12 (9 normal, 3 special) primary permissions flags which make up its mode. The first 9 are:


                          0123456789     USER     GROUP

$ ls -al /etc/passwd      -rw-r--r--   1 root     root          703 Jun  1 15:08 /etc/passwd

                          

Bits:

   1    User (owner) can Read?

   2    User (owner) can Write?

   3    User (owner) can Execute ( Run the program, change to this directory )?

   4    Group members can Read?

   5    Group members can Write?

   6    Group members can Execute?

   7    Other (everyone else) can Read?

   8    Other (everyone else) can Write?

   9    Other (everyone else) can Execute?

Bits 1-3 are the User Bits, while bits 4-6 are the Group bits and bits 7-9 are Other bits. We might say that /etc/passwd has permissions User: read, write; Group Read; Other Read. If we were the owner of this file, we could add group-write access with the command

chmod g+w /etc/passwd

and get a listing like this:

                         0123456789     USER     GROUP

$ ls -al /etc/passwd      -rw-rw-r--   1 root     root          703 Jun  1 15:08 /etc/passwd

     

This background is getting us somewhere, though: the other three bits are special bits. The first of these is called the Set-UID bit1, which lets you run a program as someone other than yourself. What do I mean?

 

Set-UID (SUID) Status

Normally, when you log into a system and run a program, it is run with your UID (User ID), so it has exactly the same privileges that you have. But there are cases where you need more privileges than that, like when you want to change your password. Remember, /etc/passwd ( or /etc/shadow ) is not writable by every user on the system. Unless you're the owner, root, you won't be able to change it. How do we solve this? We make a program, /usr/bin/passwd, which will write to the /etc/passwd file. Since it will need privilege, we lock its UID to always be that of its OWNER, rather than of the user running it2. This is exactly what the Set-UID bit does. This fixes the problem, but there's a security issue here.

 

Primary Vulnerabilities: World-Executable SUID root programs

Every Set-UID root program that you can execute is a possible path to root. Why? Basically, because it lets an ordinary user run a program as root. That program may have a bug, such that it doesn't handle "strange input" well, like in your garden variety buffer overflow vulnerability. Often, a smart programmer can exploit this vulnerability to force the SUID program to execute arbitrary code, like a shell. This shell will inherit the SUID program's root privilege, giving the attacker root. Every Linux distro seems to have a number of SUID root programs that are discovered to be exploitable like this. In Red Hat 6.0-6.1, for example, userhelper is exploitable, because it doesn't check the program path specified on the command line for oddities, like "../"'s. To protect against this type of thing, we need to turn off the Set-UID bit on every program that we can.

 

SUID/SGID Auditing

Before we can turn off SUID bits, we have to find them. What does a Set-UID program look like? To follow through with our previous example:


$ ls -l /usr/bin/passwd

-r-s--x--x   1 root     root        22312 Sep 25  1999 /usr/bin/passwd

   ^

   ^

  SUID

The eXecute "x" is replaced by an "s," so we know this program is Set-UID. It is owned by root and executable by everyone, so anyone on the system can run the program, which will run as root.


In a SUID Audit, we apply a critical principle of Computer Security: minimalism. We remove all paths to root that aren't absolutely necessary. Here, we research each SUID program on the system and make an educated decision about its level of privilege. We can list all3 the Set-UID programs owned by root using the command4:

find / -perm -4000 -uid 0 \print


But once we find them, how do we minimize the danger of exploitation?

 

Lessening the Risk

There are four basic ways to limit the danger of SUID root programs:

  1. Strip the SUID bit, so the program runs as the running user, instead of running as root.

  2. Define a special group for the program in question and make the program executable by members of the group, but not by everyone else. (chgrp wheel /bin/su ; chmod 4750 /bin/su)

  3. Strip the world(other)-execute bit, leaving it executable by the owner and group, but still SUID (more dangerous).

  4. Strip SUID and use Sudo to allow only certain users to run this command. (This is like #2, but far more manageable.)

We'll primarily use option 1 here, but you should consider each. Let's move on to an actual SUID root audit, on Red Hat 6.2.

 

Auditing Red Hat 6.2

On Red Hat, with only a few exceptions, all of the SUID root programs are executable by everyone on the system.

/bin/mount - mount is suid-root to allow ordinary users to mount floppy and CD-ROM drives. If your users won't be at console, or won't be using floppies/CD-ROM's, you can deactivate set-uid, like this: chmod u-s /bin/mount


/bin/ping - ping is suid-root to allow users to test network connectivity. You can generally restrict ping to root only, as only the system administrator should need to test or tweak network connectivity. chmod u-s /bin/ping


/bin/su - su is set-uid so that ordinary users can switch to root. You should generally leave the set-uid bit on, here, though you could make this executable only by the wheel group. This is customary on many old Unix systems and the wheel group already exists in /etc/group.


/bin/umount - umount is suid-root to allow users to unmount floppies and CD-ROM's. (See above, under /bin/mount )


/sbin/dump - Dump is a backup tool that should really only be used by the sysadmin. It really should never have had suid status! If it can be used at all by junior people, it could be used to look at files not normally accessible to every user. This is a common problem on Linux/Unix systems, where a vendor was probably trying to be helpful. If you need your junior admins (who don't have root) to be able to run this, consider using sudo instead! For now, chmod u-s /sbin/dump.


./sbin/pwdb_chkpwd - There's no man page for this. It seems like it is probably part of PAM, but since we can't find information on it, we'll have to leave it alone for now. Unfortunately, as Garfinkel and Spafford describe in Practical Unix and Internet Security, there are many OS's where this is a sad fact of the suid-root audit: sometimes, you just don't know what the program does! You might check the source or run a deja.com UseNet archive search. In my case, I'm just leaving this one alone. (First one to e-mail me useful information on this gets a honorable mention in my next article!)


/sbin/restore - Restore is dump's counterpart. (see /sbin/dump, above)


/sbin/unix_chkpwd - Again, there's no man page for this and it looks like part of PAM. ( see /sbin/pwdb_chkpwd, above )


/usr/X11R6/bin/Xwrapper - Xwrapper seems to be the script that runs your particular X Server. Your X Server needs to run set-uid root, so that it can take over your screen...


/usr/bin/at - at is used to schedule a command to run later - unfortunately, at has had a rich history of problems. Fortunately, you really can achieve the same functionality with cron! Turn off set-uid on this - even better, deactivate the atd service: (chmod u-s /usr/bin/at ; chkconfig atd off )


/usr/bin/chage - This program is used to set/read password-aging information. It would never be used by users, except that it can tell a user how much time they have until their password expires. I, being paranoid, would deactivate set-uid on this one, since users get an e-mail when their password gets near expiring. This program is especially useless to users when you're not enforcing password aging.


/usr/bin/chfn - This program is used to change your "finger" information. As it writes to the /etc/passwd file, it needs suid to work for any user other than root. If you don't want your users changing their finger information, have no users or are feeling paranoid/grumpy, chmod u-s /usr/bin/chfn. Don't discount the first reason: some sites use the finger information to keep better track of their users!


/usr/bin/chsh - chsh lets a user change their shell, by rewriting the last column of their /etc/passwd entry. If you lock all your users to one shell, or have no users, or are feeling very paranoid, chmod u-s /usr/bin/chsh.


/usr/bin/crontab - crontab allows a user to schedule (possibly repetitive) jobs for later execution. If you, as many admins, don't want your users touching cron for security-reasons, rip suid away!


/usr/bin/gpasswd - Much like passwd, gpasswd lets your users change the group passwords in /etc/group or /etc/gshadow. If you're like most admins and don't use group passwords, strip suid away.


/usr/bin/{lpq, lpr, lprm} - These are the printing utilities. If you don't print from this machine, turn suid off. Otherwise, you really should leave suid on here!


/usr/bin/passwd - As we saw before, this allows ordinary users to change their password. It needs root privilege to write to the /etc/passwd. Unless you have no users, leave suid on!


/usr/bin/procmail - While procmail is used by users to sort/act on incoming e-mail. On Sendmail-based Linux systems, it is also the local delivery agent and needs to run as root. (Sendmail runs as root, but drops privilege before it calls the delivery agent. ) Unless you receive no mail on this host, please don't turn suid off .


/usr/bin/{rcp,rlogin,rsh} - These require root to bind to a low port (<1024). You really, really, really shouldn't be using these as they are dreadfully insecure and are easily replaced by ssh and scp. Definitely deactivate these! ( chmod 0000 /usr/bin/{rcp,rlogin,rsh} )


/usr/bin/sperl5.00503 - Again, we find a case where a command is poorly documented on the system. Luckily, a google search turned up a CERT listing on sperl, AKA suidperl. suidperl is a security answer to an old problem in some kernels. It seems like a safe bet, but you really should ask your local Perl god.


/usr/libexec_ptchown - This is another program that could use a man page. Some discussion on the Linux Security Audit showed that this was used by terminal programs and the like to grab pty's. You should probably leave this alone.


/usr/sbin/sendmail - sendmail has to be suid root to allow ordinary users to send mail. If you have no users, or don't want them to send mail, turn this off. I highly recommend that you leave this on though, as e-mail is a core Internet technology.


/usr/sbin/traceroute - traceroute uses UDP packets of progressively lower Time-To-Live (TTL) values to find the router path between hosts. As admins should probably be the only one testing network connectivity, it should be fairly safe to deactivate suid. (chmod u-s /usr/sbin/traceroute )


/usr/sbin/userhelper - userhelper allows a user to change their own passwd (like passwd), finger info (like chfn) and shell (like chsh), but it is run through a GUI tool. I suggest killing this off, as it had a recent root vulnerability and it duplicates existing commands. If you can find it on the web, check out userrooter, which can easily give any ordinary user a root shell (in Red Hat 6.0-6.1) by exploiting bad parameter-checking in PAM/userhelper.


/usr/sbin/usernetctl - usernetctl allows ordinary users, if they're permitted by config files, to bring up/down the network interfaces. I honestly believe that root should be the only one affecting network interfaces. While some might argue that ppp links, often restarted, should be touched by users, I think this fails on a multi-user, multi-login system. Make your own call! ( chmod u-s /usr/sbin/usernetctl )


That's it. We're done with our audit. As a last step, you should generate a new list of Set-UID root programs and keep it in a safe place. Keep a careful eye on changes to this list, as new SUID root programs are often HOT signs of a root-compromise.


Jay Beale is the Lead Developer of the Bastille Linux Project (http://www.bastille-linux.org). He is the author of several articles on Unix/Linux security, along with the upcoming book "Securing Linux the Bastille Way," to be published by Addison Wesley. At his day job, Jay is a security admin working on Solaris and Linux boxes. You can find learn more about his articles, talks and favorite security links via http://www.bastille-linux.org/jay.

 

1The other bits are the SGID bit, which locks the GID of the process to its Group Owner, and the Stick bit, used to protect files in group/world-writable directories from deletion.

2 The SGID bit, as noted above, locks the GID of the process to its Group Owner. This is often far less dangerous, so we don't consider it much here.

3My test system was a near-everything install of Red Hat 6.2. Your mileage may vary.

4The "uid 0" flag shows files owned by root. The -perm -4000 shows files where the Set-UID bit is set. (man find). For SGID root, try: find / -perm -2000 -gid 0 -print