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."
systrace
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
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
Same goes for X, which now no longer needs to be run SUID.
Does this mean X will run slightly slower compared with an suid installation? It seems like there would be more code running behind each syscall to check the configured policy, but it's probably not a significant amount - at least, not for current systems. I'm merely curious.
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.
how is this better than setuid, setgid? At least with setuid and setgid, control over system privileges is given on a per-application basis.
Which do you think is more secure? Given a choice between having an application run as root [with all the attendant problems that this entails especially if a security problem is found in the app] versus giving the application minimal privileges [specifically all it needs to get the job done and nothing more], how could anyone think the setuid and setgid approach is better.
The difference between both approaches is the difference between a sledge hammer and a surgeon's scalpel. In fact the only downside to the minimal privileges approach, is performance and efficiency. In this day and age where one can buy half a gig of memory for around $100 and 3.0 GHz processors are on the horizon it really is time for us to adopt techniques for building secure software that have been known for decades but unimplemented due to performance/efficiency concerns.
If a flaw is found in the syscall lookups (ie: an app can make a sequence of syscalls to give itself priveledged access anyway) doesn't this mean literally any executable is capable of ruining your machine as opposed to only the suid root ones on any other *nix OS?
Wouldn't a combination of both be better?
Under the UID 0 approach, all calls needed to do something. I haven't peeked at the code, but if I were to solve the problem, I would frontload the overhead of the syscall policy evaluation to the exec() call, store the results in a bitmap field. From there, it's bit math. A if (priv & PRIV_SOMECALL) has no more overhead than if (uid==0)
This is a boring sig
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
Normal unix daemons (apache, bind, whatever) are started as root, and DOWNGRADE their permissions when they can.
This systems lets them start unpriviledged (not running as root) and the kernel will upgrade the permissions on a strict need-to-have basis.
Why give a mile when you only need an inch? That leaves a whole lot of room for error... This eliminates that problem.
Once again, OpenBSD takes the next step towards a more secure UNIX. Only they have the bravery to touch code thats 2 decades old, modernize it with well thought-out changes, and stand behind it. Not to mention that this is code that if screwed up, could reak havok. If anyone is qualified todo these things, the OpenBSD team is.
WOohoo!
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.
This is the first I've heard of Systrace privilege elevation. However, it seems to address what has historically been one of the greatest causes of security problems in Unix.
If you look at the major vulnerabilities we've seen in Unix operating systems and software, they usually fall into one of three categories:
1) Bugs in the kernel.
2) Bugs in servers running with elevated privileges (often root).
3) Bugs in suid binaries (often suid root).
Privilege elevation could significantly reduce the problems caused by 2 and 3. It's by no means a silver bullet that's going to eliminate vulnerabilities, but it could produce a huge improvement.
Consider how difficult it is to write a secure suid root binary. Not only do you have to be extremely careful about your own code, you have to worry about possible bugs in any of the libraries you link with. Some people (e.g. D. J. Bernstein) seem to have the knack of producing secure code first time, but even a good programmer who is always thinking about security can make the occasional mistake.
With privilege elevation, such mistakes are no longer security disasters that grant complete root access to an attacker. The most an attacker can do is make the few privileged syscalls that are permitted by the systrace policy.
Lachlan.
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?
Making the X server SGID kmem is still giving it far more privileges than it needs in order to be able to do its job. Just being able to read kernel memory is sufficient to get root in most cases (the easiest example to explain being reading the root password right out of the TTY buffers as root is logging on).
Hopefully the new feature makes it into other OSes -- Unix has long needed a standard way of doing this kind of fine grained privilege separation.
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.
"This means binaries no longer need to be suid or sgid an longer."
Doesn't Slashdot have any moderators who speak English? I'll gladly volunteer to read over the stories before you guys post them to the main page if it'll rid us of these ridiculous grammar, spelling, and style absurdities.
Very good point; and a new feature might require a new privilege setting, which would cause errors until the policy was redone.
The policy also doesn't protect against exploits which use privileges that were already authorized, though it's still an improvement over SUID/SGID.
It would be nice to add a CRC-32 to the policy file, and check the CRC each time the code is run. If a difference is discovered, indicating either a hacked executable or an upgrade, a warning could be given that the policy might need to be changed.
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.
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.
A little offtopic, but a great security approach that I haven't seen used to often is to port-forward port 80 to a non priviledged port Apache is running on (Say, 8080). Completely removes the need for root privs.
Your comment is rather vague. Let me be more specific.
/var/mail.
/bin/sh for me, I can't make it write to random files on the system, indeed, I can barely write a remote exploit for it at all. Add in a little chroot and other magic and suddenly you have a very hardened program.
Lets say that you have an smtp daemon. With systrace, I can very easily elevate it to be able to open port 25 on the system, and restrict it so that it can't fork or exec any programs and can do no i/o other than writing to files in
Sure, you can theorize about how evil and complicated this is, but the truth is in one fell swoop I've made it fiendishly difficult to exploit the smtp daemon -- and in most cases I don't even need to have the daemon be the least bit aware of how systrace works. Once I've done this, I can't make the smtp daemon fork a
Most of your comment seems to consist of platitudes about simplicity, not any actual experience with using systrace in a practical system. It very much adds security to the way systems run, and it is completely in the spirit of most modern security aware code, like the Postfix mailer or privilege seperated ssh.
The URL describing this stuff is
http://www.citi.umich.edu/u/provos/systrace/
and the other 5% can't even add up.
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.)
Security in UNIX can be messy. It is hard to add security late in the prosses without making it hard to use and understand.
EROS (GPL) was designed for fine tuned privileges from day one. This is a natural part of the capability system.
"EROS is a pure capability system. Authority in the system is conveyed exclusivly by secure capabilities, down to the granularity of individual pages."
This is a secure design and a OpenSource OS.
http://www.eros-os.org/
Blegh, will people please stop using "chroot jail" when they really just mean "chroot"?
This is jail - a syscall which puts a process inside it's own process list, user list, IP and root directory, while limiting various syscalls which might make it possible (or at least easy) to escape the jail.
This is chroot - a syscall which puts a process inside it's own root directory. As you said, this is almost completely unrelated to system-call security.
chroot is not jail, jail is not (merely) chroot. Calling chroot "chroot jail" actually makes it *less* clear what you're talking about.
True security will never be achieved in the *nix way (Complicated ACL's attached to every 'command' or 'system call'), due to problems such as The confused deputy.
True security can only be achieved when there is complete identity between what requests a process can express, and what the process is authorized - only possible without a global namespace such as the set of system calls or the file system. Only capability systems are of this nature.
OpenBSD may be secure in the sense that it has few bugs, where almost every bug in the every-growing code base regarding *nix security is a security hole, but its not secure in the sense that truly secure systems such as EROS are secure - by having (to sum it up):
A small, finite, debugged code base that deals with security - and no extra security code.
Simple security paradigm with a single simple-logic security test per request.
Identity between what a process can request, and what the process is authorized to do.
Fine-grained access control, with each process having capabilities to the exact objects it needs to access.
Mathematically-found model, that has mathematically provable properties.
The principle of least privelege (Your mp3 player cannot delete your files, your email client cannot listen on any port, etc).
Flexible security: The complicated authorization graph is between processes, and not between users and objects. The concept of "user" is not part of the operating system. This is also achievable because capability systems often have orthogonal persistence, that is transparent persistence (sort of like Hibernation Mode, in its functionality), which tends to be of much better disk performance.
No global namespace: There is no global namespace file system that all applications have access to. Perhaps a database of objects for the user's convinence that points via capabilities to the user's objects which are then passed on selectively. But there is no global file namespace that processes can access. All requests by processes must be carried out by activating a capability, whose mere existence authorizes the request. This instead of activating a system call from a global namespace of system calls, allowing any process to request almost anything, hoping that the security code regarding that request will properly deny that request. The global namespace allows extra communication and exploitation between processes that needn't be possible.
But really, it needs to get out of the ivory tower and start giving us examples that work. The Confused Deputy is about compilation, sounds like it was an issue from a VAX box from the 80's, and not only is so utterly irrelevant to Joe User, it's not even all that terribly accessable a metaphor to people using gcc!
The erights folks are using more accessable examples (a web browser), but in their examples paint a picture of the land of popup hell, where every app has to ask to do every single operation. Write to one file, one popup. Write to another file, another popup. Open your address book, another popup. Experience shows that users click "yes" or "ok" on popup dialogs or whatever button they can just to make the damn things go away and make them stop coming back. My own mother would ask me, "how do I keep this from asking me these questions all the time?".
I know it doesn't have to work this way -- an installer can give an app a pre-set list of capabilities that one should be able to verify, log, change, audit, revoke, etc. Roles can be created out of capability groups to put some of the ease of ACL's back into the equation. But their their own example stories don't even make that clear. It's ivory tower, all about security theory without an ounce of human factors other than "the user will learn" and some laughable user education story about POLA.
The average server is reasonably secure right now, since it performs dedicated tasks and is administered by what one presumes are trusted people. It's the desktop that's providing fertile ground for attacks. Thousands of infected desktops hitting one server, and well, wouldn't it be nice if those desktops were secure? They won't be if security doesn't take the human factor into account.
I've finally had it: until slashdot gets article moderation, I am not coming back.