Objective: The objective of this lab is for students to gain a better understanding of capabilities though first-hand experiences with the capability mechanism in Linux.
Grading: Each question below is worth 1 point, except for question 5, which is worth 5 points.
This lab has been modified by Andrew Kalafut from the original "Linux Capibility Exploration Lab" written by Wenliang Du of Syracuse University. Copyright 2013 Andrew Kalafut. Copyright ©2006 - 2011 Wenliang Du, Syracuse University. The development of the original document is/was funded by three grants from the US National Science Foundation: Awards No. 0231122 and 0618680 from TUES/CCLI and Award No. 1017771 from Trustworthy Computing. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation. A copyof the license can be found at http://www.gnu.org/licenses/fdl.html.
This lab should be done on the SEED project VMWare images available on the EOS computers. Please do all steps in the SEED VM. Pay careful attention to which steps to run as root and which as a normal user.
Capability features are provided by the library libcap. A few useful commands also come with this library:
In operating systems, there are many privileged operations that can only be conducted by privileged users. Examples of privilegd operations include configuring network interface card, backing up all the user files, shutting down the computers, etc. Without capabilities, these operations can only be carried out by superusers, who often have many more privileges than what are needed for the intended tasks. Therefore, letting superusers to conduct these privileged operations is a violation of the Least-Privilege Principle.
Privileged operations are very necessary in operating systems. All Set-UID programs invole privileged operations that cannot be performed by normal users. To allow normal users to run these programs, Set-UID programs turn normal users into powerful users (e.g. root) temporarily, even though that the involved privileged operations do not need all the power. This is dangerous: if the program is compromised, adversaries might get the root privilege.
Capabilities divide the powerful root privilege into a set of less powerful privileges. Each of these privileges is called a capability. With capabilities, we do not need to be a superuser to conduct privileged operations. All we need is to have the capabilities that are needed for the privileged operations. Therefore, even if a privileged program is compromised, adversaries can only get limited power. This way, risk of privileged program can be lowered quite significantly. Capabilities have been implemented in Linux for quite some time, but they could only be assigned to processes. Since kernel version 2.6.24, capabilities can be assigned to files (i.e., programs) and turn those programs into privileged programs. When a privileged program is executed, the running process will carry those capabilities that are assigned to the program. In some sense, this is similar to the Set-UID files, but the major difference is the amount of privileged carried by the running processes.
In a capability system, when a program is executed, its corresponding process is initialized with a list of capabilities (tokens). When the process tries to access an object, the operating system check the process’ capabilities, and decides whether to grant the access or not.First, login as a normal user, and run the following command:
The program should run successfully. If you look at the file attributes of the program
/bin/ping, you will find
ping is actually a Set-UID program with the owner being root, i.e., when you execute
effective user id becomes root, and the running process is very powerful. If there are vulnerabilities in
entire system can be compromised. The question is whether we can remove these privileges from
/bin/ping into a non-Set-UID program. This can be done via the following command as root (you can log in as root by running
chmod u-s /bin/ping
Now, run ping again (as a normal user), and see what happens. Interestingly, the command will not work. This is because ping needs to open a RAW socket. Assign the cap net raw capability to ping with the following command (as root):
setcap cap_net_raw=ep /bin/pingThe ping command should work again.
Several other programs run as Set-UID as well. You can find them with the command
find /usr/bin /bin -perm -4000 Choose one of these and remove the Set-UID bit using chmod.
A short description of each capability is available in
/usr/include/linux/capablity.h. Take a look at this file and determine which capabilities the program you chose should need.
Without capabilities, a privileged Set-UID program can also delete/disable/enable its own privileged. This is done via the setuid() and seteuid() system calls; namely, a process can change its effective user id during the run time. The granularity is quite coarse using these system calls, because you can either be the privileged users (e.g. root) or a non-privileged users. With capabilities, the privileges can be adjusted in a much finer fashion, because each capability can be independently adjusted.
To support dynamic capability adjustment, Linux uses a mechanism similar to the Set-UID mechanism, i.e., a process carries three capability sets: permitted (P), inheritable (I), and effective (E). The permitted set consists of the capabilities that the process is permitted to use; however, this set of capabilities might not be active. The effective set consists of those capabilities that the process can currently use (this is like the effective user uid in the Set-UID mechanism). The effective set must always be a subset of the permitted set. The process can change the contents of the effective set at any time as long as the effective set does not exceed the permitted set. The inheritable set is used only for calculating the new capability sets after exec(), i.e., which capabilities can be inherited by the children processes.
Download and compile use_cap.c. The program can be compiled by running
gcc -o use_cap use_cap.c /lib/libcap.a. Read the program, grant it the cap_dac_read_search capabilty (you will need to be root to do this), and run it as a normal user (not root).