Making Root Unprivileged

Mitigate the damage of setuid root exploits on your system by removing root's privilege.
The Privileged Root

As mentioned previously, Linux continues to emulate a privileged root user. This is done by perverting the capabilities behavior of exec() and setuid(). Briefly, if your effective userid is 0 when you execute a file, or if you execute a setuid root file, your permitted and effective sets are filled. If only your “real” userid is 0 (for instance, a root-owned process executes a setuid-nonroot file), only your permitted set is filled. When you change part of your userid from root to nonroot, your effective capability set is cleared. When you permanently change your userid from root to nonroot, your permitted set is cleared as well. And, if you switch your effective userid back to root, your permitted set is copied back into your effective set.

This behavior is controlled by a per-process set of securebits. One controls the setuid() behavior, and another controls the exec() behavior. They can be turned on using prctl(), and they can be locked such that neither the task nor its descendants can turn the bits back off.

System Preparation

In order to exploit POSIX capabilities fully, both kernel and userspace must be set up properly. The easiest and safest way to experiment with such core changes is to do so in a virtual machine. Although everything shown here could just as well be done on your native Linux installation, for simplicity, I assume you are installing a minimal, stock Fedora system under qemu or kvm.

My first working prototype of a rootless system was done on a Gentoo system. Ubuntu Intrepid and SLES11 should come with file capabilities enabled. However, Fedora 10 wins as being the most capability-ready distribution to date, so I use it for this demonstration. To get started, download a Fedora 10 DVD from download.fedoraproject.org (call the file f10.iso), then create a qemu hard disk image and boot kvm using:

# qemu-img create f10.img 6G
# kvm -hda f10.img -cdrom f10.iso -m 512M -boot d

Then, proceed with the Fedora installation instructions. Make sure to install software development, and skip office and productivity tools for this image.

After rebooting, disable SELinux through the menu entries System→Administration→SELinux management. Change the top entry from Enforcing to Disabled, then reboot. Although there is no inherent reason why SELinux cannot be used with file capabilities, it does require some SELinux policy modifications.

Because you will be removing the root user's privilege, you'll want other users to receive ambient privileges at login. This is done using the pam_cap.so PAM module. To enable its use, add the line:

auth required pam_cap.so

to /etc/pam.d/system-auth. The order of these entries does matter, and improper order can prevent your entry from being used. I made it the second entry, after pam_env.so. Now, test by creating a user with some privilege:

# adduser -m netadmin
# passwd netadmin
# for f in /sbin/ifconfig /sbin/ip /sbin/route; do
#   setcap cap_net_admin=ei $f
# done

The above creates user netadmin and sets his password, then adds the cap_net_admin capability to the inheritable and effective sets for three network configuration programs. If you now type ls /sbin/ifconfig, you'll notice the entry is marked in red. This is similar to how setuid binaries, such as /bin/ping, are marked, and it's a nice touch to let you easily tell which binaries ought to be treated with extra care or to detect mistaken privilege leakage.

You also must create the /etc/security/capability.conf file, which pam_cap.so will consult on each login. The file should contain:

cap_net_admin netadmin
none *

The first line says that when user netadmin logs in, pam_cap.so should add the cap_net_admin capability to pI for its login shell. The second line, which is very important, says that everyone else (*) should receive no capabilities. Now, log in as user netadmin and play with the network:

hallyn@kvm# su - netadmin
netadmin@kvm# ifconfig eth0 down

Success! You just downed the network as a nonroot user.

Now you're ready to make root unprivileged. As a first step, you will just restrict network logins over SSH. To make this as easy as possible, simply start sshd through a wrapper that sets and locks all securebits before calling the real sshd. The source for the wrapper is shown in Listing 1.

______________________

Webcast
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers

Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.

Learn More

Sponsored by AMD

White Paper
Red Hat White Paper: Using an Open Source Framework to Catch the Bad Guy

Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6

Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.

Learn more about catching the bad guy in this free white paper.

Learn More

Sponsored by DLT Solutions