Many common operating systems adhere to the idea that a user is granted privilege based on a series of lists. In traditional Unix, for example, a user is listed as a member of a group in the /etc/passwd and /etc/group lists, and the group that user belongs to is, say, allowed to execute a given program, write to some file, or delete some directory. On a Microsoft Windows system, the same sort of access control exists as well. Users are divided into pre-existing groups that allow them various levels of privilege on the system (e.g., the Administrators group, the Power Users group, the Users group). Some groups, such as the Administrators and the Power Users, can install software onto the system. Other groups, such as Guests, have very limited access and can only run certified programs. This is all fine and well, but sometimes for perfectly good reasons, a person needs to temporarily use a higher privilege level than they are normally allowed. Traditionally, a user has the capability to completely assume the login of an administrative account via su or Run As... (Unix and Windows respectively), but these solutions lack many desirable features.
We have similar situations in real life. Let's say that you have to access the electrical room in a building to install some wiring. A reasonable procedure would probably entail someone recording some pertinent information about you: your name, who you work for, why you are there, and so forth. Most likely, you would be asked to provide some credentials—say, a business card, a license, or an access badge. Then you may be given a key, or your badge may be added to the security system to allow it access into the electrical room. After some reasonable amount of time has passed, you are expected to return the key, or perhaps your badge access to the room expires.
This is almost exactly how a system such as sudo works. You are added to list that says that you are the type of person who needs additional privilege (you are added to the /etc/sudoers file by another, authorized user), you have to provide a credential (you enter your own password, not the root password), and you are granted a short-term token that expires after a reasonable amount of time has elapsed (five minutes is the default). Your actions are logged (via syslog or some other logging if you wish) and you can only access the room (or the program) the Administrator allows you.
sudo is available on almost every Unix-like system, and as such, many administrators are at least mildly familiar with it. When you use sudo, you are not actually assuming the UID of root to run a command; you are using the sudo process to execute the command as root. This differs from the traditional su command, which substitutes a user identity for your own. It sounds like a subtle difference, but there are some practical upshots to this scheme. The first is logging; by default, sudo logs all usage and command lines to syslog. The second major benefit is access control: you can configure sudo to allow only a small subset of your users to run only a small subset of commands at elevated privilege.
Unfortunately, most administrators don't have the time to learn how to configure sudo in the best possible way. In a perfect world, you would want to restrict the programs the sudo ers can use while still leaving them access to the programs they need to elevate privilege. For example, maybe your administrators need the ability to add, edit, or remove users, affect user's quotas, start and stop important processes, or kill processes that have gotten out of hand. Even if you are only administering your own laptop, it's traditional advice to log in as a regular user and increase your privilege only when you have to. Apple OS X takes this attitude by default, and it's actually impossible to log into an OS X box directly as root unless you make some changes to the netinfo database. All administrative functions happen through a rather slick (and sadly, proprietary) interface to sudo.
Even if you are already using sudo, I'm sure that if you looked at the /etc/sudoers file on most systems, it would look something like this:
# User privilege specification root ALL=(ALL) ALL billy ALL=(ALL) ALL # Uncomment to allow people in group wheel to run all commands %wheel ALL=(ALL) ALL %admins ALL=(ALL) ALL
It's better than just giving the root password to Billy, but it's just about as secure. The obvious intent here is to allow Billy the ability to run any command he needs to, but it opens up a huge door of unintended possibilities. For example, Billy can change the root password to whatever he wants just by entering sudo passwd root
. Or, Billy can use sudo to spawn a shell and sidestep sudo's logging capability by entering sudo /bin/bash
. So what makes sense here is to identify the programs Billy needs to raise privilege and limit his access to allow only those programs.
Here's an /etc/sudoers file that solves a few of these problems. We group the administrators into a user alias and tell sudo that they cannot elevate the privilege of the shells on the system or of the su program by preceding the commands with the !
character. Then, we tell sudo that these administrators are allowed to modify the user database and kill programs if necessary. This is a pretty locked-down /etc/sudoers, but it serves as an example:
# User privilege specification root ALL=(ALL) ALL Cmnd_Alias SHELL = /bin/bash, , /bin/csh, /bin/sh, /usr/bin/bash Cmnd_Alias PROGRAMS = /usr/sbin/useradd, /usr/sbin/userdel /usr/sbin/usermod User_Alias ADMINS = billy, bob, frank ADMINS ALL = !/usr/bin/su, !SHELL, PROGRAMS, /bin/kill
Here's another example, this time with a number of restrictions enabled, but allowing user emarkham the ability to elevate programs in the /bin, /sbin, /usr/bin, and /usr/sbin directories as well as a custom-written administration script:
# User privilege specification root ALL=(ALL) ALL Cmnd_Alias SHELL = /bin/bash, /bin/csh, /bin/sh, /usr/bin/bash Cmnd_Alias PATHS = /bin/, /sbin/, /usr/bin/, /usr/sbin/ # custom admin program, does remote shutdowns, backups, restores, etc. Cmnd_Alias ADMINCMDS = /usr/local/sbin/administration.pl Cmnd_Alias DANGEROUS = /usr/bin/passwd, /bin/su emarkham ALL = PATHS, ADMINCMDS, !SHELL, !DANGEROUS
Take special note of the line that specifies what the user emarkham is allowed to run. The order is important because the rules are processed left to right. If the order were !SHELL
, !DANGEROUS
, PATHS
, then sudo would happily allow emarkham to run passwd, which is the exact opposite of what we're trying to accomplish here. Depending how complex you want to go with your sudo rules, generally specifying what the user is allowed to do first, and then specifying what the user is not allowed to do last produces good results. It's easier if you have a good idea of what commands you want the user to access and then build up from there.
This example /etc/sudoers file is commented with lines that start with a #
character. If you don't get in the habit of commenting your config files, eventually you will end up with a set of rules as complex and as difficult to understand as your firewall tables.
Even though many administrators do not exploit all the functionality of Unix's sudo, the most commonly used security features are still light years ahead of how most people run Microsoft Windows. Almost every Windows user ends up running his machine as Administrator, because the system is rather difficult to actually use as an unprivileged user, even if you are a member of the Power Users group. For starters, installing or removing software typically requires Administrator rights, not to mention adding devices and their requisite drivers. Many people I work with (all security professionals!) have given up on running Windows XP as a regular user, and eventually add themselves into the Administrators group. Windows Vista provides a way to avoid this via a new system called User Account Control (UAC), but even so, it does not actually provide a way for a user to bump his privilege level without entering a separate administrative password. Even when UAC is run in Admin Approval Mode, users are never allowed to increase their privilege level to perform a task; instead, they enter their passwords to confirm an action allowed at their existing levels of privilege.
At any rate, as I write this, Windows Vista is only recently released, and for the moment, most machines running an operating system from Microsoft are running some variety of Windows XP or Windows 2000 or Windows Server 2003, all systems that do not include User Account Control.
Thankfully, there is a way to run a real sudo on Windows. Schley Andrew Kutz wrote a full-featured sudo system for Windows called sudowin. You can freely download sudowin from http://sudowin.sourceforge.net. sudowin works by using the Win32 Terminal Services APIs and in practice acts very much like the Unix sudo system. You can use sudowin at the command line, just like you would use sudo on Unix, but most users will be interested in sudowin's GUI. To use it, right-click on an application as shown in Figure 14-4, and choose Sudo... to get a password dialog box. Enter your user's password as shown in Figure 14-5, and your effective privilege level for that process is elevated.
Unfortunately, as shown in Figure 14-6, sudowin doesn't provide any confirmation message indicating whether your request for elevated privileges was granted.
By default, sudowin allows a user to run Explorer, CMD, Notepad, and Regedit with elevated privileges, but not any other commands. Most people find this pretty limiting and wish to change the configuration. It's too bad that sudowin doesn't come with a configuration GUI. To configure sudowin, you have to edit XML files, typically buried deep in the recesses of your filesystem at C:\Program Files\Sudowin\Server\sudoers.xml. You can either add additional apps to the sudowin configuration file, or take the sledgehammer approach and edit sudoers.xml to allow a user to elevate any program he wants. For example, if your username were bob on the machine named bobsmachine, you would edit the sudoers.xml file to look something like this:
<userGroup name="standard"> <users> <user name="bobsmachine\bob" allowAllCommands="true"/> </users> <!--other parts of the configuration file --> </userGroup>
Yes, this is exactly the same strategy I just advised you not to take with the Unix version of sudo, but for Windows it does make sense. For starters, if you are trying to harden your own machine, and are a member of the Power Users group (which you will in all likelihood want to be a member of ), you should actually have a limited number of cases when you need to elevate your privilege level. Software installs come to mind. Unfortunately, software installers are not all named the same thing in Windows, as opposed to, say, Debian or Red Hat Linux, where most of the software you want to install is done through the apt-get or rpm interfaces. On those systems, you can tell sudo that a user can run rpm or the like, and be done with it. On Windows, every different installer seems to have its own unique name.
Not everything is wine and roses with sudowin. Occasionally, you'll need to run an installer or a system program as Administrator using the traditional Run As... dialog. Usually, this happens with games or device driver installation. I had to do a Run As . . . when installing Silent Hunter III, and for installing drivers for my digital camera. More importantly, sudowin does not give any indication as to which program window is running with elevated privilege. If you have lots of program windows up at the same time, it's easy to lose track of which of them has the special sauce. The documentation at the project's web site is of high quality and explains the entire sudowin architecture in fine-grained detail. I wish more developers spent as much time on their documentation as Mr. Kutz seems to.
If you are thinking of using sudowin on a large corporate network as a full-on replacement for Active Directory permissions, you are probably going to be disappointed with the results, namely because at the time of this writing there does not yet seem to be any convenient way to centrally manage the sudowin configuration through Active Directory.