Skip to content
Linux Capabilities and PrivEsc

Linux Capabilities and PrivEsc

Published: at 09:06 AM

Table of contents

Open Table of contents

Intro

This article will show you how Linux Capabilities work and how to abuse them if there is a misconfiguration.

Linux Capabilities

Instead of granting full access, you can use Capabilities to assign partial permissions. Integrated directly into the kernel starting from version 2.2, Capabilities divide privileges into separate components. For example, if a root user could perform tasks A, B, and C, Capabilities allow you to assign specific permissions to a process. This means you can grant a process only permission A, or a combination such as permissions A and C, without giving it full root access.

Capabilities list

There a lot of different capabilities that you can check in Man Pages (source provided). I will include some examples:

and many others

Thread capability sets

Capabilities have one or more of following sets:

File capabilities

An Executable file can have capabilities, and when it is executed, the process will have associated capabilities. Capabilities to the file is set via setcap. Not all sets can be assigned to the file, only the following can:

setcap

setcap - set file capabilities.

Syntax

Let’s examine commands

# Granting a specific capability to a file
sudo setcap <cap_name>=+<set> /path/to/executable
# Removing a specific capability from a file
sudo setcap <cap_name>=-<set> /path/to/executable
# Setting multiple capabilities
sudo setcap <cap_name_1>,<cap_name_2>=+<set> /path/to/executable
# Viewing the capabilities of a file
getcap /path/to/executable
# Clearing all capabilities from a file
sudo setcap -r /path/to/executable

# <cap_name>
# Capabilities that are defined in Man Page
# <set>
# Legal flags are: e, i and p for effective, inheritable and permitted, respectively
# You can use one flag or mupltiple. Example: <cap_name>=+e, <cap_name>=+ep

Example

Let’s say you want to run python server on port 80. Normally, you will receive following error:

lincap01

To run on port below 1024 you will need to run it with sudo. However, you do not to give full access to the process. You can assign to it following capability:

  1. For the experiment, copy executable to some location.
  2. Set the Capability
  3. Test it

lincap02

PrivEsc with Capabilities

Sometimes Excutables are misconfigured and can have excessive capabilities, and these can be abused to get Privilege Escalation.

Node with CAP_CHOWN

General technique is to think logically. For example, if some binary like python/perl/node has capability to change owner of the file: CAP_CHOWN. You can find a way to execute a command using the programming language to change ownership of sensitive file(for example /etc/shadow).

Lets setup the environment:

lincap03

To abuse it, run the node command, it will prompt interactive command line. Next, use following JavaScript command, which can be easily googled (check sources):

fs.chown(path, <uid>, <gid>, console.log);
// for root it would be 0 0
// and in our case if we want to read shadow file we can supply our user's id
fs.chown('/etc/shadow', 1001, 1001, console.log);

lincap04

And Voila! You found root’s password hash. Then crack it and escalate the privileges.

VIM with CAP_SETUID

Some cases can be complicated, and we cannot know everything to find logic ways to abuse capabilities. So, just search in the internet, a good source would be HackTrick and GTFOBins.

Prepare the environment:

lincap05

In those examples, we know where vulnerable files are located. However, you may think how to find them in unfamiliar environments. Following command can help:

getcap -r / 2>/dev/null

lincap06

To abuse vim, we may check it in GTFOBins and find the following:

lincap07

And running the command gives the shell

./vim -c ':py3 import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

lincap08

Conclusion

I hope it helped to understand how Linux Capabilities work, and methods to abuse them. I covered only the general approach to abuse misconfigured Capabilities:

References