Less known Solaris features: RBAC and Privileges - Part 3: Privileges
We´ve talked a lot about RBAC, roles, role profiles. But what are Privileges? Privileges are rights to do an operation in the kernel. This rights are enforced by the kernel. Whenever you do something within the kernel the access is controlled by the privileges. At the moment, the the rights to do something with the kernel are seperated into 70 classes:
Every UNIX-System does this task hidden behind this privileges. There are many different privileges in the kernel. This privileges are not Solaris specific. It´s the way to control the access to this privileges.
On conventional unix systems you have a root user, he has all privileges. And you have a normal user, who has only a limited set of privileges. Sometimes you need the rights of an admin to do some tasks. You don´t even need to admin the system. You can only traceroute or ping a system, because both tools are setuid tools
setuid is nothing else than a violation of the security policy. You need a special privilege to ping: The privilege to use access ICMP. On conventional system this right is reserved to the root user. Thus the ping program has to be executed with the rights of root. The problem: At the time of the execution of the programm, the programm has all rights of the user. Not only to access ICMP, the programm is capable to do everything on the system, as deleting files in /etc. This may not a problem with ping or traceroute but think about larger programs. An exploit in a setuid program can lead to the escalation of the users privileges. Setuid root and you are toast.
Let´s have a look at the privileges of an ordinary user. There is a tool to get the privileges of any given process in the system, it´s called
ppriv. $$ is a shortcut for the actual process id (in this case the process id of the shell):
Every process in the system has four sets of privileges that determine if a process is enabled to use a priviliege or not. The theory of privileges is quite complex. i would suggest to read the chapter “How Privileges Are Implemented” in the Security Services manual to learn, how each set controls or is controlled other privilege sets. At this time, i want only to explain the meaning of the first letter:
- E: effective privileges set
- I: inheritable privileges set
- P: permitted privileges set
- L: limit privileges set
You can think about the privilege sets as keyrings. The effective privilege set are the keys the janitor has on it´s keyring. The permited privilege set are the keys the janitor is allowed to put on it´s keyring. The janitor can decide to remove some of the keys. Perhaps he thinks: I work only in room 232 today. I don´t need all the other keys. I leave them in my office. When he looses his keyring he lost only the control about this single room, not about the complete campus.
The inheritable privilege is not a really a keyring. The janitor thinks about his new assistant: “Good worker, but i won´t give him my key for the room with the expensive tools.” The limited privilege set is the overarching order from the boss of janitor to his team leaders: “You are allowed to give your assistant the keys for normal rooms, but not for the rooms with all this blinking boxes from Sun”.
At the moment the most interesting set is the E:. This is the effective set of privileges. This is the set of privilege effectively available to process. Compared to the full list of privileges mentioned above the set is much smaller. But this matches your experience when you use a unix system.
Some practical insighs to the system
You logged in as a normal user, and you have only a few privileges. It´s called the basic set.
Okay, this example looks different than the one shown before. Nevertheless is has the same meaning. With the switch
-v you can expand the aliases.
Looks a little bit more familiar? Okay, now let´s login as root.
This user has much more privileges. The effective set is much broader. The user has all privileges in the system.
How to give an user additional privileges
Now let´s assume, you have an user, that wants to use dtrace. You need three privileges to use Dtrace: dtrace_kernel,dtrace_proc,dtrace_user. root has this privileges. A normal user not. Giving root to a developer? God beware! This is a prelude to disaster. But no problem. Assign the matching privileges to the user, and the user is enabled to use dtrace.
Exit to the login prompt and login as the user you´ve assigned the privilieges
RBAC and privileges combined
Well, but we can do better than that. We´ve learned there is a thing like RBAC. There is no reason that inhibits the assignment of privileges to a role. At first we create a role bughunt, for simplicity we use the Process Management role profile. After this we set the role password.
Now we assign the privileges …
… and the user to the role.
As you might have espected, the user itself doesn´t have the privileges to use dtrace.
But now assume the role
And DTrace is at your service.
The idea of managing the privileges is not limited to users and their shells. In any given system you find dozens of programs as daemons. These daemons interact in several ways with the privileges. The best way is “Privilege-aware programming”. Okay. Let´s assume, you code a daemon for your system. For example: You know, that you never will do an exec() call. So you can safely drop this privilege. The process modifies the permited privilege set. The process can remove a privilege but not add it. Even when someone is able to your code, the attacker can´t make an exec() call. The process doesn´t even have the privilege to do such a call. And the attacker can´t add the privilege again. Several processes and programs in Solaris are already privilege aware. For example the kernel-level cryptographic framework daemon. Let´s look at the privileges of the daemon.
This daemon doesn´t have even the basic privileges of a regular user. It has the only the bare minimum of privileges to do it´s job.
Non-privilege aware processes
But the world isn´t perfect. Not every process is privilege aware. Thus you have to limit the privileges by other mechanisms. The service management framework comes to help. The following example is copied from Glen Brunettes Blueprint Limiting Service Privileges in the Solaris 10 Operating System
Let´s take the Apache Webserver as an example. The apache isn´t privilege aware. We start the daemon via the Service Management Framework.
Okay, now we look at the processes of the Apache daemons.
Six daemons running as webservd, and one running as root.
As expected for a root process, this process has the complete set of privileges of a root user. Okay, now one of it´s child.
Much better … only basic privileges.
Okay, There is a reason for this configuration. On Unix systems, you have two groups of ports. Privileged ones from 1-1023 and unprivileged ones from 1024 up. You can only bind to a privileged port with the privilege to do it. A normal user doesn´t have this privilege, but root has it. And thus there has to be one process running as root. Do you remeber the list of privileges for the apache process running at root. The process has all privileges but needs only one of them, that isn´t part of the basic privilege set.
How to get rid of the root apache
Well, but it hasn´t to be this way. With Solaris you can give any user or process the privilege to use a privileged port. You don´t need the root process anymore. Now, let´s configure it this way. At first we have to deactivate the runing apache.
I won´t explain the Service Management Framework here, but you can set certain properties in SMF to control the startup of a service.
Line 2 to 4 are the most interesting ones. Without any changes, the Apache daemon starts as root and forks away processes with the webservd user. But we want to get rid of the root user for this configurtion. Thus we start the daemon directly with the webservd user. Same for the group id.
Now it gets interesting. Without this line, the kernel would deny Apache to bind to port 80. webservd is a regular user without the privilege to use a privileged port. The property start/privileges sets the privileges to start the service. At first, we give the service basic privileges. Then we add the privilege to use a privileged port. The service would start up now.
But wait, we can do more. A webserver shouldn´t do any hardlinks. And it doesn´t send signals outside it´s session. And it doesn´t look at processes other than those to which it can send signals. We don´t need this privileges. proc_session, proc_info and file_link_any are part of the basic privilege set. We remove them, by adding a
! in front of the privilege.
Okay, we have notify the SMF of the configuration changes:
Until now, the apache daemon used the root privileges. Thus the ownership of files and directories were unproblematic. The daemon was able to read and write in any directory of file in the system. As we drop teis privilege by using a regular user, we have to modify the ownership of some files and move some files.
We need some configuration changes, too. We have to move the LockFile and the PidFile. There wasn´t one of the two configuration directives in my config file, thus i´ve simply appended them to the end of the file.
Okay, everything is in place. Let´s give it a try.
Now we check for the running httpd processes:
You notice the difference ? There is no httpd running as root. All processes run with the userid webservd. Mission accomplished.
Let´s check the privileges of the processes. At first the one, who ran as root before.
Only the least privileges to do the job, no root privileges.
And even the other processes are more secure now:
Before we changed the configuration of the webserver, it has the basic privileges of a regular user. Now we limited even this set.