Date: Wed, 23 Dec 1998 13:12:45 +0100
From: Michal Zalewski <lcamtuf@IDS.PL>
Reply-To: Bugtraq List <BUGTRAQ@netspace.org>
To: BUGTRAQ@netspace.org
Subject: Linux PAM (up to 0.64-2) local root compromise

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 [lcamtuf@ids.pl] [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]
