getpwnam shows shadow passwords of NIS users

Bug #499425 reported by Christoph
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GLibC
Fix Released
Critical
eglibc (Ubuntu)
Fix Released
Medium
Unassigned
Dapper
Won't Fix
Medium
Unassigned
Hardy
Won't Fix
Medium
Unassigned
Intrepid
Invalid
Medium
Unassigned
Jaunty
Won't Fix
Medium
Unassigned
Karmic
Won't Fix
Medium
Unassigned
Lucid
Fix Released
Medium
Unassigned

Bug Description

Hello,

I have several machines where almost all user accounts come by NIS. The NIS
server is running on a Solaris machine. As usual, the Solaris NIS server
exports the passwd data in the map "passwd" and the shadow data in the map
"passwd.adjunct.byname". These two maps are mangled together in some calls
of libc6, for example in getpwnam. This makes it possible for every user who
has an account on the NIS client machine to see the encrypted passwords of
all NIS users. This is a grave security bug.

Furthermore, getspnam returns a NULL pointer for all NIS users, even if
getspnam is called by root.

The attached patch seems to solve the problems.

It makes the following changes:

* In nis-pwd.c, do not mangle encrypted password from
   passwd.adjunct.byname map into the password field
   of passwd map, instead mangle an 'x' into the field

* In nis-spwd.c, look for key in passwd.adjunct.byname if shadow.byname
   does not exist and add the two missing fields (passwd.adjunct.byname
   has two fields less than shadow)

Maybe some people can have a look over my patch to see if I missed anything.

Regards
  Christoph

ProblemType: Bug
Architecture: amd64
Date: Tue Dec 22 13:02:29 2009
Dependencies:
 libgcc1 1:4.2.4-1ubuntu3
 gcc-4.2-base 4.2.4-1ubuntu3
 libc6 2.7-10ubuntu5
DistroRelease: Ubuntu 8.04
Package: libc6 2.7-10ubuntu5
PackageArchitecture: amd64
ProcEnviron:
 SHELL=/bin/tcsh
 PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
 LANG=en_US.UTF-8
SourcePackage: glibc
Uname: Linux 2.6.24-24-generic x86_64

CVE References

Revision history for this message
Christoph (christoph-pleger-cs) wrote :
Revision history for this message
Kees Cook (kees) wrote :

Hello! Thanks for the report and the patch. One thing I'm curious about; isn't it possible for a local user to just use "ypcat passwd.adjunct.byname" to see the encrypted passwords? Regardless, I would be curious to see if upstream glibc would be willing to use your patch. Have you opened a bug with glibc? http://sourceware.org/bugzilla/

Also, IIUC, this is not a "private" security issue, in that NIS leaking encrypted passwords is a fairly well understood limitation. Should this bug be made public to get more people looking at it?

Revision history for this message
Christoph (christoph-pleger-cs) wrote : Re: [Bug 499425] Re: getpwnam shows shadow passwords of NIS users

Hello,

On Tue, 22 Dec 2009 23:00:55 -0000
Kees Cook <email address hidden> wrote:

> Hello! Thanks for the report and the patch. One thing I'm curious
> about; isn't it possible for a local user to just use "ypcat
> passwd.adjunct.byname" to see the encrypted passwords?

No, only the root user can look at passwd.adjunct.byname. When a normal
user calls "ypcat passwd.adjunct.byname", the following error message
is shown:

No such map passwd.adjunct.byname. Reason: No such map in server's
domain

> Regardless, I
> would be curious to see if upstream glibc would be willing to use your
> patch. Have you opened a bug with glibc?
> http://sourceware.org/bugzilla/

No, not yet, I thought that Debian or Ubuntu would send the patch
upstream. Do you think that I should do that?

>
> Also, IIUC, this is not a "private" security issue, in that NIS
> leaking encrypted passwords is a fairly well understood limitation.
> Should this bug be made public to get more people looking at it?

I also reported the bug to Debian, so the security violation is
already public. So, it's no problem to make it public in Ubuntu, too.

Regards
  Christoph

visibility: private → public
Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :
Download full text (7.1 KiB)

Hello,
I have several machines where almost all user accounts come by NIS. The NIS
server is running on a Solaris machine. As usual, the Solaris NIS server
exports the passwd data in the map "passwd" and the shadow data in the map
"passwd.adjunct.byname". These two maps are mangled together in some calls
of libc6, for example in getpwnam. This makes it possible for every user who
has an account on the NIS client machine to see the encrypted passwords of
all NIS users. This is a grave security bug.

Furthermore, getspnam returns a NULL pointer for all NIS users, even if
getspnam is called by root.

I wrote a patch nis_shadow.diff that solves these problems. It makes the
following changes:

* In nis-pwd.c, do not mangle encrypted password from
  passwd.adjunct.byname map into the password field
  of passwd map, instead mangle an 'x' into the field

