From mboxrd@z Thu Jan 1 00:00:00 1970 From: sbaugh@catern.com Subject: Re: Providing an alternative to setuid in GuixSD Date: Mon, 24 Oct 2016 18:01:47 -0400 Message-ID: <8760ohh0dw.fsf@catern.com> References: <87funnhz7h.fsf@catern.com> <878tteli9w.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:47683) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bynK7-0004ZR-JK for guix-devel@gnu.org; Mon, 24 Oct 2016 18:02:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bynK3-0008If-Ic for guix-devel@gnu.org; Mon, 24 Oct 2016 18:02:27 -0400 Received: from [195.159.176.226] (port=58434 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bynK3-0008I6-8L for guix-devel@gnu.org; Mon, 24 Oct 2016 18:02:23 -0400 Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1bynJj-0005xS-5T for guix-devel@gnu.org; Tue, 25 Oct 2016 00:02:03 +0200 List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: guix-devel@gnu.org Chris Marusich writes: > Hi, > > I don't think I have all the answers, but this is an interesting topic, > so I'll chime in with what I can. I'm sure others will have more > thoughts to share, too. > > sbaugh@catern.com writes: > >> 1. Each binary is an attack surface which is frequently exploited by >> attackers for local privilege escalation. So getting rid of them >> would improve security. >> >> 2. setuid binaries make access control decisions in an environment >> controlled by the user running them, by looking at files at absolute >> paths in that environment, such as /etc/passwd. Thus, if unprivileged >> users had access to chroot or other filesystem namespacing >> functionality, those users could escalate privileges by manipulating >> /etc/passwd, /etc/shadow, /etc/sudoers, and then running a setuid >> binary. So unprivileged chroot is not possible. > > When you say "filesystem namespacing functionality," are you referring > to the Linux feature known as "user namespaces"? I was referring to things which correspond ~directly to chroot, like mount namespaces or Plan 9 namespaces. But it's best to just consider chroot I think. The vulnerability is most clear when chroot is unprivileged, but it is present in any system with setuid binaries and the ability to perform non-trivial filesystem namespace manipulations without privileges. (In particular, to change what the root directory points to) Given chroot, all you need to do is: 1. Create your own filesystem tree with your own /etc/passwd and /etc/shadow which specifies a known password for root. 2. Chroot into that filesystem tree 3. Run su and provide the known password for root; it will check the password against the /etc/shadow that you created. 4. Escape the chroot. Once you have root in the chroot, there are many mechanisms for doing this. For example, create a device file corresponding to the real root fs, mount it, and chroot again there. 5. Enjoy your new root privileges in the main filesystem namespace. > There is an article on LWN that discusses some of the security issues > surrounding this: > > Filesystem mounts in user namespaces > https://lwn.net/Articles/652468/ > > I admittedly don't know a lot about this feature, but it sounds like it > is not currently designed to let a user escalate privilege in a way that > would enable malicious modification of system files such as /etc/passwd. > Can you clarify your second concern a little more to help me understand? That's partially correct; user namespaces would not allow modification of the "real" /etc/passwd, but they would allow you to create a mount namespace where you can put whatever file you want in place of /etc/passwd. In fact, you could get up to step 4 of the above attack. But then you would be stuck: You are not supposed to be able to escape a user namespace even with root, and while you are still inside a user namespace your privileges don't mean anything. So, user namespaces provide an alternative solution. But they also independently expose quite a large attack surface, and I am not really optimistic about them being accessible unprivileged in any mainstream distro any time soon... I am much more optimistic about the project of eliminating setuid binaries and thereby allowing "plain old chroot" to be safely done without privileges. This would only allow an a small subset of the functionality of user namespaces, but it would be enough for a lot of applications. > It would be nice if the Guix daemon could create chroots for building > packages even when it runs as a non-privileged user. That is definitely > a limitation (see the comment about "--disable-chroot" in (guix) Build > Environment Setup). However, I don't understand how eliminating setuid > binaries would enable unprivileged access to root. Can you clarify why > the latter follows from the former? Eliminating setuid binaries means step 3 in the above attack outline is not possible. A distribution without setuid binaries could therefore safely turn on unprivileged access to chroot. >> == How to do it == >> >> Most (all?) setuid binaries can be replaced with a non-setuid binary >> which performs local IPC to a privileged daemon. >> >> The largest targets for elimination are sudo and su. Luckily there is >> already a ready alternative for those commands: ssh. We can augment lsh >> with the rich access controls of sudo, add any extra missing features, >> and then replace sudo/su with wrappers around ssh. (A wrapper would be >> needed just for sheer familiarity of the system to a user.) sshd runs >> and performs access controls in a fixed environment, so this is not >> vulnerable to the chroot attack I mentioned above. >> >> Once we have a solid replacement for sudo, we can take a generic >> approach to eliminating other setuid binaries: just replace them with >> wrappers which call 'sudo command "$@"', and make sure the >> sudo-replacement is appropriately configured to allow running that >> command without authentication. >> >> I believe we could do this with all binaries, though there may be some >> issues I'm not yet aware of yet. >> >> In the longer term I'm not sure if we would want to individually >> replace setuid binaries with IPC-performing commands. The only real >> benefit is maybe elegance... > > That's an interesting idea. Some questions come to mind: > > * How would we allow one user to run a program as a different user? Well, if user A can authenticate as user B, they certainly can also run a program as user B through normal ssh-like means. So I assume you mean allowing user A to run a program as user B only by authenticating as user A. I believe that can be achieved with some ssh tricks. (I've done just this with ssh and Kerberos principals before; I believe you could do the same with ssh and Unix authentication but I haven't thought about it in much detail so I'm waving my hands a bit here) > * How would we allow a user to update their own entries in shared > databases like /etc/passwd? Through IPC to a privileged process: The "passwd" tool, as an example, could simply send a message providing the new password to a daemon privileged to perform the actual update. Alternatively for case of passwd specifically, we could use the tcb framework of Openwall: http://www.openwall.com/tcb/ Which is a somewhat more elegant trick, but may be more work and less compatible. (I'm also not sure that it works with absolutely all PAM modules; there could be some besides the basic files authentication which anticipate running as root. But I don't know for sure.) > * Could this approach work with any kernel, not just Linux? Definitely. As described currently it's totally kernel-independent. At some point, file-descriptor-passing-over-Unix-sockets might be useful. That would add a very small amount of kernel-dependence as that is sometimes available in different ways on different Unix kernels. (But it is still generally available.) > * Because the daemon must have enough privileges to take any potential > action that might be requested, does this solution fail to enforce the > principle of least privilege in basically the same way that many setuid > programs do (because they start with more privileges than they need)? Yes. However, it's a big advance over setuid, because the daemon runs in a fixed environment, rather than running in an environment entirely controlled by an unprivileged user. And that is enough of an improvement to get big benefits, namely, safe unprivileged chroot. > * Do you know of any prior art in this area which is similar to what you > are proposing? I saw some interesting-looking references in the Protego > paper linked above, but I didn't go down the rabbit hole. Yes, there is some pre-existing software which is directly relevant: - s6-sudod, which is explicitly for this purpose: http://skarnet.org/software/s6/s6-sudod.html - remctl, which is much older but could be usable for this purpose: https://www.eyrie.org/~eagle/software/remctl/ - systemd's machinectl has a "shell" subcommand for getting a shell in containers running on the local host, or on the local host itself: https://www.freedesktop.org/software/systemd/man/machinectl.html I don't know of any Unix/Linux distributions that really use this approach. There's some similarity to Plan 9; Plan 9 has unprivileged namespacing in part because it doesn't have setuid. Of course, Guix is also an example of this IPC-to-privileged-action approach: To perform the privileged action of isolating our builds, we perform IPC to another more privileged process which does it for us.