COMMAND
PAM
SYSTEMS AFFECTED
Linux PAM (up to 0.64-2)
PROBLEM
Michal Zalewski found following. 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. Vulnerable is 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. No info
about other PAM-compliant distributions. Quick vunerability test:
$ grep pam_unix_passwd /etc/pam.conf /etc/pam.d/passwd
Attacker may read and write permissions to /etc/shadow file or
gain superuser privledges (locally).
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? Let's see:
<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.
SOLUTION
Lame fix is to:
chmod -s /usr/bin/passwd
Better fix is to add umask(077) somewhere. Given that Solaris
doesn't have pam_unix_passwd (all of the unix schema is
implemented in a single pam_unix.so module) Solaris isn't
vulnerable to this particular module exploit.