* In nis-spwd.c, look for key in passwd.adjunct.byname if shadow.byname
  does not exist and add the two missing fields (passwd.adjunct.byname
  has two fields less than shadow)

diff -Naurp glibc-2.7.original/nis/nss_nis/nis-pwd.c
glibc-2.7/nis/nss_nis/nis-pwd.c
--- glibc-2.7.original/nis/nss_nis/nis-pwd.c 2006-05-02 00:31:15.000000000
+0200
+++ glibc-2.7/nis/nss_nis/nis-pwd.c 2009-12-22 09:04:46.000000000 +0100
@@ -275,8 +275,8 @@ internal_nis_getpwent_r (struct passwd *
        yp_match (domain, "passwd.adjunct.byname", result, namelen,
    &result2, &len2)) == YPERR_SUCCESS)
  {
- /* We found a passwd.adjunct entry. Merge encrypted
- password therein into original result. */
+ /* We found a passwd.adjunct entry. Merge "x"
+ into original result. */
    char *encrypted = strchr (result2, ':');
    char *endp;
    size_t restlen;
@@ -304,7 +304,7 @@ internal_nis_getpwent_r (struct passwd *

    mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen),
          ":", 1),
- encrypted, endp - encrypted),
+ "x", 1),
      p, restlen + 1);
    p = buffer;

@@ -408,8 +408,8 @@ _nss_nis_getpwnam_r (const char *name, s
       && yp_match (domain, "passwd.adjunct.byname", name, namelen,
      &result2, &len2) == YPERR_SUCCESS)
     {
- /* We found a passwd.adjunct entry. Merge encrypted password
- therein into original result. */
+ /* We found a passwd.adjunct entry. Merge "x"
+ into original result. */
       char *encrypted = strchr (result2, ':');
       char *endp;

@@ -436,7 +436,7 @@ _nss_nis_getpwnam_r (const char *name, s

       __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
            ":", 1),
- encrypted, endp - encrypted),
+ "x", 1),
    p, restlen + 1);
       p = buffer;

