| Summary: | /etc/shells security vagueness affecting ports | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Phil Pennock <freebsd> |
| Component: | misc | Assignee: | Ports Security Team <ports-secteam> |
| Status: | Closed Not A Bug | ||
| Severity: | Affects Some People | CC: | portmgr, swills |
| Priority: | --- | ||
| Version: | CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
I would say the description in /usr/src/etc/shells is right and chpass is fine. The fact that people at some point took it as "list of all available shells" is the problem. One might even argue ports shouldn't touch /etc/shells at all, that it's up to the admin to decide which shells are acceptable. So, I would agree the man page for shells(5) is off and at the least the ports that add restricted shells to /etc/shells should be changed. Thinking about this more, I have changed my mind. The basic text for shells.5 hasn't changed ever: https://svnweb.freebsd.org/base/head/share/man/man5/shells.5?annotate=263142 And I don't think there's any issue with it. The history of this file seems to go against the idea that "20 years ago, it was considered a security flaw for /etc/shells to list an untrusted shell". I'm not actually convinced there's a security issue here. You say: if arbitrary code can be gotten running as uid N, it can invoke chpass to change shell to any shell listed in /etc/shells But if you can run arbitrary code as a particular user, you can by definition do anything as that user, such as copy files, delete files, etc. Changing the shell to something else is just one of those things. But if arbitrary code can run as that user, what's the benefit to an attacker of changing the shell? There's only downside, such as possibly setting off alarms that a users shell changed, IMHO, since they can do whatever they want. There is the question of a user running a restricted shell being able to change their shell using chpass. With the unrestricted shells in /etc/shells they can do that, but we of course don't want to remove the unrestricted shells from /etc/shells as that would prevent unrestricted users from changing their shells. The text in /usr/src/etc/shells certainly suggests that it should contain the unrestricted shells. So the only thing that can be done is to either remove the setuid bit from chpass or remove chpass entirely. There are ENABLE_SUID_K5SU, ENABLE_SUID_NEWGRP and PPP_NO_SUID flags for make.conf Perhaps a CHPASS_NO_SUID flag would be useful? Or you could mount your filesystem(s) without the nosuid option. But of course these are local customizations, we wouldn't want to do that by default. The restricted user can't change shell from "rfoo" to "foo" just because "foo" is listed in /etc/shells, because _both_ the "before" and "after" shells must be listed. Within a single system, I think that you're right and it's not a privilege escalation attack. It's a privilege persistence attack and good monitoring of login shells should catch it. The worst scenarios aren't Ports tree so much as NIS/LDAP within an org, systems where the shell is overridden in the map used by that host to a very limited menu program. The user logs in, gets access to chsh in the NIS map and can then log into any other host using the same map. That's the privilege escalation that was kicking around in the recesses of my memory, but for the industry I work in, it's been a long time since I've seen NIS used. And _those_ menu programs are not getting auto-added to /etc/shells by Ports. But the current text of shells(5) is mis-leading for them, because its interaction with chpass/chsh/chfn is not documented. It's fine to declare "privilege persistence" out-of-scope. For myself: on my current systems all users authenticate with ssh-keys, I don't have pam_ssh_agent_auth installed, so chpass is unusable anyway, so I drop the setuid bit. So: shells(5) should be updated to tell administrators of the consequences of adding shells to the file, because of how it's used? And no changes to Ports? But, mmm, a user with a restricted shell should not be allowed to run chpass, the idea is that they have a shell with a restricted number of commands available, and thus, cannot run chpass. It'd a bit like giving me a restricted shell allowing me to run vim. Ok, so, I will run vim, then :!csh, and I'll be out of the restricted area. Bugs happen, restricted shell setups leak, people find ways out and then get to see if they can stay outside their confines. Thus privilege persistence. See: https://en.wikipedia.org/wiki/Restricted_shell#Weaknesses_of_a_restricted_shell the last part of which is going to work in all uses of restricted shell that don't setup a separate chroot for the user as well, or at least limit PATH to a directory with only select binaries in it. That list should of course not contain an suid chpass. If you provide a restricted shell, provide restricted commands, don't allow vi or vim, allow rvim. But this is not /etc/shells's fault. (In reply to Mathieu Arnold from comment #7) Right. Likewise, don't provide chpass. So, there's nothing to do here. Closing. |
The shells(5) manpage describes /etc/shells as "a list of the shells on the system". The top of /usr/src/etc/shells documents the historical meaning: # List of acceptable shells for chpass(1). # Ftpd will not allow users to connect who are not using # one of these shells. My recollection is that 20 years ago, it was considered a security flaw for /etc/shells to list an untrusted shell, as the whole point was to define "if a user has one of these shells, then they're trusted for local system access". Indeed, /usr/bin/chpass is setuid-root and uses "ok_shell()" to enforce exactly this behavior; so if arbitrary code can be gotten running as uid N, it can invoke chpass to change shell to any shell listed in /etc/shells, as long as the current shell is listed in that file too. Thus providing a privilege escalation attack. Yet the standard behavior of Ports is to add _all_ shells, including restricted shells, to /etc/shells. grep '^@shell' /usr/ports/shells/*/pkg-plist rbash, rzsh, scponly; also devel/git adds libexec/git-core/git-shell too. Users with any of those should _not_ be able to change their shell. The only reason I can think of to add these shells to /etc/shells is some gateway software deciding to only allow access if the shell is listed and so rejecting restricted shells ... which is a bug. So either the description in /usr/src/etc/shells is wrong and chpass is a security hole, or the man-page shells(5) is wrong and has led to many Ports being configured to introduce security holes when installed.