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."
...and isn't being able to run binaries unpriviledged a security hole, or am I just not getting it?
I know NOTHING about BSD, however I thought it was *nix-like and you didn't want apps running around all will-nilly ( yes I said will, nilly) with elevated rights. What makes this so news worty? Until I read the whole thing I actually thought a secutity flaw was unearthed.
This sounds similar to a scheme that Java supports on some platforms (netscape?); I believe there is a setPrivilege() call.
I'd like to see more of this kind of thing- restrictions to the file space that 'parts' of programs can access should be made, as well as I/O and networking restrictions. Is an email worm going to happen if the OS stops the macros from sending mail? Why should it if somebody else wrote the macro? There's a clear need for better granularity of security.
We've seen how useful personal filewalls are for network interfaces- this needs to be extended to the other services that the OS supports.
-WolfWithoutAClause
"Gravity is only a theory, not a fact!"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.
how is this better than setuid, setgid? At least with setuid and setgid, control over system privileges is given on a per-application basis. With this per-system call method, the kernel somehow has to track each system call made by an application and grant or refuse privileges on some basis. (On what basis is unclear from the article.) This seems like a lot of data for a kernel to keep track of, considering the number of system calls a typical unix kernel has.
Though I believe improvements to setuid, setgid is needed, per system call access privileges don't seem to be the right approach. I would much rather go with chroot jails for each application.
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?
I see it to be a *good thing* indeed but does not solve all the problems and the most important running login daemons like sshd which eventually has to change to a different user and thus has be run as a root to call setuid(), on the other hand if rules allow to elevate privileges for setuid() then it is sort of meaningless. What we need is to have a possibility to change user without compromising security. Any ideas?
Why not just make it SGID kmem (or mem or whatever group owns /dev/mem and/or /dev/kmem)?
It seems like that would be as easy a way of partitioning "root-like" permissions as any other.
My other first post is car 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.
Suppose a new Apache version starts up differently, so the previous policy no longer matches. Perhaps Apache won't change that much, but there are certainly some apps which would need more complicated policies than Apache; what if they read config files in a different order, or add some new wrinkle? What about Perl or Python programs, where some module changes, or Perl itself changes?
It would seem to me (as naive as I am to this new concept) that this could be a major pain in the butt. How much does this apply in practice?
Infuriate left and right
For system services that change privileges based on some internal state (like authentication), sandboxing does not work very well. In that case, you want to use Privilege Separation.
On the other hand, if you have some global restrains, like root may never log in, you can use systrace to enforce them.
A combination of both methods will give you a good fit.
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.
Hey, interesting idea, how about expanding the policy to include which system calls, which level, and the amount of times they can use them.
Don't know how CPU intensive, but after reading that Apache httpd ACL, you could really be anal and lock down applications. We currently use EFS on our Sun Boxes, and it locks down the boxes tighter than a drum. Sounds like a nice extension on a theme.
ACL's, MAC's and more http://www.trustedbsd.org/
http://www.apple.com/macosx/jaguar/unix.html
... Jaguar integrates features from state-of-the-art FreeBSD 4.4...
KLAATU, BORADA, NIh*ahem*
Using the executable file of the process would be dangerous because the attacker could use compromized shared libraries. Any passwords would require changes in the software (i.e. you'll have to recompile apache so that it could authenticate).
The only thing I can think of is a token in the process environment that can only be set by root (maybe an additional group ID). So apache would still have to be run by a program with root permissions (init script) to be able to listen to port 80.
This is the first real kernel-level security feature in OpenBSD.
Earlier versions of OpenBSD had only application-level security (secure applications, but running as root, and therefore no effective OS-level security below the application-level).
Granting certain privileges to an application instead of all-powerful superuser-privileges is IMO the most-important security feature of a secure operating system - this is a standard feature on every trusted unix system, and actually i believe it should be a standard feature on every unix platform.
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.
I've used ssh to rid myself of things like "su -l" and "sudo" before. I think the basic idea can be used to get rid of necessary suid/sgid programs with elevated permissions. The basic theory is each application is actually called by a wrapper using ssh. Public keys from the application's user or group (root, apache, wheel, etc.) are provided to a user with genuine need to access these apps and placed in the ~/.ssh/authorized_keys(2) file. Then the user's public key is provided to the application user's ~/.ssh/authorized_keys(2) file. When the user calls the application, they are allowed access using RSA key authentication. No need for blind SUID/SGUID apps as only those users who need to use it have the permission. Furthermore, these permissions can be easily revoked by a.)changing the app's private/public keypair without providing them to the user, or b) commenting/deleting the user from the authorized file. Additionally, with ssh-agent, keychain, and authorization forwarding, these priveledges can be locked down tight. I'm not sure if openssh authorization forwarding will allow the authorization to be okayed from a remote machine. Just a random thought that seems appropriate here. Let me know what you think.
--Wes
I always get the shakes before a drop.
I think that's what I'm talking about. I was trying to make a joke about how these things were already tried w/ transistors. Maybe it is time to reexamine that thinking. (Or not.)
Thanks,
cts
P.S.
Ya, I know, but when REP MOVSB was cool, so was 64k (Ok, it lasted through the 286, but you know what I mean.) And why don't we use the >2 levels of privilege? (I don't know, but it's probably on lkml. Are the other ports better w/ this?)
P.P.S
wouldn't "mov ip,Word Processor" be cool!!!!
It seems like a good idea, but since I am no Unix expert, could you please someone explain why, for example, accessing port 80 (web access) needs root access ?
Operating systems should not have any super user (root) account at all.
Why?
Those super priviledges are an anachronism which doesn't fit the world. Most of us live in a democratic society. Democracy has historical won over the hierarchical societies - for a reason. Now if we want to model the real world, we are orced to map it to a kingdom like world. If there was no super user to hack a lot of vulnerabilities where gone.
But we need administration! Yes, we need even more fine grained access control, but no entral authority. We need to grant and revoke rights and subrights among each other.
How? The Paper Askemos - a virtual settlement describes (among other aspects of Askemos) a set theory based priviledge system which handles that. (You might also look at the slides from the most recent talk at the netobjectdays.org conference here
(there only temporary).
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/
I just wonder, why so complicated ? Mandatory Access Controls, Priviledge Elevation ... some administrative nightmare. Probably more security holes by misconfiguration that bad code. Think sendmail.
...
Why do certain applications need to have root priviledges at all ?
Wouldn't it be more wise, to allow certain users to actually perform certain tasks. Fighting the cause but the symptom.
Like, defining e.g. via sysctl that user "named" is allowed to bind to port 52 on IP 1.2.3.4.
(You could still use capabilities to disallow sysctl.conf when in multiusermode)
That would be, only user "named" could bind, not even root to that ip/port.
So instead of "lifting" a binary to temporary root priviliedges with some black magic to allow some syscalls, why not telling the kernel that this user may do this and this
The difference is, you need no whatsoever "root faking". Don't let an application ever become root or needing rootpriviledges (when configured), no matter for how little time it may be.
Instead, be able to grant privileges to users at lowest level, insteat of cheating on the higher ones.
Existing programs will assume that if a process demonstrates one privilege that traditionally only a root process posesses, then it must also have all the others
Assumptions cause trouble, lets assume that this buffer is "more than big enough for anything someone will put in there", that worked out REALY well didn't it?
A proper program should check for each individual requirement, and act appropriately. Bad code has lots of assumptions, an assumption is a bug that hasn't been found yet.
Most of my code isn't proper, I'm lazy.
This works for httpd fairly well. However, consider procmail. It needs to be able to write to any users mail file. So for certain servers it works well. For certain ones it does not. Others that might have problems would be crond also. If crond cannot switch to the proper user when executing it will not work either.
I don't see how this buys too much though. It doesn't explain the configuration policy. But I suppose if you can allow a certain app with the full path and maybe a checksum on the binary, then set the permissions to the app. like this: /usr/bin/procmail checksum +setuid() +setgid()
That might work. But it seems easier to just say you will allow procmail to run setuid root. It keeps the idea simpler and does not require that the administrator know exactly what syscalls procmail makes.
In summary, this might be a cool idea, but I think expecting a sysadmin to know exactly what syscalls an application needs to have for permissions is a bit much. Sure, you may claim that the admin should know these things, but do you really think an admin reads/understands all the source code that goes onto his system? I highly doubt it.
Norris/Palin 2012
Fact: We deserve leaders who can kick your ass and field dress your carcass.
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.
There are still a lot of problems with capabilities.
..
a tis-capability)
* Simple security paradigm with a single simple-logic security test per request.
What if you delete an object? You'd have to revoke capabilities on all processes, or otherwise these processes could gain access to re-allocated space - this would compromise the object-reuse-protection mechanismn.
The principle of least privelege (Your mp3 player cannot delete your files, your email client cannot listen on any port, etc).
But you would have to define different capabilities for the same program used by different users, because you don't want user A to read user B's files with the mail program that both users share. Still not very simple.
No global namespace
Another thing which makes it pretty complicated. How do you manage your data? You could only manage mail files with your mail program, sound files with your mp3 player, and so on
The catch is that user A has no way to know what other programs are running on behalf of user B. All of these programs will gain access to C when userB is added to the access list for C. There is no way to grant object access to a single program B without potentially granting access to other programs as well.
In a capability system, the transfer is restricted to program B, because the capability is transfered only to program B. The default situation is that other programs do not gain access to the object.(http://www.eros-os.org/faq/basics.html#wh
As soon as you break into a program which has a certain capability, you can transfer this capability to another program.
The result is exactly the same: You're potentially granting access to all other applications. Still not secure.
The most secure solution for very restricted data sharing is still compartment mode and information labeling.
Modern unix environments use a combination of access lists (for access to objects), capabilities (for process privileges) and capability inheritance controls. One of these systems is the only Operating System which is evaluated at the TCSEC B3 level by NSA (for those who don't know it: that means ZERO DESIGN FLAWS)
---
There are a lot of other problems with capability-based systems, especially when you want to share data between processes (and that's probably why you're using ONE computer for two programs and not TWO computers for two programs. Commercial applications need to share data).
IBM's S/38 (the predecessor of the AS/400) had a capability-based access control, which needed only one initial security check, and then used the capability to allow access to a certain object.
Object reuse protection was available, because neither S/38's nor AS/400's ever reuse a virtual memory address.
On the AS/400 the capability flag in object pointers can't be used by user space applications any more, because of the problems related with revoking access to objects after a process has been granted access to an object by giving it a capability. Only the SLIC kernel allows itself to hold capabilities.
Another very important thing (perhaps the most important thing at all) is, that a capability is nothing else than a piece of data which can be used by a program - for example, a pointer with a certain bit set or cleared, indication valid authority (security checks performed) or invalid authority (security checks not performed).
Therefore you also need to protect these pointers from modification (IBM's AS/400 has pointer protection for object pointers built into the hardware, but don't confuse this with space pointers - this has only little to do with protection from buffer overflows and such, it's more like protected mode on other platforms, because AS/400s have a virtual single level store and for this reason you need some kind of protected pointer; complicated, as u can see).
So how do you protect a program which has some capability from modifying some pointer or other data structure which has something to do with the capability? You still need something like a system call everytime you use a capability, because you need to go into kernel mode to be able to work with capabilities that are protected from modification by user space processes.
---
I'd recommend you read 'Fortress Rochester'. This book was written by Frank Soltis, the system architect of the S/38 and the AS/400; in his book he explains some of the problems involved with capability-based access control, and why capabilites have been moved out of (even hardware protected!) system pointers on the AS/400.
The flaw with this is that your named can still be subverted, and run any number of other syscalls, for things like reading files, creating files (albeit in places with 777 perms), binding other ports, exec a shell, fork some other app (a trojan that was uploaded to /tmp?), and so many other things.
/etc/localtime and write to certain network sockets (syslogd? nameserver queries/responses?). It can't write to /tmp, can't exec, can't fork, can't read other files in /home or /etc or elsewhere, or any of the sorts of potentially dangerous things that vulnerable apps have been known to do (the Apache/OpenSSL worm comes to mind).
You're talking about minimal uid privilege, which isn't really "minimal" at all.
systrace is about minimal syscall privilege - unless you as the sysadmin have explicitly allowed all of those things above, named can do nothing whatsoever. The policy would perhaps elevate privileges to bind to port 53/udp&tcp only on a single IP address, read configuration files from a certain path only, load certain shared libraries (libc is the obvious one), read