krad jpeg by k

Hardening OpenBSD For Multiuser Environments
- Now With New 3.0 Technology!

Mmmmm, OpenBSD. Functional, secure, free. With an emphasis on security and integrated cryptography, it carries an excellent reputation for plain old "you-just-cant-hack-this-ness". Not perfect, but nothing is, at least they're not wearing suits and lying to you.

There are a few roles where i believe OpenBSD fits perfectly. One of these is in multiuser environments, where you have large numbers of possibly malicious users with local access. Here the OpenBSD team's commitment to auditing and fixing code provides a level trust in the environment which is hard to find elsewhere. Also, their efforts to provide integrated cryptography means setting up secure access is easy. So, let's take advantage of the freely available source and tailor it to our specific needs.


In Phrack 54, route|Mike Schiffman wrote a series of patches for OpenBSD 2.4 for Trusted Path Execution (TPE). Stephanie brings a modified version of these up to speed for OpenBSD 2.8 - 3.0, along with some additional features. A trusted path is one where the parent directory is owned by root and is neither group or other writeable. The TPE works off an internal list of trusted user id's. If a given user tries to execute a file not in a trusted path, and their user id is not in the kernels trusted list, they are denied execution privileges. In real terms, this means they can't download, compile and run krad-sploit.c.

In addition to the TPE, a series of privacy patches came along too. Originally supplied as patches for the individual utilities, these are now implemented through kvm(3), and honour trusted users (ie, trusted users are allowed to see all system information). As a practical example, this means that untrusted users will only be able to see information about processes they own, and the 'stat' tools (netstat, iostat, vmstat, etc) will generally be broken for them. It has been pointed out that by going through trying to kill every possible process id you can find other users processes, but you can't really gain any information on them, so this is not really a great concern.

The original TPE patches had one known way of bypassing the execution restrictions, which was using shell redirection to allow arbitrary interpreted language scripts to be run (perl, sh, etc). This has been fixed up, but could possibly be a big pain in the ass, so please pay attention. When an interpreter is invoked, like most things, it creates a new process group with a job count of one. When a series of commands are connected via the '|' character on the command line, all the commands belong to the same process group and the job count represents the number of commands eg 'ps -ax | grep something | awk '{print $1}' has a job count of three, and the ps, grep and awk processes all belong to the same process group. The one exception to this is when a user logs in, where we find their shell has its job count set to zero. So how can we use this to prevent shell redirection for a given set of programs? We need to be able to distinguish between ordinary commands and interpreters. At the moment this is done by setting the immutable flag on them. So, in kern_exec(), if we find an untrusted user executing something with the immutable flag set and a job count greater than zero, we flag the process as being potentially dodgy. Then in other system calls we disallow read()'ing from fd 0 (stdin) and things like dup2(0, n) if the process has been flagged.

There are two main disadvantages to this. First is the system will need to be brought down to single user mode if the interpreter needs to be patched, and secondly, people will have a hard time su'ing to an untrusted user. Of course, when a user has shell, they can still type any commands that could otherwise be placed in a shell script, but at the least, this will raise the bar a bit.

Finally, Stephanie brings restricted symbolic links, ala the openwall patches for linux. As time permits, i'm still working on adding additional features, and will add bits of the openwall stuff i like. The basic goal is to add an extra layer of security without being a monumental pain in the ass to legitimate users, so some things won't be there. I haven't added the additional hard link restrictions of the openwall patch, but will do something about this later as time permits.


Step by step instructions are presented in the install guide which comes with the source. Read it all first, but it's reasonably straight forward. It would be a good idea to read the original article (local copy) if you haven't already.

It's distributed under the original two clause BSD license, mess with it all you want, but don't get cranky at me if it breaks something.

You can also read the tpe_adm(8) man page online.


stephanie-3.0.tar.gz contains all you need for 2.8 - 3.0: stephanie-3.0.tar.gz

Idle Ramblings

I'd just like to point out this is to add an extra layer of security. It is not a "solution" to security problems. You can make your stack non-executable, give your eip canary values and all sorts of cool stuff, but ultimately the only real solution is to fix broken software. In the real world it's naive to rely on idealism, so this is why this stuff is available. But dont think it will solve all your problems.


Mike Schiffman - Wrote the original stuff, gave me hosting space
Grant Bayley - Gave me a 2.9 box to mess with, rebooted it when i broke things.
k - Did the reet title graphic
Work - Has been pretty cool with me while i work on this.