A short guide to get you started on AppArmor
AppArmor is a linux security module that allows for path based mandatory access control. It’s easy to learn and very effective at both preventing and containing exploits. I suggest you make use of it.
This post is just a short crash course to get you set up and using apparmor.
We first need to install the apparmor-utils package.
sudo apt-get install apparmor-utils
Once it’s done installing you should be able to access these commands:
Let’s create our first profile. I’ll use pidgin.
# aa-autodep pidgin
This will create the pidign profile in complain mode. Complain mode will audit violations but not stop them.
Close (if open) pidgin and then open it up again. And then close it. Then run the command:
At this point you’ll be greeted with some of the “complaints” that were logged. Review and allow what’s needed.
r: r is read access
w: w is write access
a: a is limited write access (append)*
k: k allows the ability to lock a file
m: m lets a file be loaded into memory
x: allows execution
ix: executes the file under the constraints of the profile (inherit)
ux**: executes the file outside of the profile (unconfined)
Cx: executes the file in its own profile, which is specific to the parent process
Px**: executes the file in its own profile, which you will have to define (profile)
*not to be confused with allow. a is the rule, allow is a command that applies it via logprof.
**Capital C, P or U means that the environment is sanitized before executing the code. You want to sanitize whenever possible.
To test the profile out run:
# aa-enforce /etc/apparmor.d/usr.bin.pidgin
if it isn’t working still set it back to complain:
# aa-complain /etc/apparmor.d/usr.bin.pidgin
The first few times I set up a profile I ended up with a super convoluted mess. It was terrible. I wiped it, started over and actually *thought* before I hit “allow” or “inherit” and in very little time I was able to create many profiles for my programs.
Profiles are stored in /etc/apparmor.d/<path.path.path> so for pidgin it’s /etc/apparmor.d/usr.bin.pidgin. You can manually edit the profiles with a text editor. This is really simple and I suggest you have a look at a few profiles before you start.
1) Instead of aa-autodep you can try aa-genprof, which will try to build a partial profile for you.
2) Development profiles can be a great place to start. You can get them here:
3) Apparmor profiles can get complicated. Don’t bother trying to profile something like compiz, there’s no real point. A program like Pidgin or xchat is perfect though.
Creating Strong Profiles
There are a few things to make note of when aiming to create very strong AppArmor profiles. Get used to everything above here so you’ve got your bearing before looking below.
Abstractions are generic templates that can be imported into AppArmor profiles. Most profiles come with at least a few abstractions. Abstractions are dangerous – they can pull in other abstractions within them, and lead to far more rights than your program may need. Creating with abstractions is easy but your profiles will be stronger without them. If you’re going to use abstractions always review what you’re pulling in.
2) Owner Tag
The “owner” tag is your friend. Sometimes you have to give a program really unruly access to your file system (/home/** rw). Using the “owner” tag means that (in the case of /home/** rw) the profiled program can only read/write to files that it has ownership of. This is a really useful tag and I suggest you make use of it wherever possible. Programs mostly just need access to their own files and folders, especially for write access, and owner is great for enforcing this.
3) Know Which Execution Rules To Use
There are four execution rules: ix, Cx, Px, and Ux. Knowing when to use them is important, but not difficult.
First of all, never use UX. Let’s remove it as an option right now.
Often times it’s easiest to just inherit the process, but oftentimes this is not the best action. Inherited processes should be the ones that will only act on files already defined.
For example, Chrome might call /bin/which to interact with its files. There’s no need to run which in a child process, it needs access to all of Chrome’s files and nothing else.
You most certainly wouldn’t want to run Native Client as an inherited process. Native Client will require its own separate resources and rules, so it makes much more sense to run it as Px.
You may also consider running Native Client as a child process from Chrome, though in my opinion this isn’t as powerful as Px as you can not have child processes within a child process.
A child process is very good for situations where you don’t want the process to always be confined. For example Chrome needs to run xdg-settings. You don’t want xdg-settings to always be profiled, and even if you did you wouldn’t need all of those capabilities just for what chrome will use it for. So running it as a child makes the most sense.
As you create more profiles this all becomes much easier and intuitive.
4) Avoid UX, Be Wary Of PX/CX
There are three execution rules that can let an attacker gain privileges, CX, PX, and UX.
Never use UX – if you use UX you make your profile far far weaker, essentially allowing an attacker to execute any file they can write on the system. Really, if you feel the need to UX then your profile is in trouble, go for CX instead.
Attackers can potentially escalate privileges by moving to a new process under a new profile. They do this through CX/PX. If I’m an attacker in someone’s Pidgin profile but I can’t access the files I need I might hop over to the browser process through a “/usr/bin/firefox Px” rule, which would then let me access anything the Firefox profile has access to.
Always use a capital P/C. This ‘sanitizes’ the environment, which removes specific variables that could be passed along to the new process. You very rarely can’t sanitize the environment and it’s far more secure to do so.
5) Don’t Allow Writing To Areas You Can Map
Mapping a file to memory can potentially allow an attacker to move forward in an exploit, either by then marking it as executable or using ROP. If an attacker can write to an area it’s best not to allow it to be mapped. If it’s absolutely necessary make sure to restrict it with an ‘owner’ tag, at the very least. This is usually the case for cache files and sometimes /tmp. Avoiding the combination is a good idea
This isn’t all you can do. Very specific rules with file extensions are one more way to be secure. Use your imagination.