Skip to content

Commit

Permalink
Merge pull request #46 from LeChatP/develop
Browse files Browse the repository at this point in the history
Capable: Add json output, many fixes and some tests
  • Loading branch information
LeChatP authored May 18, 2024
2 parents 6e8786f + af319f3 commit 89960df
Show file tree
Hide file tree
Showing 23 changed files with 1,102 additions and 566 deletions.
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@
],
"c-cpp-flylint.clang.includePaths": [
"${workspaceFolder}/src"
]
],
"terminal.integrated.env.linux": {
"PROFILE" : "debug",
"RUST_BACKTRACE" : "1",
}
}
10 changes: 4 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ path = "src/chsr/main.rs"
reqwest = { version = "0.12.4", features = ["blocking", "json"] }
pcre2 = "0.2.4"
regex = "1.9.1"
serde = { version = "1.0.185" }
serde_json = "1.0.113"
serde = { version = "1.0.200" }
serde_json = "1.0.116"

[dependencies]
tracing = "0.1.40"
Expand All @@ -46,11 +46,10 @@ strum = { version = "0.26.2", features = ["derive"] }
semver = { version = "1.0.22", features = ["serde"] }
nix = { version = "0.28.0", features = ["user","process", "signal", "fs"] }
#sudoers-reader = { path = "sudoers-reader" }
clap = { version = "4.5.3", features = ["derive"] }
capctl = "0.2.4"
pcre2 = "0.2.6"
serde = { version = "1.0.197", features=["rc"] }
serde_json = "1.0.114"
serde = { version = "1.0.200", features=["rc"] }
serde_json = "1.0.116"
ciborium = "0.2.2"
glob = "0.3.1"
pam-client = { version = "0.5.0", git = "https://gitlab.com/LeChatP/rust-pam-client.git" }
Expand All @@ -65,7 +64,6 @@ md5 = "0.7.0"
chrono = "0.4.37"
pty-process = "0.4.0"
once_cell = "1.19.0"
crossterm = "0.27.0"
pest = "2.7.8"
pest_derive = "2.7.8"
phf = { version = "0.11.2", features = ["macros"] }
Expand Down
97 changes: 38 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,38 @@
</p>
<!-- markdownlint-restore -->

# RootAsRole (V3.0.0-alpha.4) : a secure alternative to sudo/su on Linux systems
# RootAsRole (V3.0.0-alpha.4) : A memory-safe and security-oriented alternative to sudo/su commands

This tool allows you to configure your privilege access management more securely on a single operating system.
**RootAsRole** is a project to allow Linux/Unix administrators to delegate their administrative tasks access rights to users. Its main features are :

