Sudo: Setting Up Intelligent Security Policies Part One
What is Sudo?
Prior to sudo whenever you wanted to run a command as a specific user then you would su (switch user) to gain access to a shell for that user. This of course required that you knew the password for that user, and it would spawn a new shell after successful authentication. The major drawback to this was that in order to allow a user to do something, you had to allow the user to do anything. This sort of configuration also makes it fairly trivial for an authorized user to perform unauthorized actions, such as changing the root password and locking everyone out.
Basically sudo is a setuid binary which allows any user to invoke it as root. Here is where it starts to get a bit tricky. Any user can invoke sudo as root. However that doesn’t mean that any user can invoke anything with sudo as root. Sudo itself is invoked as root, and then the policy processing begins and sudo determines if it is going to do what you are requesting (if it is in policy).
If you remember nothing else about sudo (as a user) then remember this. Sudo allows you to “su and do” without having to “su and do”. This of course means that the below actions are identical in terms of executing the action.
$ su - Password: # whoami root
$ sudo whoami [sudo] password for oracle: root
The only real difference in the above is the password that we enter. In the first example we need to enter the root password. In the second we enter the password of the user we are logged in as.
A great example to illustrate the functionality of sudo is the simple “id” this command simply lists your security contexts. When we execute id
$ id uid=1000(matthew) gid=1000(matthew) groups=1000(matthew),10(wheel),18(dialout),1001(vboxusers)
Above we can see that we are logged in with the user matthew with the uid of 1000. You also see the groups that I am a member of.
$ sudo id [sudo] password for matthew: uid=0(root) gid=0(root) groups=0(root)
Now when we insert sudo in front of the id command we notice that it prompts for a password, specifically the password of the user invoking sudo (in this case matthew). After successful authentication then we see that we actually get the id information for the root user.
There is another major way that sudo can be used. And that is to achieve a root shell.
$ sudo -s [sudo] password for matthew: #
Above we see that we now have a persistent root shell. The big takeaway from this usage is that you lose all of your sudo logging. The only thing that is logged is the execution of the shell (this will be the users shell defined in the /etc/passwd – usually /bin/bash).
# more /var/log/sudo.log Jan 22 16:04:09 : matthew : TTY=pts/8 ; PWD=/home/matthew ; USER=root ; COMMAND=/bin/bash
One of the biggest benefits of sudo is the ability to log what individuals are doing on a system, and thus having the ability to forensically resolve problems based on the actions that were taken just prior to the problem. Here is an example of what the output looks like.
# more /var/log/sudo.log Jan 22 13:25:13 : user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/etc/init.d/network restart Jan 22 13:25:34 : user1 : command not allowed ; TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/etc/init.d/network status
Now we can see that we have a successful execution of /etc/init.d/network restart on line 1. This took place at Jan 22 13:25:13 local time. We also know that it was invoked by the oracle user, while the oracle user was standing in /home/oracle (this is important for anything executed using a relative path). We also then see the user that the command is executed as (which in this case is root).
The second entry we have is an attempt by the oracle user to execute /etc/init.d/network status. This was denied because it is outside the allowance of the sudo policy.
List Effective Sudo Policy
You won’t always be in an environment where you will be able to push for changes to your sudo policies, however it doesn’t mean that you can’t look at the effective ruleset to see what you have in effect. To list the policies as they are in effect against your user.
$ sudo -l Matching Defaults entries for matthew on this host: requiretty, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, logfile=/var/log/sudo.log User matthew may run the following commands on this host: (ALL) ALL
If you are building policies and you want to test the effective policies for a specific user. You can invoke it like so to list the effective policy.
# sudo -U matthew -l Matching Defaults entries for matthew on this host: requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", logfile=/var/log/sudo.log Runas and Command-specific defaults for matthew: User matthew may run the following commands on this host: (root) ALL, (root) !/bin/sh, !/bin/bash, !/bin/bash2, !/bin/ash, !/bin/bsh, !/bin/tcsh, !/bin/csh, !/bin/ksh, !/bin/ksh93, (root) !/bin/su, !/usr/bin/vncserver, (root) !/bin/passwd, !/usr/sbin/useradd, !/usr/sbin/userdel, !/usr/sbin/usermod, (root) !/usr/sbin/visudo
That wraps up Part One. In Part Two we will look at specific policy examples and how they would be used.