Traditionally, a Linux process is either privileged (running as root) or unprivileged. Privileged processes are not subject to kernel permission checks, and thus have full power over a system. A capability is a distinct and independent privilege that can be used by a process to bypass certain permission checks. Capabilities were first introduced in Linux 2.2, and several more were added in later versions. They are usually set on executable files and are automatically granted to the process when a file with a capability is executed. Capabilities essentially divide the power of the root user into separate privileges, which improves security by limiting the access an attacker would gain by exploiting or abusing a service.
This guide will introduce some commonly used capabilities and demonstrate how they can be viewed and modified.
Common Capabilities
The Linux kernel implements a multitude of capabilities. Some of them are:
- CAP_SYS_ADMIN: Allows a wide range of operations. This capability should be avoided in favor of more specific capabilities.
- CAP_CHOWN: Make changes to the User ID and Group ID of filesÂ
- CAP_DAC_READ_SEARCH: Bypass file read, and directory read/execute checks. A program with this capability can be used to read any file on the system.
- CAP_DAC_OVERRIDE: Override DAC (Discretionary Access Control) i.e. bypass read/write/execute permission checks. This capability grants an executable the ability to access and modify any file on the filesystem.
- CAP_NET_BIND_SERVICE: Allows binding to port numbers lower than 1024.
- CAP_KILL: Bypass permission checks for sending signals to processes such as SIGHUP and SIGKILL.
- CAP_SYS_NICE: Modify the niceness value and scheduling priority of processes among others.
- CAP_SYS_RESOURCE: Allows overriding various limits on system resources, such as disk quotas, CPU time limits, etc.
The full list is available in the capabilities(7) manual page.
Files can be assigned capabilities in 3 different sets: permitted, inheritable, and effective. Threads have 2 additional sets: ambient and bounding. Each set can contain zero or more capabilities, with the exception of the effective set for files, which actually is a single bit. These sets define complex kernel behaviors which are beyond the scope of this guide. When assigning capabilities to files, we will use the permitted and effective sets in most cases.
NOTE: SELinux can interfere with capabilities. On systems with SELinux in enforcing mode, it may prevent processes from taking advantage of their capabilities.
Required Tools
Two different packages exist for capability management: libcap and libcap-ng. The latter is designed to be easier than the former. Both are covered in this guide.
libcap provides getcap and setcap for viewing and setting file capabilities, while libcap-ng consolidates both functions in one tool, filecap.
libcap
Installation
On Debian, Ubuntu and other Debian-based distributions, the libcap utilities can be installed with:
apt update apt install libcap2-bin
To install on CentOS, use the following command:
yum install libcap
To install on Fedora, use the following command:
dnf install libcap
To install on Arch, use the following command:
pacman -Sy libcap
Usage
getcap simply displays the capabilities assigned to a file, if any. Use the following syntax:
getcap /path/to/binary
For example:
Getcap can also search recursively with the -r flag. For instance:
NOTE: 2>/dev/null is used to avoid cluttering the output with "Operation not supported" errors, which occur when getcap tries to get the capabilities of files in /sys, /proc, etc. These special virtual filesystems do not support capabilities.
To set file capabilities with setcap, use the following syntax:
setcap CAP+set filename
For example, to add CAP_CHOWN and CAP_DAC_OVERRIDE to the permitted and effective sets, use:
setcap CAP_CHOWN,CAP_DAC_OVERRIDE+ep file1
To remove capabilities from a file, use the -r flag:
setcap -r filename
Here are a few additional examples:
libcap-ng
Installation
To install on Debian, Ubuntu and other Debian-based distributions:
apt update apt install libcap-ng-utils
To install on CentOS:
yum install libcap-ng-utils
To install on Fedora:
dnf install libcap-ng-utils
To install on Arch:
pacman -Sy libcap-ng
Usage
- The filecap program refers to capabilities without the "CAP_" prefix (for instance, NET_ADMIN instead of CAP_NET_ADMIN).
- filecap does not work with relative paths, it expect the full path when passing files or directories as arguments.
- filecap does not allow you to specify capability sets, it always uses permitted and effective when setting capabilities.
To view the capabilities assigned to a file:
filecap /full/path/to/file
To search a directory recursively, use:
filecap /full/path/to/dir
To search the whole filesystem with filecap, use one of the following commands:
filecap / filecap -a
Here are a few examples of using filecap to examine files and directories:
To set a capability on a file, use the syntax:
filecap /full/path/to/file cap_name
For example:
filecap /usr/bin/tac dac_override
To remove capabilities, use this syntax:
filecap /full/path/to/file none
Here are a few examples of setting and remove capabilities using filecap:
Conclusion
Capabilities are a powerful kernel feature with wide security applications. They should be substituted for full privileges and root SUID whenever possible.