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

From: Michal Zalewski (lcamtufat_private)
Date: Wed Dec 23 1998 - 04:12:45 PST

  • Next message: Pedro Ribeiro: "3COM Documentation backdoors in CB3500"

    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.
    
    Vunerable platforms:
    --------------------
    
    Almost any Linux with PAM + PAM-compliant passwd utility. Both RFC and
    PAM readme recommends pam_unix_passwd.so as default password manipulation
    routine. Note: RedHat 5.x distribution isn't vunerable, because this
    module is obsoleted with newer, universal pam_pwdb.so, while bug in
    pam_unix_passwd.so (shipped with dist) is still present.
    
    In the other words, if you have Linux PAM installed on your system 'by
    hand', as described in RFC/FAQs, your system is vunerable. Default RedHat 5.x
    installation is less or more secure. We have no information about other
    PAM-compliant distributions.
    
    There's no information about SunOS/Solaris/etc PAM, as it's slightly
    different than Linux version.
    
    Quick vunerability test:
    $ grep pam_unix_passwd /etc/pam.conf /etc/pam.d/passwd
    
    Compromise:
    -----------
    
    - Read and write permissions to /etc/shadow file,
    - Superuser privledges, locally.
    
    Description:
    ------------
    
    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.
    
    strace output for critical part of code:
    
    2957  open("/etc/nshadow", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 8
    [...]
    2957  chown("/etc/nshadow", 0, 0)       = 0
    2957  chmod("/etc/nshadow", 0600)       = 0
    [...]
    2957  rename("/etc/nshadow", "/etc/shadow") = 0
    
    Impact:
    -------
    
    <ttyp1>
    [lcamtuf@nimue /]$ umask 0
    [lcamtuf@nimue /]$ echo $$
    3023
    [lcamtuf@nimue /]$ exec passwd
    Changing password for lcamtuf
    (current) UNIX password:
    New UNIX password:
    <ttyp2>
    [root@nimue /root]# gdb passwd 3023
    Attaching to program `/usr/bin/passwd', process 3023
    [...]
    0x400c37b4 in __read ()
    (gdb) break chown
    Breakpoint 1 at 0x400c4480
    (gdb) c
    Continuing.
    <ttyp1>
    Retype new UNIX password:
    <ttyp2>
    Breakpoint 1, 0x400c4480 in chown ()
    <ttyp3>
    [root@nimue /root]# ls -la /etc/nshadow
    -rw-rw-rw-   1 root     root            0 Dec  4 11:56 /etc/nshadow
    
    Typical race. Considerated exploitable :-)
    
    The closing:
    ------------
    
    Lame fix:   chmod -s /usr/bin/passwd
    Better fix: add umask(077); somewhere ;P
    Thanks to:  Nises and manY for patience :-)
    
    _______________________________________________________________________
    Michal Zalewski [lcamtufat_private] [ENSI / marchew] [dione.ids.pl SYSADM]
    [http://linux.lepszy.od.kobiety.pl/~lcamtuf/] <=--=> bash$ :(){ :|:&};:
    [voice phone: +48 (0) 22 813 25 86] ? [pager (MetroBip): 0 642 222 813]
    Iterowac jest rzecza ludzka, wykonywac rekursywnie - boska [P. Deutsch]
    



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