Unlike sudo, this project sets the principle least privilege on its core features. Like sudo, this project wants to be usable. More than sudo, we care about configurators, and we try to warn configurators about dangerous manipulations.
* [A structured access control model based on Roles](https://dl.acm.org/doi/10.1145/501978.501980)
* [Role hierarchy](https://dl.acm.org/doi/10.1145/501978.501980)
* [Static/Dynamic Separation of Duties](https://dl.acm.org/doi/10.1145/501978.501980)
* [Linux Capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) support, to minimize the privileges of the user executing the command.
* Prevent the escalation of privileges via Bounding set manipulation.
* [Highly configurable](chsr/README.md) with a simple command line interface. This interface is designed to be as easy as `ip` command.
* File relocation ability.
* Multi-layered and inheritable execution environment configuration.
* Interoperable and evolvable by using [JSON](https://www.json.org/) as the main configuration file format.
* Command matching based on commonly-used open-source libraries:
* [glob](https://docs.rs/glob/latest/glob/) for binary path
* [PCRE2](https://www.pcre.org/) for command arguments

By using a role-based access control model, this project allows us to better manage administrative tasks. With this project, you could distribute privileges and prevent them from escalating directly. Unlike sudo does, we don't want to give entire privileges for any insignificant administrative task, so you could configure it easily with `capable` command.
## <img src="https://lechatp.github.io/RootAsRole/favicon.svg" width="20px"/> You can find every interesting resources using [the RootAsRole User/Knowledge/Reference Guide Book](https://lechatp.github.io/RootAsRole/).</h2>

## Installation

### How to Build

Requirement: rustc >= 1.70.0

1. git clone <https://github.com/LeChatP/RootAsRole>
1. cd RootAsRole
1. . ./dependencies.sh
1. sudo ./configure.sh
1. make install
1. `git clone <https://github.com/LeChatP/RootAsRole>`
1. `cd RootAsRole`
1. `. ./dependencies.sh`
1. `sudo ./configure.sh`
1. `make install`

Note: The `configure.sh` installs `cargo` and `bpf-linker` rust programs manually into `/usr/local/bin`. You can refuse to install it this way, but these are mandatory to build the program. Depending on your distribution or how you want to install this software, you may know that most rust binaries are installed to `$HOME/.cargo/bin`. When you use sudo to configure, these binaries are installed in the effective user home directory. You may need to move these binaries to a known-user path.
**[What does the installation do?](https://lechatp.github.io/RootAsRole/guide/installation.html#what-does-the-installation-script-do)**

> [!WARNING]
> **This installation process gives by default the entire privileges set for the user which execute sudo. This means that the user which install this program will be privileged.**
Expand Down Expand Up @@ -65,61 +76,40 @@ If you're accustomed to utilizing the sudo tool and find it difficult to break t
alias sudo="sr"
```

```sh
sr chattr -i /etc/security/rootasrole.xml
sr nano /etc/security/rootasrole.xml
```
However you won't find out exact same options as sudo, you can use the `--role` option to specify the role you want to use instead.

This will remove immutable bit flag on the configuration and open text editor for the configuration file.

### How to find out the privileges needed for your command
## Why do you need this tool ?

Use `capable` program, it will listen every capabilities requests and display them to you.
Traditional Linux system administration relies on a single powerful user, the superuser (root), who holds all system privileges. This model does not adhere to the principle of least privilege, as any program executed with superuser rights gains far more privileges than necessary. For example, `tcpdump`, a tool for sniffing network packets, only needs network capabilities. However, when run as the superuser, tcpdump gains all system privileges, including the ability to reboot the system. This excessive privilege can be exploited by attackers to compromise the entire system if tcpdump has vulnerabilities.

The RootAsRole project offers a role-based approach for managing Linux capabilities. It includes the sr (switch role) tool, which allows users to control the specific privileges assigned to programs. This project eliminates the need for sudo and su commands, which do not provide fine-grained control over privileges.

## Feedback
While tools like `setcap` and the `pam_cap` module also manage privileges, they only handle this specific function, which is for limited administrative usages. For example, when you need to use `apt` to install a package, you may not only need cap_dac_override (to read/write files arbitrary) but also to change effective user ID to root. Indeed, without the setuid, every installed file configuration will be owned by the user who executed the command, making file configuration owners inconsistent. This is why the RootAsRole project is essential for managing the entire user credential structure.

You may give us your feedbacks about RootAsRole here:
Additionnally, `setcap` is applied to the binary file, which means that the capabilities are fixed for every program use-case. This is not ideal for a multi-user system, where different users may need different capabilities for the same program.

<https://docs.google.com/forms/d/e/1FAIpQLSfwXISzDaIzlUe42pas2rGZi7SV5QvUXXcDM9_GknPa8AdpFg/viewform>
Furthermore, the `pam_cap` module is applied to the PAM user session, which means that the capabilities are fixed for every user's session. This is not ideal as administrator do not need these capabilities for every commands and every sessions.

## Video presentation of the version 1.0 (in French)
The RootAsRole project is compatible with LSM (Linux Security Modules) such as SELinux and AppArmor, as well as pam_cap.so. Administrators can continue using pam_cap.so alongside our module. Additionally, the module includes the capable tool, which helps users identify the privileges required by an application.

<https://www.youtube.com/watch?v=2Y8hTI912zQ>
### How to configure RootAsRole

## Why do you need this tool ?
You can configure RootAsRole with the `chsr` command. This command permits you to create roles, tasks, and assign them to users or groups. You can find more information about this command in the [Configure RootAsRole](https://lechatp.github.io/RootAsRole/chsr/index.html) section.

Traditionally, administering Linux systems is based on the existence of one powerful user (called superuser) who detains alone the complete list of the system's privileges. However, this administrative model is not respecting the least privilege principle because all programs executed in the context of the superuser obtain much more privileges than they need. For example, tcpdump, a tool for sniffing network packets, requires network capabilities to run. However, by executing it in the context of superuser, tcpdump obtains the complete list of systems' privileges, event reboot functionnality. Thus, the traditional approach of Linux administration breaks the principle of the least privilege that ensures that a process must have the least privileges necessary to perform its job (i.e., sniff packet networks). As a result, an attacker may exploit the vulnerabilities of tcpdump to compromise the whole system when the process of tcpdump possesses the complete list of root privileges.
#### How to Find Out the Privileges Needed for Your Command

RootAsRole module implements a role-based approach for distributing Linux capabilities to users. Our module contains the sr (switch role) tool that allows users to control the list of privileges they give to programs. Thus, with our module, users can stop using sudo and su commands that don't allow controlling the list of privileges granted to programs. Some tools already permit control of the list of privileges to give to programs, such as setcap and pam_cap module. However, these tools necessitate the use of extended attributes to store privileges. Storing privileges in extended attributes causes many different problems (see below motivation scenarios). Our module allows assigning Linux capabilities without the need to store the Linux capabilities in the extended attributes of executable files. Our work leverages a new capability set added to the Linux kernel, Ambient Set.
To determine the privileges required for your command, you can use the capable program. This tool listens for capability requests and displays them to you. Here’s how to use it effectively:

Our module is compatible with LSM modules (SELinux, AppArmor, etc.) and pam_cap.so. So administrators can continue using pam_cap.so along with our module. Finally, the RootAsRole module includes the capable tool, which helps Linux users know the privileges an application asks for.
1. **Run the capable program**: It will monitor and display all capability requests made by your command.

## How do we solve Role conflicts ?
1. **Analyze the output**: Pay close attention to the capabilities requested. It's common to see capabilities like CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH because many programs attempt to access files the user doesn't have permission to read. However, these capabilities are often not essential. Additionally, be aware that the Linux kernel may return the cap_sys_admin capability, even if it is not necessary.

As you may know with this RBAC model, it is possible for multiple roles to reference the same command for the same users. Since we do not ask by default the role to use, our tool applies an smart policy to choose a role using user, group, command entry and least privilege criteria. We apply a partial order comparison algorithm to decide which role should be chosen :
1. **Filter unnecessary capabilities**: Determine if the requested capabilities are truly needed. If they are not, consider switching to an appropriate user with the necessary access rights.

* Find all the roles that match the user id assignment or the group id, and the command input
* Within the matching roles, select the one that is the most precise and least privileged :
1. user assignment is more precise than the combination of group assignment
1. the combination of group assignment is more precise than single group assignment
1. exact command is more precise than command with regex argument
1. command with regex argument is more precise than a wildcarded command path
1. wildcarded command path is more precise than wildcarded command path and regex args
1. wildcarded command path and regex args is more precise than complete wildcard
1. A role granting no capability is less privileged than one granting at least one capability
1. A role granting no insecure capability is less privileged than one at least one insecure capability
1. A role granting insecure capability is less privileged than one granting all capabilities.
1. A role without setuid is less privileged than one has setuid.
1. if no root is disabled, a role without 'root' setuid is less privileged than a role with 'root' setuid
1. A role without setgid is less privileged than one has setgid.
1. A role with a single setgid is less privileged than one that set multiple gid.
1. if no root is disabled, A role with multiple setgid is less privileged than one that set root gid
1. if no root is disabled, A role with root setgid is less privileged than one that set multiple gid, particularly using root group
1. A role that enables root privileges is less privileged than one which disables root privileges (see "no-root" feature)
1. A role that disables the Bounding set feature in RootAsRole is less privileged than one that enables it
1. **Handle missing privileges**: If your program fails to execute due to missing privileges, try granting the specific missing privileges one at a time. Test the program after each change until it works as expected.

After these step, if two roles are conflicting, these roles are considered equal (only the environment variables are different), so configurator is being warned that roles could be in conflict and these could not be reached without specifing precisely the role to choose (with `--role` option). In such cases, we highly recommend to review the design of the configured access control.
By following these steps, you can identify and manage the necessary privileges for your command more effectively.

## Tested Platforms

Expand All @@ -129,17 +119,6 @@ Our module has been tested on:
* Debian>=10
* ArchLinux

After the installation you will find a file called rootasrole.xml in the /etc/security directory. You could configure it with `chsr` command or you could configure this file in order to define the set of roles and assign them to users or group of users on your system. Once configuration is done, a user can assume a role using the ‘sr’ tool that is installed with our package.

## Capable Tool

Since V2.0 of RootAsRole, we created a new tool that permits to retrieve capabilities asked by a program or a service. This can be very important when a user wants to configure the sr tool in order to inject the capabilities requested by a program. Please note that you should pay attention to the output of the tool, especially with regards the cap_sys_admin capability. In most cases, programs don't need this capability but we show it because this what Linux kernel returns to the capable tool.


## [Motivations and Some Working Scenarios](https://github.com/SamerW/RootAsRole/wiki/Motivations-and-Some-Working-Scenarios)

## [How sr and sr_aux work?](https://github.com/SamerW/RootAsRole/wiki/How-sr-and-sr_aux-work)

## Contributors

Ahmad Samer Wazan : <[email protected]>
Expand Down
28 changes: 28 additions & 0 deletions book/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,31 @@ The `chsr` command allows you to configure the roles and capabilities of the sys

By using a role-based access control model, this project allows us to better manage administrative tasks. With this project, you could distribute privileges and prevent them from escalating directly. Unlike sudo does, we don't want to give entire privileges for any insignificant administrative task. You can configure our tool easily with `chsr` command. To find out which capability is needed for a administrative command, we provide the `capable` command. With these two tools, administrators could configure its system to respect the least privilege principle.


## Scenarios

### Scenario 1: Personal usage

You are using your personal computer and you want to install a new package. By default, RootAsRole add one role with 2 tasks : one task for using `chsr` command that grant only the `CAP_LINUX_IMMUTABLE` capability as `root` user (unprivileged), and one task for all commands but without `CAP_LINUX_IMMUTABLE` privilege.

```bash
sr apt install <package>
```

### Scenario 2: System administrator of a company

You are the system administrator of a company and you want to delegate the right to restart the server to a user. You can use `chsr` to create a role and grant the right to restart the server to users.

```bash
sr chsr role r_users add # Create a new role
sr chsr role r_users grant -g users # Grant the role to the group users
sr chsr role r_users task t_reboot add # Create a new task
sr chsr role r_users task t_reboot command whitelist add reboot # Add the reboot command to the task
sr chsr role r_users task t_reboot cred caps whitelist add CAP_SYS_BOOT # Add the CAP_SYS_BOOT capability to the task
```

Then users can restart the server with the following command:

```bash
sr reboot
```
2 changes: 1 addition & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- [Installation](guide/installation.md)
- [`sr` Command Line Tool](sr/README.md)
- [`chsr` Command Line Tool](chsr/README.md)

- [`capable` Command Line Tool](capable/README.md)

# Knowledge Guide

Expand Down
35 changes: 35 additions & 0 deletions book/src/capable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Capable tool usage

<pre style="white-space: pre-wrap;">
<b><u>Usage:</u></b> capable [OPTIONS] [COMMAND]...

<b><u>Arguments:</u></b>
[COMMAND]... Specify a command to execute with arguments

<b><u>Options:</u></b>
<b>-s, --sleep</b> <SLEEP> Specify a delay before killing the process
<b>-d, --daemon</b> collecting data on system and print result at the end
<b>-j, --json</b> Print output in JSON format, ignore stdin/out/err
<b>-h, --help</b> Print help (see more with '--help')
</pre>

## Examples

```bash
$ capable -j cat /etc/shadow
["CAP_DAC_OVERRIDE","CAP_DAC_READ_SEARCH"]
```

#### How to Find Out the Privileges Needed for Your Command

To determine the privileges required for your command, you can use the capable program. This tool listens for capability requests and displays them to you. Here’s how to use it effectively:

1. **Run the capable program**: It will monitor and display all capability requests made by your command.

1. **Analyze the output**: Pay close attention to the capabilities requested. It's common to see capabilities like CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH because many programs attempt to access files the user doesn't have permission to read. However, these capabilities are often not essential.

1. **Filter unnecessary capabilities**: Determine if the requested capabilities are truly needed. If they are not, consider switching to an appropriate user with the necessary access rights.

1. **Handle missing privileges**: If your program fails to execute due to missing privileges, try granting the specific missing privileges one at a time. Test the program after each change until it works as expected.

By following these steps, you can identify and manage the necessary privileges for your command more effectively.
9 changes: 9 additions & 0 deletions book/src/misc/misc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Video presentation of the version 1.0 (in French)

<https://www.youtube.com/watch?v=2Y8hTI912zQ>

## Feedback

You may give us your feedbacks about RootAsRole here:

<https://docs.google.com/forms/d/e/1FAIpQLSfwXISzDaIzlUe42pas2rGZi7SV5QvUXXcDM9_GknPa8AdpFg/viewform>
Loading

0 comments on commit 89960df

Please sign in to comment.