Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining a threat model #279

Open
vam67423 opened this issue Jan 22, 2024 · 8 comments
Open

Defining a threat model #279

vam67423 opened this issue Jan 22, 2024 · 8 comments

Comments

@vam67423
Copy link

Looking through this repository and reading the documentation has left me wondering what the threat model for this project might be.
To cite the concept documented here https://apparmor.pujol.io/concepts.html
We take inspiration from the [Android/ChromeOS Security Model](https://arxiv.org/pdf/1904.05572v2.pdf), and we apply it to the Linux world
The Android security model has well defined security boundaries that specifies what objects (files, contacts, devices like cameras) can be used by which application. The resulting architecture ensures that both apps and services are isolated without any known ways to escape the isolation.

Reading the profiles in this repository, most rule sets allow several ways to escape the isolation through IPC methods, writeable configurations or device files. I'm trying to see the benefit in this approach as it does not seem like any of the profiles are intended to prevent this escape, so all they do is to close a few of the most direct attack vectors while leaving plenty open to circumvent the isolation completely. (I very much like the audit logging in combination with apparmor that is basically a decent IDS, though this does not seem to be the focus either)

Related to this is also the question what benefit it has to isolate services without major attack surfaces (parsing file formats or connecting to the net) like top or administration tools like lvm. To extend the question, why isolate root applications at all when they can simply remove the apparmor filter altogether?

Rule 3: Do not confine everything
    Some programs should not be confined by a MAC policy.
Some programs should not be confined by themselves. For example, tools such as ls, rm, diff or cat do not have profiles in this project. Let's see why.

These are general tools that in a general context can legitimately access any file in the system. Therefore, the confinement of such tools by a global profile would at best be minimal at worst be a security theater.

From my perspective, this would include most profiles currently present in this repository, especially the administration tools like systemd-*, lvm and everything that required root to begin with.

Perhaps I am just overlooking something big here in which case the documentation may need an update to specify what use case this project intends to serve.

In any case, I would like to add that this repository seems to be the only available collection of apparmor profiles that appear to be well maintained and I appreciate the work put into this (documentation is especially well put together).

@roddhjav
Copy link
Owner

I am still working on the formalization of the threat model. However, I presented a wide overview of the security model at my talk at the LSS (see slide 6 of the LSS presentation). It is nothing fancy, it simply tries to apply the concepts behind Android/ChromeOS/ClipOS on a classic linux. AppAmor (or SElinux) is only a MAC system, therefore, it cannot implement by itself the full security construction (that is not the purpose of this project anyway).

The Android security model has well defined security boundaries that specifies what objects (files, contacts, devices like cameras) can be used by which application. The resulting architecture ensures that both apps and services are isolated without any known ways to escape the isolation.

This is exactly what this project is trying to do. All resources are defined under variables or abstractions.

most rule sets allow several ways to escape the isolation through IPC methods, writeable configurations or device files.

Can you give example of such escape? The current architecture allows some escape but mostly due to rules such as @{bin}/* rPUx, they are the only way to not break a system. Similarly, the shell in your every day terminal is never confined.

From my perspective, this would include most profiles currently present in this repository, especially the administration tools like systemd-*, lvm and everything that required root to begin with.

That's not how apparmor (or SElinux) works. AppArmor restrictions apply to everyone, root or not. A confined process needs the mac_admin capability to be able to update an AA profile. (there are other restrictions too: it is usually not possible to remove a profile loaded into the kernel - that depends on the distribution -)

(Note: there is exactly the same construction with SELinux on Fedora and on Android/ChromeOS)

Ultimately, you can even remove the root user and only consider capability based program. Eg:

  • A firewall only need the net_admin capability.
  • A web server only need net_bind_service
  • Updating the AA profile is only allowed by program with the mac_admin capability

Related to this is also the question what benefit it has to isolate services without major attack surfaces (parsing file formats or connecting to the net) like top or administration tools like lvm.

A lot of profiles are needed as dependencies of other bigger program. For example, ps is needed by about 20 profiles. As the program action does not depend on the context, we can allow a simple transition to ps: @{bin}/ps rPx. Otherwise, we would need to include all ps access (meaning /proc/@{pids}/** and sys_ptrace) in the parent profiles.

Also, it is both more secure and easier to work with a profile architecture that consist of a lot of simple profiles than a few set of big profiles (that would need to allow everything).

Finally, the end goal of the project is to prevent the execution of a process that does not have a profile. This requires to have simple basic profiles - or to put everything in a single profile that would not confine anything -

@vam67423
Copy link
Author

I am still working on the formalization of the threat model. However, I presented a wide overview of the security model at my talk at the LSS (see slide 6 of the LSS presentation). It is nothing fancy, it simply tries to apply the concepts behind Android/ChromeOS/ClipOS on a classic linux. AppAmor (or SElinux) is only a MAC system, therefore, it cannot implement by itself the full security construction (that is not the purpose of this project anyway).

The Android security model has well defined security boundaries that specifies what objects (files, contacts, devices like cameras) can be used by which application. The resulting architecture ensures that both apps and services are isolated without any known ways to escape the isolation.

This is exactly what this project is trying to do. All resources are defined under variables or abstractions.

most rule sets allow several ways to escape the isolation through IPC methods, writeable configurations or device files.

Can you give example of such escape? The current architecture allows some escape but mostly due to rules such as @{bin}/* rPUx, they are the only way to not break a system. Similarly, the shell in your every day terminal is never confined.

Any unfiltered access to IPC services like dbus, X11 or write permissions in @HOME (with access to configuration files). Terminal device files are also an issue. I'm certain there are more but these are the few I read about here

If preventing these escapes is an objective there is probably quite a few profiles that are affected and I'm not sure it can even be prevented without restricting the expected functionality in some cases.

From my perspective, this would include most profiles currently present in this repository, especially the administration tools like systemd-*, lvm and everything that required root to begin with.

That's not how apparmor (or SElinux) works. AppArmor restrictions apply to everyone, root or not. A confined process needs the mac_admin capability to be able to update an AA profile. (there are other restrictions too: it is usually not possible to remove a profile loaded into the kernel - that depends on the distribution -)

(Note: there is exactly the same construction with SELinux on Fedora and on Android/ChromeOS)

Ultimately, you can even remove the root user and only consider capability based program. Eg:

* A firewall only need the `net_admin` capability.

* A web server only need `net_bind_service`

* Updating the AA profile is only allowed by program with the `mac_admin` capability

If a process has permissions for a subset of privileged actions (like capabilities) there is often a way to work around it.
For example if I can mount filesystems (or write to fstab) I can probably mount a new profile and just need to wait for it to be reloaded (or until the next boot circle)

For many capabilities there are ways to become full root which makes capabilities difficult to access.
There are some comprehensive explanations about this in these papers:
https://research.nccgroup.com/wp-content/uploads/2020/07/ncc_group_understanding_hardening_linux_containers-1-1.pdf
https://research.nccgroup.com/wp-content/uploads/episerver-images/assets/e675596b59cf4e2eb306412316e32969/e675596b59cf4e2eb306412316e32969.pdf

If I recall it correctly among the affected capabilities that allow to gain full root are net_admin and sys_ptrace

Related to this is also the question what benefit it has to isolate services without major attack surfaces (parsing file formats or connecting to the net) like top or administration tools like lvm.

A lot of profiles are needed as dependencies of other bigger program. For example, ps is needed by about 20 profiles. As the program action does not depend on the context, we can allow a simple transition to ps: @{bin}/ps rPx. Otherwise, we would need to include all ps access (meaning /proc/@{pids}/** and sys_ptrace) in the parent profiles.

Also, it is both more secure and easier to work with a profile architecture that consist of a lot of simple profiles than a few set of big profiles (that would need to allow everything).

That makes sense

Finally, the end goal of the project is to prevent the execution of a process that does not have a profile. This requires to have simple basic profiles - or to put everything in a single profile that would not confine anything -

Not sure I see the big picture yet but I suspect there is some benefit to it, even if I am uncertain how much exactly, especially due to the point about capabilities above. It probably makes exploitation harder by requiring additional steps at the very least.

@roddhjav
Copy link
Owner

roddhjav commented Jan 26, 2024

Any unfiltered access to IPC services like dbus, X11 or write permissions in @HOME (with access to configuration files). Terminal device files are also an issue. I'm certain there are more but these are the few I read about here

If preventing these escapes is an objective there is probably quite a few profiles that are affected and I'm not sure it can even be prevented without restricting the expected functionality in some cases.

I am not claiming the current rules are perfect. However, all of this is already in place:

  • All IPC rules are already as strict as they can be: network, signal, ptrace, dbus, mqueue
  • Terminal is only given to program that require it (apparmor may not be the best tool for this)
  • Files access is as limited as possible

People usually complain because it is too paranoid... not too weak.

You are more than welcome to give example of thing that could be improved. Ideally, I could even write a linter to autodetect possible issue in profiles.

If a process has permissions for a subset of privileged actions (like capabilities) there is often a way to work around it.
For example if I can mount filesystems (or write to fstab) I can probably mount a new profile and just need to wait for it to be reloaded (or until the next boot circle)

If I recall it correctly among the affected capabilities that allow to gain full root are net_admin and sys_ptrace

This is sys_admin that is well known to be overloaded. However:

  • You still need it every time you want to mount something.
  • That's more an issue for the dev: If a program require it, blocking it in apparmor would simply break the program.

Furthermore, please note that having a given capability is usually not enough. For example:

  • A program that want to mount something needs: sys_admin, a specific mount/umount rule, and access to the path the mount takes place.
  • To update the AA profile, one needs mac_admin and a write access to some files in @{sys}/kernel/security/apparmor/. Another way would be to directly write compiled profile to the apparmor cache (in /etc/apparmor/cache.d). But as with everything that is in /etc not a lot of program can do this. Actually, only some apparmor tool and the package manager of the distribution have access to this.
  • To write kernel logs one needs audit_write and a write access to /var/log/

So the risk is more to have rules that would be too wide (eg: mount, instead of mount fstype=fuse.portal -> @{run}/user/@{uid}/doc/, )

To me, as of today, the risk would come more from an unconfined process than to a profile that is too weak. Again, it does not mean they are all perfect...

@vam67423
Copy link
Author

vam67423 commented Jan 27, 2024

Any unfiltered access to IPC services like dbus, X11 or write permissions in @HOME (with access to configuration files). Terminal device files are also an issue. I'm certain there are more but these are the few I read about here
If preventing these escapes is an objective there is probably quite a few profiles that are affected and I'm not sure it can even be prevented without restricting the expected functionality in some cases.

I am not claiming the current rules are perfect. However, all of this is already in place:

* All IPC rules are already as strict as they can be: network, signal, ptrace, dbus, mqueue

* Terminal is only given to program that require it (apparmor may not be the best tool for this)

* Files access is as limited as possible

After reviewing the profiles I do admit that most are a lot better then I initially thought, especially the file permissions.
The consoles abstraction was one of the concerns, but to my surprise even that isn't as easy to exploit anymore, or at least the usual TIOCSTI trick does not work on the current arch linux anymore, possibly due to a recent change in the kernel
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=83efeeeb3d04

You are more than welcome to give example of thing that could be improved.

Any profile that includes abstractions/X or abstractions/X-strict while running X11 is vulnerable to both sandbox escape and possible priv escalation in case of an available root shell in an X11 window.

POC:

  1. open xterm with a root shell inside
  2. in a different shell and as a normal user run the script below while inside an apparmor confinement with X-strict abstraction:
    (note you need to allow xdotool and bash as well for simplicity since we are not bringing actual payload with us)
#!/bin/bash

## howto: enter the name of target application as argument
## e.g.
## ./X11Injection.sh xterm

windowid=$(xdotool search --class $1)
xdotool windowactivate --sync $windowid type --delay 100 'id'
xdotool windowactivate --sync $windowid key --delay 100 Return

Ideally, I could even write a linter to autodetect possible issue in profiles.

That seems like a good idea. At least something like checking some common control files like .bashrc for write permissions.

This is sys_admin that is well known to be overloaded. However:

* You still need it every time you want to mount something.

* That's more an issue for the dev: If a program require it, blocking it in apparmor would simply break the program.

This actually sums it up pretty well.
In the end it comes down to the philosophy or threat model about what these profiles are intended to do. While one can say that removing permissions is helping to reduce risks even if there is a way to circumvent it, I would personally argue against any measure that does not implement a hard boundary. If a program cannot be confined effectively, perhaps it should not use partial confinement to avoid giving a false sense of security.
I'm not sure which would be best for this project, both philosophies are probably fine here. But perhaps there could be a comment inside the profiles when it has been designed and reviewed to be solid enough to not allow any known weakpoints. As mentioned I would see the common frontend applications as a primary target for this. For example I would want to see media players like vlc to be completely confined because those media codes are a huge attack surface.

@roddhjav
Copy link
Owner

roddhjav commented Jan 27, 2024

Regarding you POC, this is a concern, obviously. However:

  • The only real solution is not to use Xorg any more, and it has nothing to do with apparmor. As I have written before, apparmor is only a tool to implement some security feature, not everything.
  • It is still an issue as it works on wayland with xwayland as well...

From my testing, the solution (for gnome) would be to remove the following rule:

  owner @{run}/user/@{uid}/.mutter-Xwaylandauth.@{rand6} r,

It is however problematic as it is required for all program using xwayland. I don't really care of xorg itself as it is deprecated. I will look for a stable solution for (x)wayland.

In the end it comes down to the philosophy or threat model about what these profiles are intended to do

Rule 2 is quite clear about this:

Rule 2: Do not break a program

Having profiles that break a normal use of a program is the reason why one the first result of the "apparmor" (or selinux) keyword on Google is something like "how to disable this shit". Security is a journey, it will be better tomorrow than today, and it is by far better today than yesterday (without apparmor.d).

@vam67423
Copy link
Author

vam67423 commented Jan 27, 2024

Regarding you POC, this is a concern, obviously. However:

* The only real solution is not to use Xorg any more, and it has nothing to do with apparmor. As I have written before, apparmor is only a tool to implement some security feature, not everything.

* It is still an issue as it works on wayland with xwayland as well...

From my testing, the solution (for gnome) would be to remove the following rule:

  owner @{run}/user/@{uid}/.mutter-Xwaylandauth.@{rand6} r,

It is however problematic as it is required for all program using xwayland. I don't really care of xorg itself as it is deprecated. I will look for a stable solution for (x)wayland.

Most applications today already support wayland but may also try X11 when available and add this to the profile when automated generation tools are used. A possible solution could be to allow only connections to the wayland socket and to block xwayland when it is not absolutely required. (which would remove support for all X11 desktops, but as you said those are deprecated anyway)
In cases where an application still needs X11 there could be a warning in the profile, though I would personally rather not allow such profiles into the repo at all, since it makes little sense to "confine" these apps with such an obvious escape path.

@roddhjav
Copy link
Owner

roddhjav commented Jan 27, 2024

A possible solution could be to allow only connections to the wayland socket and to block xwayland when it is not absolutely required. (which would remove support for all X11 desktops, but as you said those are deprecated anyway)

That's more complex that it looks like. For instance, on Gnome over wayland, if you deny owner @{run}/user/@{uid}/.mutter-Xwaylandauth.@{rand6} r, the DE does not start...

Not to mention that it would break all programs using xwayland (cf Rule 2)

Also, (on wayland again) xwayland is only used when it is absolutely required. So maybe I could remove @{run}/user/@{uid}/.mutter-Xwaylandauth.@{rand6} from the X-strict abstraction and add it manually to some specific profiles. That may be the best solution, but it will be time consuming.

In cases where an application still needs X11 there could be a warning in the profile, though I would personally rather not allow such profiles into the repo at all, since it makes little sense to "confine" these apps with such an obvious escape path.

That's a no go, (cf Rule 2)

Most applications today already support wayland but may also try X11 when available and add this to the profile when automated generation tools are used.

Nitpicking a big: That's not how the profiles are generated, and it is not how app works too (they use what is provided to them: running wayland UI on Xorg would not work, the opposite only works thanks to xwayland).

@beroal
Copy link
Contributor

beroal commented Jan 31, 2024

I use AppArmor to restrict access to files in $HOME.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants