[8829] in bugtraq
Re: Linux PAM (up to 0.64-2) local root compromise
daemon@ATHENA.MIT.EDU (Savochkin Andrey Vladimirovich)
Thu Dec 24 22:12:13 1998
Date: Thu, 24 Dec 1998 18:02:03 +0300
Reply-To: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: Savochkin Andrey Vladimirovich <saw@MSU.RU>
X-To: Michal Zalewski <lcamtuf@IDS.PL>
To: BUGTRAQ@NETSPACE.ORG
In-Reply-To: <Pine.LNX.4.05.9812231312190.28401-100000@dione.ids.pl>; from
"Michal Zalewski" on Wed, Dec 23, 1998 at 01:12:45PM
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
On Wed, Dec 23, 1998 at 01:12:45PM +0100, Michal Zalewski wrote:
> As someone said, "Never make any mistaeks."
>
> Latest release of Linux Pluggable Authentication Modules (pam-0.64-2, as
> well as previous ones), has huge security flaw in pam_unix_passwd.so
> module, which can be exploited to gain read/write permissions to
> /etc/shadow file.
>
[snip]
> Default password change routine in pam_unix_passwd.so module, called
> from passwd utility, creates temporary file /etc/nshadow using fopen().
> Unfortunately, process umask isn't changed. After approx. 3 syscalls,
> chmod is called to set proper mode on this file (0600). But, for these
> 3 syscalls, file permissions are equal to 0666 ~ umask. If umask of
> current process (which is inherited from parent process, of course)
> is set to 0, we have /etc/nshadow file with permissions 0666. Then,
> after all, it's moved using rename() to /etc/shadow. Cute.
Thank you for the report.
The attached patch takes care of file creation permissions in
pam_unix_passwd and pam_tally modules. I should warn people that the patch
isn't well tested. pam_unix_passwd module can't be tested on my system.
It doesn't work at all because of a glibc bug.
Best regards
Andrey V.
Savochkin
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pam-0.65-umask.patch"
diff -ru Linux-PAM-0.65.orig/modules/pam_tally/pam_tally.c Linux-PAM-0.65/modules/pam_tally/pam_tally.c
--- Linux-PAM-0.65.orig/modules/pam_tally/pam_tally.c Thu Jan 15 01:08:33 1998
+++ Linux-PAM-0.65/modules/pam_tally/pam_tally.c Thu Dec 24 17:12:21 1998
@@ -137,13 +137,16 @@
int lstat_ret = lstat(filename,&fileinfo);
if ( lstat_ret && *tally!=TALLY_HI ) {
- if ( ( *TALLY=fopen(filename, "a") ) ) {
- /* Create file, or append-open in pathological case. */
+ int oldmask = umask(077);
+ *TALLY=fopen(filename, "a");
+ /* Create file, or append-open in pathological case. */
+ umask(oldmask);
+ if ( !*TALLY ) {
_pam_log(LOG_ALERT, "Couldn't create %s",filename);
return PAM_AUTH_ERR;
}
+ lstat_ret = fstat(fileno(*TALLY),&fileinfo);
fclose(*TALLY);
- lstat_ret = lstat(filename,&fileinfo);
}
if ( lstat_ret ) {
@@ -563,6 +566,8 @@
*argv);
exit(0);
}
+
+ umask(077);
/*
* Major difference between individual user and all users:
diff -ru Linux-PAM-0.65.orig/modules/pam_unix/pam_unix_passwd.c Linux-PAM-0.65/modules/pam_unix/pam_unix_passwd.c
--- Linux-PAM-0.65.orig/modules/pam_unix/pam_unix_passwd.c Thu Oct 9 06:59:04 1997
+++ Linux-PAM-0.65/modules/pam_unix/pam_unix_passwd.c Thu Dec 24 16:53:30 1998
@@ -554,6 +554,7 @@
int err = 0;
#ifdef HAVE_SHADOW_H
struct spwd *spwdent=NULL, *stmpent=NULL;
+ int oldmask;
#endif
if(flags & PPW_SHADOW) { retval |= PPW_SHADOW; }
gettimeofday(&time1, NULL);
@@ -583,7 +584,9 @@
return PPW_NOSUCHUSER;
spwdent->sp_pwdp = towhat;
spwdent->sp_lstchg = time(NULL)/(60*60*24);
+ oldmask = umask(077);
pwfile = fopen(SH_TMPFILE,"w");
+ umask(oldmask);
opwfile = fopen("/etc/shadow","r");
if(pwfile == NULL || opwfile == NULL)
return PPW_ERROR;
@@ -623,7 +626,9 @@
unlink(SH_TMPFILE);
} else {
pwd->pw_passwd = towhat;
+ oldmask = umask(077);
pwfile = fopen(PW_TMPFILE,"w");
+ umask(oldmask);
opwfile = fopen("/etc/passwd","r");
if(pwfile == NULL || opwfile == NULL)
return PPW_ERROR;
@@ -659,7 +664,9 @@
}
#else
pwd->pw_passwd = towhat;
+ oldmask = umask(077);
pwfile = fopen(PW_TMPFILE,"w");
+ umask(oldmask);
opwfile = fopen("/etc/passwd","r");
if(pwfile == NULL || opwfile == NULL)
return PPW_ERROR;
--UlVJffcvxoiEqYs2--