Hi, I am posting to a public list as this issue has been already disclosed publicly on full-disclosure mailing list. This looks a bit worrying: http://lists.grok.org.uk/pipermail/full-disclosure/2010-August/075944.html Looks like the per-user login capability database (~/.login_conf, ~/.login_conf.db) functionality is creating a vulnerability. What I found especially worrying is that this user-supplied untrustable file is being parsed and processed by various daemons and other login mechanisms BEFORE permanently dropping root privileges. Unless there is a very strong reason, which I am overlooking, to do so, I find this design very flawed. It makes the following possible for example: - System administrator sets a limit (for example datasize) in /etc/login.conf to a certain class of users, and expects it to limit those users' use of system resources. - User creates their own .login_conf where they set the limit unlimited. This succeeds because the user's .login_conf{,.db} is processed before dropping privileges. The problematic execution order is evident by doing for example the following: - Enable tracing of sshd and its child processes (as root): # ktrace -i -p `cat /var/run/sshd.pid` - Log in as normal user with sshd from other terminal and do nothing there. Just log out immediately or whatever. - Stop the trace: # ktrace -C - Examine the execution order in the trace (pay attention to process ID numbers): # kdump | grep ' sshd ' | grep 'NAMI.*/.login.conf\|set.*uid' | less I think that the following is needed: - Change the execution order in several daemons, maybe in PAM? /usr/bin/login? - Fix the database handling routines (the problem pointed out in HI-TECH's e-mail to full-disclosure). Even if the user-specific login capabilities database is being processed in the user's context, this might still allow for example breaking to /bin/sh from an (authorized) ftp-only account. - Add a flag in global login capababilities database for choosing whether the per-user login capabilities should be processed and make it DISABLED default. User-specific .login_conf{,.db} would be processed only if excplicitly enabled by the administrator. I think this bug goes in to a class of local privilege escalation. Am I missing something obvious? What do you think? -- Janne Snabb / EPIPE Communications snabb@epipe.com - http://epipe.com/
> What I found especially worrying is that this user-supplied untrustable > file is being parsed and processed by various daemons and other > login mechanisms BEFORE permanently dropping root privileges. Unless > there is a very strong reason, which I am overlooking, to do so, I > find this design very flawed.This seems to be incorrect for both ftpd and sshd on 6.4-RELEASE. 41673 sshd CALL setuid(0xbb8) 41673 sshd RET setuid 0 41673 sshd CALL seteuid(0xbb8) 41673 sshd RET seteuid 0 41673 sshd NAMI "/home/venglin/.login_conf" 41673 sshd NAMI "/home/venglin/.login_conf.db" 41673 sshd NAMI "/home/venglin/.login_conf.db" 41513 ftpd CALL seteuid(0xbb8) 41513 ftpd RET seteuid 0 41513 ftpd NAMI "/home/venglin/.login_conf" 41513 ftpd NAMI "/home/venglin/.login_conf.db" 41513 ftpd NAMI "/home/venglin/.login_conf.db" Back in 2001 I found a very similar vulnerability in 4.4-RELEASE, which allowed to read any file in system with root privileges: http://marc.info/?l=bugtraq&m=100101802423376&w=2 Since then, elevated privileges are dropped before parsing login_conf. -- * Fido: 2:480/124 ** WWW: http://www.frasunek.com ** NICHDL: PMF9-RIPE * * Jabber ID: venglin@nette.pl ** PGP ID: 2578FCAD ** HAM-RADIO: SQ5JIV *
On Tue, 10 Aug 2010, Przemyslaw Frasunek wrote:> This seems to be incorrect for both ftpd and sshd on 6.4-RELEASE. > > 41673 sshd CALL setuid(0xbb8) > 41673 sshd RET setuid 0 > 41673 sshd CALL seteuid(0xbb8) > 41673 sshd RET seteuid 0 > 41673 sshd NAMI "/home/venglin/.login_conf" > 41673 sshd NAMI "/home/venglin/.login_conf.db" > 41673 sshd NAMI "/home/venglin/.login_conf.db"The above actually seems correct to me. Both uid and euid are set before accessing the capabilities. On 8.1-RELEASE this is different, only euid is set to the user (to make it possible to access this file if the home directory happens to be NFS mounted without root access?).> 41513 ftpd CALL seteuid(0xbb8) > 41513 ftpd RET seteuid 0 > 41513 ftpd NAMI "/home/venglin/.login_conf" > 41513 ftpd NAMI "/home/venglin/.login_conf.db" > 41513 ftpd NAMI "/home/venglin/.login_conf.db"This is clearly wrong, it is still possible to change euid back to 0. It is still possible to setrlimit() anything.> Back in 2001 I found a very similar vulnerability in 4.4-RELEASE, which allowed > to read any file in system with root privileges: > > http://marc.info/?l=bugtraq&m=100101802423376&w=2Hehe... I was about to try out this one next. -- Janne Snabb / EPIPE Communications snabb@epipe.com - http://epipe.com/
On Tue, 10 Aug 2010, Janne Snabb wrote:> Looks like the per-user login capability database (~/.login_conf, > ~/.login_conf.db) functionality is creating a vulnerability.Attached is a temporary workaround for anyone who is worried about this problem. It disables per-user login capability databases completely. Only the system wide /etc/login.conf is used. Do not apply the patch if you need per-user login capabilities. This should work on 8.1-RELEASE, most likely on some other releases as well. I did not find any references to the evil ~/.login_conf{,.db} anywhere else in the source except in lib/libutil/login_cap.c. 1. Save the attached login_cap.c.diff in /tmp 2. cd /usr/src/lib/libutil 3. patch < /tmp/login_cap.c.diff 4. make 5. make install 6. re-start any affected daemons: /etc/rc.d/sshd restart /etc/rc.d/ftpd restart The relevant files are /lib/libutil.* and /usr/lib/libutil.* if you build on one machine and distribute binaries to others. Re-start the relevant daemons at each machine after updating the libutil libraries. -- Janne Snabb / EPIPE Communications snabb@epipe.com - http://epipe.com/ -------------- next part -------------- --- login_cap.c.orig 2010-06-14 02:09:06.000000000 +0000 +++ login_cap.c 2010-08-10 14:55:13.000000000 +0000 @@ -194,11 +194,13 @@ int r, me, i = 0; uid_t euid = 0; gid_t egid = 0; const char *msg = NULL; const char *dir; +#ifdef XXX_USER_LOGIN_CONF_ENABLED char userpath[MAXPATHLEN]; +#endif static char *login_dbarray[] = { NULL, NULL, NULL }; me = (name != NULL && strcmp(name, LOGIN_MECLASS) == 0); dir = (!me || pwd == NULL) ? NULL : pwd->pw_dir; @@ -213,15 +215,17 @@ egid = getegid(); (void)setegid(pwd->pw_gid); (void)seteuid(pwd->pw_uid); } +#ifdef XXX_USER_LOGIN_CONF_ENABLED if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) { if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) login_dbarray[i++] = userpath; } +#endif /* * XXX: Why to add the system database if the class is `me'? */ if (_secure_path(path_login_conf, 0, 0) != -1) login_dbarray[i++] = path_login_conf;
Janne Snabb <snabb@epipe.com> writes:> This looks a bit worrying: > > http://lists.grok.org.uk/pipermail/full-disclosure/2010-August/075944.htmlIt would be easier to take this seriously if it didn't come from a script kiddie who clearly does not understand the tools he's using. DES -- Dag-Erling Sm?rgrav - des@des.no
On 2010-08-10, Janne Snabb wrote:> Looks like the per-user login capability database (~/.login_conf, > ~/.login_conf.db) functionality is creating a vulnerability.See also PR bin/141840: http://www.freebsd.org/cgi/query-pr.cgi?pr=141840 -- Jaakko
Are there any other tricks / work around people have implemented ? MACs ? ---Mike At 11:25 AM 8/10/2010, Janne Snabb wrote:>On Tue, 10 Aug 2010, Janne Snabb wrote: > > > Looks like the per-user login capability database (~/.login_conf, > > ~/.login_conf.db) functionality is creating a vulnerability. > >Attached is a temporary workaround for anyone who is worried about >this problem. It disables per-user login capability databases >completely. Only the system wide /etc/login.conf is used. Do not >apply the patch if you need per-user login capabilities. > >This should work on 8.1-RELEASE, most likely on some other releases >as well. I did not find any references to the evil ~/.login_conf{,.db} >anywhere else in the source except in lib/libutil/login_cap.c. > >1. Save the attached login_cap.c.diff in /tmp > >2. cd /usr/src/lib/libutil > >3. patch < /tmp/login_cap.c.diff > >4. make > >5. make install > >6. re-start any affected daemons: > /etc/rc.d/sshd restart > /etc/rc.d/ftpd restart > >The relevant files are /lib/libutil.* and /usr/lib/libutil.* if you >build on one machine and distribute binaries to others. Re-start >the relevant daemons at each machine after updating the libutil >libraries. > >-- >Janne Snabb / EPIPE Communications >snabb@epipe.com - http://epipe.com/ > >_______________________________________________ >freebsd-security@freebsd.org mailing list >http://lists.freebsd.org/mailman/listinfo/freebsd-security >To unsubscribe, send any mail to "freebsd-security-unsubscribe@freebsd.org"-------------------------------------------------------------------- Mike Tancsa, tel +1 519 651 3400 Sentex Communications, mike@sentex.net Providing Internet since 1994 www.sentex.net Cambridge, Ontario Canada www.sentex.net/mike