OpenBSD Gains Privilege Elevation
ocipio writes "OpenBSD's systrace now has privilege elevation support. This means binaries no longer need to be suid or sgid an longer. Applications can be executed completely unprivileged. Systrace raises the privileges for a single system call depending on the configured policy."
I think you misunderstand.
The message referenced indicates that this is a security feature, which will allow the individual system calls to be executed with escalated privileges. This is an advantage in that you do not need to have the entire binary executed with the escalated privileges, and so reducing the number of potential privilege escalation attacks.
This signature carefully hand-crafted from recycled electrons.
systrace
I think you misunderstood. The parent post is clearly a joke.
I.O.U One Sig.
It's fine grained control of privelege. This is to the basic unix concept of running as a uid and setuid what ACLs are to normal unix filesystem permissions. For a really simplistic example - with this you could run your apache binary with literally zero priveleges, like "nobody" (from start to finish, no run as root then drop privs), and the explicitly enable it to have root-like privs only for the one system call it uses to listen to port 80.
11*43+456^2
It's not a bug, it's a feature !
For example the Apache webserver, it needs to be started as root, in order to bind to port 80. Now this is no longer required, since a call to the new function will allow it to bind to 80 as an regular user, provided that the syscall is configged to allow that.
Same goes for X, which now no longer needs to be run SUID.
It probably won't be long before these mechanism is common good, but I wonder what happens if someone finds an exploit in THAT ?
There are things that must run as root to work. The common way to allow normal users to do these things was to make them setuid, which meant that the application always runs as its owner, no matter who launched it. Yes, this can be a security hole if not configured wisely. Stuff that requires configuring network interfaces is a good example. This method allows an application to be run as joe_user, but still access privileged system calls, depending on configuration. It is less of a security hole than what is being done now.
"Proximity to wonder has blunted our perception and appreciation of it" --Tim Hartnell in 'Exploring ARTIFICIAL INTELLI
Actually, this type of security is pervasive throughout the _standard_ Java libraries ... not just tied to netscape or any other implementation.
Java's one of the few programming languages that has security built in from the ground up.
And yes, this new BSD feature is VERY similar to Java's declaritive security mechanisms.
(Please let's not start a war of "Java is cool vs. Java sucks", I wanted to provide the above!)chroot jails are almost completely unrelated to system-call security, unless the system call is to the file-system. chroot simply allows you to change the root of the file system so that the application cannot access part of the file-system beneath it. If the process is running as root, this helps nothing, since there are many ways of accessing the complete file-system bypassing the normal means if you are root.
What they're doing here is simple and clever. The idea is to run an executable, trap it's privileged system calls, and then create a policy file (call to uid map) from the run. After the policy is in place and the executable is run again, the system promotes the calls listed in the policy to the appropriate privilege level. Any new privileged calls generate an error, as they're most likely a security breach or some part of the executable that never got executed the first time.
b in_httpd.
A sample apache policy is here: http://www.citi.umich.edu/u/provos/systrace/usr_s
This sounds similar to an idea I've floated around to a few people, except that my idea worked on library functions. The idea was to allow setuid and setgid on individual functions instead of entire programs. When you called such a function, it would run with the elevated privileges determined by the ownership of the library file itself, and when it returned, permissions would go back to what they were previously.
/etc/priv.conf can only be read by root). An attacker could execute a
The one issue I had with this was what to do if a setuid function called another function. Should the privileges be passed onto the extra function? At first thought, it seems like it should, but consider this example:
I have a library called libprivfunctions.so. Within this library is a function to open a privileged file:
FILE *open_priv_file(void) {
return fopen("/etc/priv.conf", "r");
}
We'll say this function is set to run as a setuid root (maybe
export LD_PRELOAD=/home/attacker/libc.so
before running a program linked against libprivfunctions.so. This version of libc.so would have a fopen that creates a root shell. When open_priv_file() is called, it will call the falsified fopen which, if run as root, will breach the security of the system. Maybe the easiest way around this would be to disallow any LD* variables when running programs linked against setuid/setgid functions (similar to the way setuid/setgid progams work). But the logic behind this gets complicated (you don't know if you're linking against setuid functions until after you've linked. But what if that outcome was caused by one of the LD* variables?).
I would say that allowing elevated privileges to just system calls is a good way around this problem. Hats off to OpenBSD for another sound decision.
For every post, there is an equal and opposite re-post.
Somewhat similar capabilities also exist for Linux. The Linux Security Module (LSM) effort adds the ability to insert an additional access control mechanism into a Linux kernel (without a recompile). You can then at run-time insert a modules to add finer control over privileges. Several modules exist, such as SELinux. This approach makes it easier to experiment or create your own access control policy. There are various LSM modules already available; none of them are exactly like this, but most provide finer-grain control. There are definitely technical differences, too, but describing those differences would take up WAY too much space here.
There are definitely situations where finer control over privileges is very desirable. Which way is the best way is very much in doubt. The good thing about finer control is that you can give a program only the privileges it needs. The bad thing about finer control is that it takes more work to set up. "Learning" from program runs helps, but it doesn't fully solve the problem - there are usually many conditions that aren't triggered by simple runs yet can happen in real life.
Anyway, this kind of capability is a good thing. It will be interesting to see what happens over the years as people try out various ways to add finer control - the trick will be to add finer control while still keeping the system easy to administrate. It's not even clear that there is a single solution.
- David A. Wheeler (see my Secure Programming HOWTO)
I really hate to say it, but:
1) The story in no way credits Niels Provos, the author of systrace.
2) The story does not mention that this feature was added to NetBSD first.
I don't mean to claim "NetBSD is better" or anything, but at least say "OpenBSD and NetBSD" or "NetBSD and OpenBSD" or something, not "OpenBSD". Also, PLEASE credit the guy that did the work, eh?
I hate to be a bitch here, but the feature was added to NetBSD first. I don't mean to imply NetBSD is better than OpenBSD, but maybe some equal billing would have been in order? And by the way, what happened to crediting the author of the code? The work was all done by Niels Provos, who's a damn good security guy.
Niels Provos was an OpenBSD developer until recently. He's the same guy who did the PrivSep code for OpenSSH.
/ 10 /11/0039.html
It actually appeared in NetBSD first.
http://mail-index.netbsd.org/current-users/2002
Regular capability systems are more coarse grained. You can have capabilities that say this application is allowed to bind to a reserved port,etc. However, with privilege elevation in systrace, you have much finer control. The privileges are just elevated for a single system call matching specified system call arguments.
Additionally, with systrace you can reduce the privileges of binary applications without the need to add support for capabilities in the source code.
Except this change originated in NetBSD.
Read more of this story at Slashdot.Read more of this story at Slashdot.Read more of this story at Slashdot.
setuid and setgid are not perfect and the recent spate of Linux vulnerabilities certainly speaks of the need for improvements in this area. My point is that doing away with setuid and setgid and replacing it with per system call access privileges does not seem to be the right way to increase security.
With Posix (and Linux, which is Posix compliant) it is already possible for an application to drop it's privileges. This solves the problem of an application running its entire life as root. With the posix compliant call to setuid, an application can be setuid root only for as long as it needs to access privileged resources and can drop those privileges once it no longer needs to be root.
However, the above article talks about an application elevating its privileges and for the kernel to grant that privilege on a system call basis. The article is short on the details but elevating the privileges of an application is certainly a very dangerous process. If an application asks the kernel to elevate its privileges, how is the kernel to decide if it should grant that request? My mind-set tells me that it should check the effective user id of the running process but then isn't this setuid and setgid again? If the kernel will grant this request by checking a list of applications that is allowed to do this, then how is this different from a kernel checking if an application is owned by root?
I have stated my preferences for chroot jails and for a good reason. Once a system is cracked, the intruder can do with the filesystem as much as he pleases. At least with chroot jails, the intruder is restricted to the chroot directory and cleaning up the mess is easier. Yes, I know this is not a cure but I think the idea of jailing applications to a particular environment is a good idea.
I am an old hand so my mind has petrified with an imprint of the old ways of doing things. I could be wrong, but until I am fully convinced, I will be among the voices that express caution at the idea of throwing away setuid and setgid.
Just my half cent.
I'll say it again: the change appeared in NetBSD first, so one should mention both NetBSD and OpenBSD here, and please give credit to Niels Provos, the author of systrace and thus the guy who's been doing all the hard work here.
There is no need to speculate in how it works when you can just go to the webpage and have a look yourself. http://www.citi.umich.edu/u/provos/systrace/
The method employed is somewhat fiendish. A systraced program is "mastered" by a systrace daemon that gets information on all its system call activities and either thumbs up or thumbs down particular requests. (For performance reasons, things get fast pathed in many instances so the upcall doesn't have to happen.)
Because of the way that this works, via a userland policy engine, the systrace daemon (which is user code) can use any method it likes to determine how to implement the policy. The way it is currently implemented, the systrace program reads a policy file associated with particular programs and makes decisions that way.
There is no need for a program to authenticate to the kernel because the program itself has no knowledge of the policy and cannot evade it in any reasonable way.
The mechanisms involved are still evolving a bit, but Niels has come up with a bunch of really good tricks here. I don't know that systrace is a finished mechanism as much as a toolkit for building new and more interesting mechanisms that are in the tradition of ACLs but much more flexible.
The answer is you can't tell the kernel "I'm Apache." Obviously a mechanism that just let you do that would be trivial to evade. The kernel can easily know whether you are the apache program or not, however, because it knows the inode backing your executable -- there is no way to forge that. This is the same way the kernel knows that you have a suid bit -- it looks at the inode for what it is executing when it executes it.
The systrace mechanism is a very nice one. Most on-system exploits these days are caused by suid programs being exploited before they give up privileges (and many don't give up privs ever). By only giving a program just the privs it needs, you can avoid having to have root privs available to the programs at all. You can't exploit privileges you never have had.
You are working backwards. Looking at it objectively, it is clear that a system where applications have to become superuser to perform certain tasks but can relinquish this authority is inferior to a system where superuser priveleges are never given to a process.
Your position is understandable since this is how the Unix security model has worked for decades even though better mechanisms have been proposed but rarely caught on. For example, look at POSIX 1.E which is almost 2 decades for an example of a better model for handling systems permissions than the traditional Unix model. Recently there has been work done on FreeBSD POSIX 1.E capabilities as well as on the Linux front. This is a good indication that more and more people are disatisfied with the deficiencies of the Unix security model and its reliance on a "superuser" account for so many essential tasks.
Lastly I don't think any Linux distro has ever been certified as POSIX compliant although many feel that doing so wouldn't be difficult.
The URL describing this stuff is
http://www.citi.umich.edu/u/provos/systrace/
Separating the various functions whose use should require privileges into catagories that can be granted individually (or in groups) to different userids is definitely a Good Thing: it probably won't eliminate the need for a super-user and a few godlike system maintainance users, but it allows the system administrators to keep the really dangerous 'own all data' and 'devour all resources' functions to be kept under tighter control than the all-or-nothing approach. (Arguably, you shouldn't even consider handling sensitive information on a platform that cannot administer privileges in a reasonably fine-grained way, but that's another argument.)
Also consider this: who decides whom should get granted what rights? Well, that person is automatically superuser, because he simply can give himself all the rights without telling anybody. The problem with a System Administrator is simply that it should be a "person of trust", if you don't trust him, you should get rid of him. It's that simple.
I can only say: I like being a tyrant on my systems. But I'm a fair and good tyrant for I respect my users and don't go and meddle with their data.
You can have my root account if you pry if from my cold dead hands.
In the interests of pedantry, it's actually ports below 1024.
Then I went to read the actual thing here, and I found that it also checks for syscall arguments, including some sort of pattern-matching (you can even change dinamically the system call arguments, making a sort of chroot-on-the-fly).
It looks like a promising idea. My only concerns are :
1 - performances
2 - setting up a policy file requires a good knowlwedge of system calls, and not many programmers (not to speak of users or sysadmins) have that. The interactive policy setup helps a little, but it is _you_ that have to say 'yes' or 'no'.
Ciao
----
FB
1. Is this going to be in the new 3.2 release in November?
Yes. November 1st, actually. http://www.openbsd.org/items.html#32
2. Do programs have to be re-written to take advantage of this feature?
No. http://www.citi.umich.edu/u/provos/systrace/
It's not about ACLs, it's about privileges.
.comPack works, which is an EAL4 (exceeding B1) kernel security addon for Solaris and AIX.
There are different kinds of philosophy regarding privilege management.
Granting privileges to binaries, authorizations to users
Trusted Unices commonly grant privileges to binaries, but only let the process use the privilege, when the user who executes the binary has got a certain authorization.
For example, there is one Authorized Privilege Set (APS) and one Privileged Authorization Set (PAS). You put the PV_FS_MOUNT privilege into the APS, and you put the MOUNT authorization into the PAS.
If the user who executes the binary has a MOUNT authorization, then the process gains the PV_FS_MOUNT privilege, and the user can use the program to mount or unmount filesystems.
If the user who executes the binary does not have a MOUNT authorization, then the process does not gain the PV_FS_MOUNT privilege, and therefore the user can't mount or unmount filesystems.
(This explaination is a bit simplified, because you would also have to look at the limiting privilege set or limiting authorization set, but that does not matter here)
This is how Pitbull
Granting privileges to users, running processes with adopted authority
The other way is to grant privileges to users, and then to let a binary run with the privileges of a specific user added to the privileges of the current user (Adopted Authority).
For example you put the ALLOBJ privilege into the privilege set for user 'John', and you give some binary an adopted authority from user 'John'.
User 'Mark', who does not have the ALLOBJ privilege, executes the binary, and the process gains (adopts) all privileges from user 'John', so user 'Mark' can run the program with the ALLOBJ privilege.
This is how the SLIC part of OS/400 works (SLIC is the operating system kernel of OS/400, running on IBM AS/400 computers).
[Tell me if I got something wrong here, I'm not an OS/400 expert]
Granting privileges to users makes administration easier and it's powerful enough for almost any scenario; granting privileges to binaries makes it a bit more difficult but also more powerful, and i guess that's why it is the preferred method used by Trusted Operating Systems.