Re: Linux PAM (up to 0.64-2) local root compromise

From: Savochkin Andrey Vladimirovich (sawat_private)
Date: Thu Dec 24 1998 - 07:02:03 PST

  • Next message: plasmoid deep/thc/clb: "Re: Merry Christmas to Sun! (Was: L0pht NFR N-Code Modules"

    --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--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:26:16 PDT