Hi, I have discovered a bug in the rhost module of Linux-PAM-0.57. This bug leads to a vulnerability in the remote login authentication, with the effect that ordinary user accounts may not be password protected. There is only one case when the bug causes a vulnerability: The problem case is when the user''s .rhost file has the name of a machine with *more than one IP address* as the *final* entry. To be explicit, here are two example .rhost files: One of them leaves an account wide open, the other does not. CAUSES PROBLEMS DOES NOT CAUSE PROBLEMS ---------------- ----------------------- karman.tam.uiuc.edu vn.nas.nasa.gov vn.nas.nasa.gov karman.tam.uiuc.edu Note that vn.nas.nasa.gov has two IP addresses. Thus, as the final entry of a .rhost file, it leaves the user''s account wide open, i.e. any other user of the same name can log in to that account from any machine without a password. The problem is in the rhost module of PAM. The module calls gethostbyname() in two locations, once for the connecting machine, then once for each named entry in the .rhosts file. The call returns a structure with a pointer to a list of IP addresses stored as unsigned longs. Since there may be multiple IP addresses, the PAM code uses a while loop over the addresses of the connecting machine, then another while loop over the addresses of the machines named in .rhosts. These while loops are terminated by a null pointer in the address list. Apparently gethostbyname does not allocate new memory for the unsigned longs each time it is called. Thus the calls to gethostbyname() for the .rhosts entries clobber the subsequent IP addresses of the connecting machine. If the final .rhost entry is a name with multiple IP addresses, the the null terminator gets replaced with the second IP address of the final entry in the .rhost file. The second iteration of the while loop on the connecting machine now sets the IP number of the connecting machine to the IP number of the final entry in the .rhosts file. A match follows and the account is open. WHO IS AFFECTED? Unfortunately, the effects of this vulnerability reach beyond the Linux community. For example, users named langford have been able to walk into my Linux account for months. From that Linux account, user langford could freely rlogin to other departmental machines and NASA government machines. In particular, administrators of sites with multiple IP addresses might consider disabling rlogin access to their machines, with the understanding that not all Linux users will fix the rlogin problem immediately. HOW TO FIX IT? I removed the loop that goes over IP numbers of the connecting machine. IMO this is not particularly important. The only case is if I have .rhost entry by IP number, not name, of a machine I connect *from* with multiple IP addresses. If I refer to the connecting machine by *name* in the .rhost file, the remaining while loop takes care of everything for me. One of the IP addresses will still match. For me this fix is suitable, although I hope someone can fix the PAM module in a better way. Until the PAM module is updated, users should check that the last entry of their .rhost file only has one IP address. They can use the command nslookup, for example. Jacob Langford langford@uiuc.edu
Jacob A. Langford wrote:> I have discovered a bug in the rhost module of Linux-PAM-0.57. This > bug leads to a vulnerability in the remote login authentication, with > the effect that ordinary user accounts may not be password protected.The following patch is due to Savochkin Andrey Vladimirovich, it should fix 0.57''s pam_rhosts module. 0.58 and 0.59 source is still alpha-code but Andrey has posted a patch for these to the pam-list already. Thanks for finding this bug! Cheers Andrew RCS file: RCS/pam_rhosts_auth.c,v retrieving revision 1.11 diff -u -r1.11 pam_rhosts_auth.c --- pam_rhosts_auth.c 1997/04/05 06:26:39 1.11 +++ pam_rhosts_auth.c 1997/10/02 05:47:02 @@ -3,6 +3,7 @@ * Modifications, Cristian Gafton 97/2/8 * Modifications, Peter Allgeyer 97/3 * Modifications (netgroups and fixes), Nicolai Langfeldt 97/3/21 + * Security fix: 97/10/1 - gethostbyname called repeatedly without care *---------------------------------------------------------------------- * Copyright (c) 1983, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -524,25 +525,31 @@ { struct hostent *hp; int answer = 1; /* default to failure */ - u_long addr; - char **ap; + u_long *addrs; + int n, i; opts->last_error = (char *) 0; hp = gethostbyname(rhost); /* identify host */ if (hp != NULL) { - ap = hp->h_addr_list; - while (*ap) { /* loop though address list */ - memcpy (&addr, *ap, sizeof(addr)); - - /* check user on remote host */ - if (iruserok(pamh, opts, addr, superuser, ruser, luser, rhost) - == 0) { - answer = 0; /* success */ - break; - } - ++ap; - } + /* loop though address list */ + for (n = 0; hp->h_addr_list[n]; n++); + D(("rhosts: %d addresses", n)) + + if (n) { + addrs = malloc (n * sizeof(*addrs)); + for (i = 0; i < n; i++) + memcpy (addrs+i, hp->h_addr_list[i], sizeof(*addrs)); + + for (i = 0; i < n && answer; i++) { + D(("rhosts: address %d is %04x", i, addrs[i])) + answer = iruserok(pamh, opts, addrs[i], superuser, + ruser, luser, rhost); + /* answer == 0 means success */ + } + + free (addrs); + } } return answer; -- Linux-PAM, libpwdb, Orange-Linux and Linux-GSS http://parc.power.net/morgan/index.html