@@ -509,8 +509,8 @@ _nss_nis_getpwuid_r (uid_t uid, struct p
    yp_match (domain, "passwd.adjunct.byname", result, namelen,
       &result2, &len2)) == YPERR_SUCCESS)
     {
- /* We found a passwd.adjunct entry. Merge encrypted password
- therein into original result. */
+ /* We found a passwd.adjunct entry. Merge "x"
+ into original result. */
       char *encrypted = strchr (result2, ':');
       char *endp;
       size_t restlen;
@@ -538,7 +538,7 @@ _nss_nis_getpwuid_r (uid_t uid, struct p

       __mempcpy (__me...

Read more...

Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :

Created attachment 4491
Patch for NIS shadow problems

Here is my patch in form of an attachment.

Revision history for this message
Kees Cook (kees) wrote :

Yes, please open an upstream report. If the patch is taken upstream, all distros will benefit from it. :)

Changed in glibc (Ubuntu):
importance: Undecided → Wishlist
status: New → Confirmed
Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :

Created attachment 4498
New patch

I was told that there are missing parantheses in free result. Obviously, I
sent an obsolete version of the patch. Here is the version that I used to
compile glibc successfully.

Revision history for this message
Christoph (christoph-pleger-cs) wrote :

Hello,

On Tue, 05 Jan 2010 21:03:47 -0000
Kees Cook <email address hidden> wrote:

> Yes, please open an upstream report.

I did that yesterday.

> ** Changed in: glibc (Ubuntu)
> Importance: Undecided => Wishlist

Why that? Do you really think that a bug that enables all users on a
machine to see the encrypted passwords of other users is not a
security violation and that a solution is only on the wishlist?

I was informed that in my patch, there are missing parantheses near
free result. Obviously, I sent an obsolete version of the patch. Now, I
have attached the version that I really used to successfully compile
the package.

Regards
  Christoph

Revision history for this message
Kees Cook (kees) wrote :

Great, thanks for forwarding it. Can you link to the upstream bug so this bug will track it?

As to the "Wishlist", glibc nis support has always been broken, and having access to encrypted passwords has been a known problem for a long time. It seems that the passwd.adjunct.byname way of doing things is new, and as such, a feature request, really. (i.e. no new hole, regression, etc.) This shouldn't be seen as lack of interest or anything -- this is a great way for NIS to be more secure finally. :)

Revision history for this message
Christoph (christoph-pleger-cs) wrote :

Hello,

> Great, thanks for forwarding it. Can you link to the upstream bug so
> this bug will track it?

The link is:

http://sourceware.org/bugzilla/show_bug.cgi?id=11134

> As to the "Wishlist", glibc nis support has always been broken, and
> having access to encrypted passwords has been a known problem for a
> long time. It seems that the passwd.adjunct.byname way of doing
> things is new, and as such, a feature request, really. (i.e. no new
> hole, regression, etc.) This shouldn't be seen as lack of interest or
> anything -- this is a great way for NIS to be more secure finally. :)

As far as I know, this is not true. In glibc, the NIS shadow password
feature was introduced in libc6, the corresponding NIS map was called
shadow.byname. Sun Microsystems, the inventor of NIS, does not use a map
shadow.byname, they are using passwd.adjunct.byname since many years.
So, it seems that some glibc developers failed to take over an existing
standard.

Regards
  Christoph

Kees Cook (kees)
affects: glibc (Ubuntu) → eglibc (Ubuntu)
Changed in glibc:
status: Unknown → Confirmed
Revision history for this message
Christoph (christoph-pleger-cs) wrote :

Hello,

what will be Ubuntu's further actions to solve this bug in the libc
packages? Debian already has built new packages even for its stable
distribution and is about to release them, together with a Debian
security announcement, very soon.

Regards
  Christoph

Revision history for this message
Kees Cook (kees) wrote :

Actually, this should be Fix Released now, as it's in upstream glibc 2.11.1. It is not likely to ever go into Karmic, though you can pursue a Stable Release Update if you want:
https://wiki.ubuntu.com/StableReleaseUpdates

Changed in eglibc (Ubuntu):
status: Confirmed → Fix Released
Revision history for this message
Kees Cook (kees) wrote :

Actually, let me rephrase that. It sounds like this is an actual leak that has now been fixed, rather than just being a long-standing glitch in how NIS is designed. Since this is CVE-2010-0015 we'll roll out fixes for all the Ubuntu stable releases shortly.

Changed in eglibc (Ubuntu Karmic):
status: New → In Progress
importance: Undecided → Medium
Changed in eglibc (Ubuntu Dapper):
status: New → In Progress
Changed in eglibc (Ubuntu Hardy):
status: New → In Progress
Changed in eglibc (Ubuntu Jaunty):
importance: Undecided → Medium
Changed in eglibc (Ubuntu Intrepid):
status: New → In Progress
importance: Undecided → Medium
Changed in eglibc (Ubuntu Hardy):
importance: Undecided → Medium
Changed in eglibc (Ubuntu Dapper):
importance: Undecided → Medium
Changed in eglibc (Ubuntu Lucid):
importance: Wishlist → Medium
Changed in eglibc (Ubuntu Jaunty):
status: New → In Progress
Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :

Hello,

I am sorry that my patch for the NIS shadow password security
vulnerability introduced a new bug. One of my NIS users informed me
that she could not login any more after she had used chsh to change her
login shell. The reason was that in the shadow file, the encrypted
password had been replaced by an 'x'. This happens because in my
patch, file nis-pwd.c, the string "##<username>" is replaced with "x".

I thought that this replacement is necessary to let libc6 search for
the encrypted password in the shadow map. But now I found out that it
is not necessary and that without it everything works fine: logging in,
changing password and changing the shell.

I have attached a new patch that simply lets the password field of the
passwd.byname map alone.

Regards
  Christoph

Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :

Created attachment 4605
Another try

Revision history for this message
In , Drepper-fsp (drepper-fsp) wrote :

I'm not so sure about either change.

The server can regulate which process can read the passwd.adjunct database using
the source port number. A value < 1024 would indicate privileges. If an
attacker can illegally bind a socket to a low port security is already
compromised. The code in libc will ignore the error from being denied access
and will use the original entry from /etc/passwd as-is.

That's how it is meant to be used. In this model processes with privileges can
get to the information. Especially because I don't think imitating the shadow
file using the passwd.adjunct content is going to work.

You say there are two fields missing in passwd.adjunct. In theory perhaps true
but I have not found anywhere any indication that usually the file contains any
information except the first two fields. That's not really the correct content
for the file. It means no password aging etc happens.

Changing the implementation along your patch sounds arbitrary. The current
behavior re filling in the password might be used by some people. There is no
way in Sun's implementation to enable behavior like this? There is no setting
in Sun's ypserv to restrict access based on ports? I cannot change it without a
good reason.

The bigger problem is the synthetic shadow file. I don't like this at all. If
you want a shadow file, why don't you export one from the server? I realize
that if you say you don't want a shadow file and restricted access to passwd and
the server doesn't have port-based access control that you then want these
changes. But these are lots of ifs.

The current libc implementation works perfectly if you use the model I
described. You get a full passwd file for privileged users and a version
without the password for non-privileged users. This is a sensible model and
your patch would cause it to stop working.

Changed in glibc:
status: Confirmed → Incomplete
Revision history for this message
In , Christoph (christoph-pleger-cs) wrote :

Subject: Re: getpwnam shows shadow passwords of NIS users

Hello,

> The server can regulate which process can read the passwd.adjunct
> database using the source port number. A value < 1024 would indicate
> privileges. If an attacker can illegally bind a socket to a low port
> security is already compromised.

Normal permissions should prevent an attacker from illegally binding a
socket to a port < 1024. Of course there can be a security hole that
gives root privileges. But a security hole of that kind gives access to
everything, in spite of that no sensible administrator gives
permissions 777 to all files. So, we must find a solution for the
normal case which says that no ordinary user can use a port < 1024,
not a solution for a case where another security hole is already
present.

Of course a user can connect his own notebook to the network, be root
on it, which allows to use a port < 1024, and read the encrypted
passwords. But that problem can be solved by other means, for example
by IPSec authentication.

> That's how it is meant to be used. In this model processes with
> privileges can get to the information. Especially because I don't
> think imitating the shadow file using the passwd.adjunct content is
> going to work.

Where do you see a problem? I've been using this for some time now and
the only problem I found was the overwriting of the password field,
which I solved by the modified patch.

> You say there are two fields missing in passwd.adjunct. In theory
> perhaps true but I have not found anywhere any indication that
> usually the file contains any information except the first two
> fields.

Right, that is why I put empty strings into these fields. These
field are defined in libc6, what will getspnam do if they are not
present?

> There is no way in Sun's implementation to enable behavior
> like this? There is no setting in Sun's ypserv to restrict access
> based on ports? I cannot change it without a good reason.

The access IS restricted on ports. But that does not help when,
on the Linux client side, nscd is in use.

> The current libc implementation works perfectly if you use the model I
> described. You get a full passwd file for privileged users and a
> version without the password for non-privileged users.

Unfortunately, that is not true. The current implementation allows
EVERY user to use the getpwnam library call to see the encrypted
password of any NIS user.

> This is a
> sensible model and your patch would cause it to stop working.

No, my patch MAKES it working.

Regards
  Christoph

Revision history for this message
In , Drepper-fsp (drepper-fsp) wrote :

I decided to implement this but only as a non-default mode. It can be selected
by a new variable in /etc/default/nss. This is as far as I'm willing to go. As
I explained, the current code has its own justification and is not broken.

Your last patch still contained a bunch of mistakes. The change I checked in
really has not much to do with it.

Changed in glibc:
status: Incomplete → Fix Released
Revision history for this message
Alex Valavanis (valavanisalex) wrote :

Intrepid Ibex reached end-of-life on 30 April 2010 so I am closing the report. The bug has been fixed in newer releases of Ubuntu.

Changed in eglibc (Ubuntu Intrepid):
status: In Progress → Invalid
Revision history for this message
Christoph (christoph-pleger-cs) wrote :

Will there ever be fixes for hardy and jaunty?

Revision history for this message
Kees Cook (kees) wrote :

Upstream rejected these patches, so it puts us in a rather tricky position.

Revision history for this message
Christoph (christoph-pleger-cs) wrote :

Hello,

On Fri, 06 Aug 2010 16:27:16 -0000
Kees Cook <email address hidden> wrote:

> Upstream rejected these patches, so it puts us in a rather tricky
> position.

As far as I remember, Ulrich Drepper wrote that they do not completely
reject the patches, but that they are going to use a variable in some
configuration file, so that for staying compatible with existing
software, the new code is only applied in certain cases.

Regards
  Christoph

Revision history for this message
Alex Valavanis (valavanisalex) wrote :

Jaunty reached end-of-life on 23 October 2010, so this bug will not be fixed in that version of Ubuntu. It has been fixed in newer versions.

Changed in eglibc (Ubuntu Jaunty):
status: In Progress → Won't Fix
Changed in eglibc (Ubuntu Karmic):
status: In Progress → Won't Fix
Changed in eglibc (Ubuntu Dapper):
status: In Progress → Triaged
Changed in eglibc (Ubuntu Hardy):
status: In Progress → Triaged
Changed in glibc:
importance: Unknown → Critical
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thank you for reporting this bug to Ubuntu. dapper has reached EOL
(End of Life) and is no longer supported. As a result, this bug
against dapper is being marked "Won't Fix". Please see
https://wiki.ubuntu.com/Releases for currently supported Ubuntu
releases.

Please feel free to report any other bugs you may find.

tags: added: hardy
Changed in eglibc (Ubuntu Dapper):
status: Triaged → Won't Fix
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Thank you for reporting this bug to Ubuntu. hardy has reached EOL
(End of Life) and is no longer supported. As a result, this bug
against hardy is being marked "Won't Fix". Please see
https://wiki.ubuntu.com/Releases for currently supported Ubuntu
releases.

Please feel free to report any other bugs you may find.

Changed in eglibc (Ubuntu Hardy):
status: Triaged → Won't Fix
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.