Bug 168181 - CVE-2005-2977 unix_chkpwd helper doesn't verify requesting user if SELinux is enabled
Summary: CVE-2005-2977 unix_chkpwd helper doesn't verify requesting user if SELinux is...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: pam
Version: 4.0
Hardware: All
OS: Linux
medium
low
Target Milestone: ---
: ---
Assignee: Tomas Mraz
QA Contact: Jay Turner
URL:
Whiteboard: impact=low,source=redhat,embargo=2005...
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2005-09-13 09:55 UTC by Tomas Mraz
Modified: 2015-01-08 00:10 UTC (History)
4 users (show)

Fixed In Version: RHSA-2005-805
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2005-10-26 15:56:27 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Add delay to unix_chkpwd on failure. (996 bytes, patch)
2005-09-14 16:30 UTC, Daniel Walsh
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2005:805 0 normal SHIPPED_LIVE Low: pam security update 2005-10-26 04:00:00 UTC

Description Tomas Mraz 2005-09-13 09:55:48 UTC
+++ This bug was initially created as a clone of Bug #168180 for RHEL4 +++

Description of problem:


Version-Release number of selected component (if applicable):
all pam with the SELinux patch included (FC3,4 RHEL4)

How reproducible:

Try:
$ echo -n <root password> | /sbin/unix_chkpwd root nonull && echo OK

OK should not be printed.


So the problem is in this part of SELinux patch:
        /*
-        * determine the current user's name is
+        * determine the current user's name is.
+        * On a SELinux enabled system, policy will prevent third
parties from using
+        * unix_chkpwd as a password guesser.  Leaving the existing
check prevents
+        * su from working,  Since the current uid is the users and the
password is
+        * for root.
         */
-       user = getuidname(getuid());
-       if (argc == 2) {
-           /* if the caller specifies the username, verify that user
-              matches it */
-           if (strcmp(user, argv[1])) {
-               force_failure = 1;
-           }
+       if (SELINUX_ENABLED) {
+         user=argv[1];
+       }
+       else {
+         user = getuidname(getuid());
+         /* if the caller specifies the username, verify that user
+            matches it */
+         if (strcmp(user, argv[1])) {
+           return PAM_AUTH_ERR;
+         }
+       }

Obviously when you set SELinux to permissive mode it's possible to run
unix_chkpwd without problem. But even when I set it to enforcing I was
able to run it. (Probably it's disabled only by strict policy?)

So unix_chkpwd allows brute-forcing of any passwords in /etc/shadow.
Also note that there is no delay if the password is incorrect - it exits
immediately, and there is no logging of failed attempts.

Comment 1 Daniel Walsh 2005-09-14 16:30:22 UTC
Created attachment 118806 [details]
Add delay to unix_chkpwd on failure.

Here is a patch that adds a 2 second delay after failure if SELinux is called. 
Similar to what would happen if you called su.	Only problem with this patch is
it will double timeout of other apps using pam's delay function.  Also this
does not prevent user from doing a verify

unix_chkpwd root verify < /dev/null
12959:0:99999:7:-1:-1

Which I am not sure is a security problem.

Comment 2 Tomas Mraz 2005-09-15 12:58:28 UTC
I'd prefer to remove the if(SELINUX_ENABLED) part of the original patch for
RHEL4 as we don't ship strict policy for RHEL4. Then we can think about and test
a better patch for a next update release.


Comment 4 Daniel Walsh 2005-09-15 14:01:42 UTC
A simple fix for this would be

  if (SELINUX_ENABLED  && getuid() == 0) {
+         user=argv[1];
+       }
+       else {
+         user = getuidname(getuid());
+         /* if the caller specifies the username, verify that user
+            matches it */
+         if (strcmp(user, argv[1])) {
+           return PAM_AUTH_ERR;
+         }
+       }

This app will only be run as root when SELinux is blocking access to the
/etc/shadow.  I believe this fixes the problem with out changing the behavior at
all.


Comment 5 Tomas Mraz 2005-09-15 14:39:01 UTC
This is what I propose too but it would work only if the setuid(0) call was
added after the fork before exec-ing unix_chkpwd in pam_unix module.

Otherwise su, sudo, userhelper won't work (they call setuid later in the process).


Comment 6 Tomas Mraz 2005-10-07 15:32:10 UTC
Please see also bug 168180 for discussion.


Comment 11 Josh Bressers 2005-10-26 15:45:59 UTC
Lifting embargo, this issue is now public.

Comment 12 Red Hat Bugzilla 2005-10-26 15:56:28 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2005-805.html


Comment 13 Jay Levitt 2005-11-16 17:47:42 UTC
Installing the official RHEL4 pam-0.77-66.13 from this errata breaks
subversion-via-httpd's ability to use pam_unix for authentication.  

Specifically:

I'm running RHEL AS4 for 32-bit x86. When I install the updated pam rpm, I'm no
longer able to use pam_unix to authenticate mod_dav_svn.  I get the following
error in /var/log/messages when attempting to login with a subversion client:

Nov 15 19:56:25 dev httpd(pam_unix)[31001]: authentication failure; logname=
uid=48 euid=48 tty= ruser= rhost=  user=jay

(UID 48 is the apache login.)  Rolling back to pam-0.77-66.11 solves the
problem.  I have no problem using pam_unix to authenticate regular web
directories, only subversion repositories, which seems like a good clue.

I don't know enough to know if this is a bug in the errata, or a bug in the way
mod_dav_svn works.  Maybe it doesn't ask for the right privileges, but the
former pam bug was letting it get away with that?  If so, I will report to the
subversion team.

I'm running Apache httpd 2.0.54, installed from source, with subversion 1.2.3,
likewise.  Snippets of my httpd.conf:

..the regular web site, which works fine...

<Directory "/srv/www/htdocs/my.site.example.com">
       Options +Indexes
       IndexIgnore ..

       SSLRequireSSL
       AuthPAM_Enabled On
       AuthType Basic
       AuthName "Development Intranet"
       Require valid-user
</Directory>

..the subversion repository, which fails as soon as the errata RPM is installed...

<VirtualHost *:443>
       ServerName svn.example.com
       CustomLog logs/svn.access.log combined
       SSLEngine On

       # This must be accessible, but is otherwise unused
       DocumentRoot "/srv/www/htdocs/svn-phony"

       <Location /dev/>
               AuthPAM_Enabled on
               AuthType Basic
               AuthName "Developer repository"
               Require group dev
       </Location>

       <Location />
               DAV svn
               SVNParentPath "/srv/svn/"
               SVNPathAuthz off
       </Location>

</VirtualHost>

.. my /etc/pam.d/httpd config ...

#%PAM-1.0
auth       required     /lib/security/pam_unix.so
account    required     /lib/security/pam_unix.so



Comment 14 Tomas Mraz 2005-11-16 21:02:20 UTC
This was never intended to work - for example if you've had turned SELinux off
with the previous pam release it wouldn't work either.

It is not too good idea to authenticate httpd against unix accounts and
passwords anyway. Couldn't the subversion via httpd be authenticating against
its own password database? Of course if you don't care about security too much
you can make /etc/shadow readable for the apache group or not to use shadow
passwords at all although I wouldn't recommend doing anything like that.



Note You need to log in before you can comment on or make changes to this bug.