The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: Zardoz 'Security Digest' - Archives (1989 - 1991)
DOCUMENT: Zardoz 'Security Digest' V3 #12 1991-09-13 (1 file, 6309 bytes)
NOTICE: recognises the rights of all third-party works.


Date: Fri Sep 13 13:55:16 PDT 1991
Subject: Security Digest V3 #12

Security Digest Volume 3 Issue 12


            Announcing Crack v3.2a - A Sensible Password Checker for UNIX
            hp write()
            YP is not secure
            ypserv problem (NEW BUGID: 1036869)
            Re: ypserv as network-wide /etc/password server? (with source fix)

The unix security mailing list is by invitation only and often
contains sensitive material which IS NOT INTENDED FOR PUBLIC

PLEASE SEND NEW SECURITY HOLES TO:              [email protected]
PLEASE POST NORMAL MESSAGES TO:              [email protected]
PLEASE SEND REQUESTS TO:             [email protected]

Postings that describe security holes/fixes have a * in their subject.


Date: Fri, 23 Aug 91 17:13:38 +0100
From: Alec David Muffett <[email protected]>
Subject: Announcing Crack v3.2a - A Sensible Password Checker for UNIX

This is official announcement of a new version of the "Crack" Unix
password testing suite, recently posted to the newsgroups alt.sources,, and comp.sources.misc.

Crack is designed to give very much greater throughput in testing
password security than that standard COPS password cracker, but it is
not a complete security testing system, and should thus be run in
parallel with programs like COPS.

Version 3.2a, just released, also contains and utilises a fast
implementation of the Unix crypt() function, suitable for use on Suns,
DECs, and several other Unix platforms, and although it is not totally
portable, it does much to enhance the speed with which passwords can be
checked.  It is hoped that fcrypt() will be supported on more platforms
in the near future.

Crack is supplied with (reasonably) full documentation and source code.

Crack v3.2a is available for anonymous ftp:-

        Site:  []
        Directory:      ~/packages


Subject: hp write()

[ hp/ux still has not changed their write() function as has been done
on Sun, Solbourne, MIPS, NeXT, IBM 6000 and others (those are the only
machines in my office right now 8-).  And to make things much worse,
they are now (with hp/ux 7.0) shipping a set-uid root group writable
file as follows (according to William Walker):

} under hp/ux 7.0 (on the 800's at least, my 400's are still crated)
} the distribution tapes create /etc/proxy as...
} $ ls -l /etc/proxy
} -rwsrwxr-x   1 root     other      47104 Jan 24 14:06 /etc/proxy

All of my systems that have the modified write() include the following
paragraph as part of their man page on write(), and "pass" the test
following that:

     If the real user is not the super-user, then write()  clears
     the set-user-id bit on a file.  This prevents penetration of
     system security by a user who  "captures"  a  writable  set-
     user-id file owned by the super-user.

% groups
neil ...
% su
wizard# cd /etc
wizard# cp hosts test
wizard# chmod 4775 test
wizard# chgrp neil test
wizard# ls -lg test
-rwsrwxr-x  1 root     neil          165 Feb  7 23:33 test*
wizard# exit
% cd /etc
% cat hosts >>test
% ls -lg test
-rwxrwxr-x  1 root     neil          330 Feb  7 23:34 test*

Whereas, on the hp it is reported that it behaves as follows:

$ whoami
$ groups
adm ...
$ su
# cp hosts test
# chmod 4775 test
# chgrp adm test
# ls -l test
-rwsrwxr-x   1 root     adm         9300 Feb  8 09:37 test
# exit
$ cat hosts >> test
$ ls -l test
-rwsrwxr-x   1 root     adm        18600 Feb  8 09:38 test


From: Mark Moraes <uunet!!moraes>
Subject: YP is not secure

For YP in this article, subsititute "what Sun used to call Yellow
 Pages and now calls NIS":-)

In past digests, people have commented that ypserv will helpfully hand
out password files to anyone who asks.  True.  What people don't seem
to have mentioned is a far nastier pair of bugs/features/oversights in
ypbind that leave a system running YP wide open, viz:

- ypbind will happily accept ypset requests from the network to change
the ypserv for a domain.  (This is of course documented as a
recommended way to tell ypbind about ypservs on other networks, since
ypbind uses broadcasts to find out it's ypserv) So anyone can tell your
ypbind to use them as a ypserv, give it a fake passwd file, and login
as root, *IF* they know, or can guess your domainname.  (This is true
for at least the ypbind that comes with SunOS3.x; I see no evidence
that this has changed in the manual page for SunOS4.0 -- we have no
SunOS4.0 systems running YP that I could test this on, and no SunOS4.0
src) And of course, anyone who has an account on your machine can
trivially find out your domainname.  The problem could probably be
fixed by changing ypbind so it accepts a list of trusted hosts for
ypset requests, or better yet, accepts a list on startup from some
trustworthy file.  Which leads to the second problem.

- anyone on your machine can start up their own ypbind -- the old
ypbind will gracefully(!) yield to it.  If you have Sun src on your
system, or have someone capable of writing a ypbind substitute that
behaves differently, then there doesn't seem to be much one can do to
stop them replacing your ypbind; it would appear to be a feature of
Sun RPC.

I suspect it is possible to have a machine on your ethernet that
listens for YP broadcast requests and replies quickly, beating out the
real ypserv.  But that's a different kettle of fish -- you pretty much
have to trust everyone on your ethernet anyway.

Alas, an ever-increasing number of vendors seem to be shipping YP with
their systems, presenting the illusion that YP makes it simpler to
administer a network (hah -- our sysadmin tasks became MUCH simpler,
performance improved, and things became more reliable and predictable
in the presence of server crashes when we removed YP! And we got to
run the nameserver without too many contortions.  And the less said
about ypbind under load, the better...).

A sysadmin on one of the only systems to run YP on our campus, when
warned of these problems, commented

> This is a well known problem. I've already acquired two patches from
> SUN that is supposed to fix this. Neither worked.

I have not seen these problems mentioned before on this list, or any
other.  (I do remember seeing mention of a modified ypbind on
sun-spots/sun-nets/sun-managers once, but my habit of ignoring all YP
related articles there probably means I missed it) My apologies if
this is duplicate material.


From: uunet!iis!prl
Subject: ypserv problem (NEW BUGID: 1036869)

Sun has reconsidered their position and the bug has been reopened. It has
a new bug ID: 1036869. My thanks to the people at Sun Switzerland
for their efforts to get this accepted as a `real problem'.

Swiss readers should contact Sun Switzerland, who will be able
to provide them with the fix from Richard Watterson at Purdue given to
me by Dan Trickle (source patch in my last message to this list).
Currently Sun CH has sun4 and sun3 fixes for 4.0.3 (should also work for 4.0).

I hope that this fix or one similar will become available from Sun
to others on the list soon.

Users of YP from other vendors should maybe encourage them to make
this fix available, too.


From: uunet!iis!prl
Subject: Re: ypserv as network-wide /etc/password server? (with source fix)

Thanks to Dan Trickle at Purdue, I now have a source patch
to ypserv to fix the YP problem I described in Volume 2 Issue 11.

For those of you who don't have source, I know this is cold comfort,
so to start off, here are a summary of the partial workarounds
I know to this problem:

1)  make your YP domainname long and unrelated to your hostname.
    Something like olddomainname:ghfBHUIOheude1hbqwj76494 would
    maybe more useful than completely random. Maximum allowed length
    is 64 bytes. This is truely security through obscurity...

2)  If you access the wider Internet through a flexible router
    (Cisco or similar) switch off access to port 111, tcp and udp.
    This significantly increses the programming effort needed to
    exploit the problem. Unfortunately, ypserv is not always at the
    same port on all machines, so it's difficult to switch off
    access to ypserv reliably. This will prevent all normal SunRPC calls
    going through the bridge. This may not be what you want.

3)  The official word from Sun in response to the bug report:
        ``For now we recommend taking 2 steps:  1) do not run the YP server
        on your Internet gateway and 2) do not do IP routing from your
        Internet gateway to the rest of your machines.  This is the
        solution employed at Sun.''

Of these workarounds, 3) is the only completely reliable one,
assuming the attack comes from outside, but may
not meet most people's idea of user-friendliness.

2) and 3) will not protect you from someone who has broken in on a machine
`inside' the barrier but not in your domain, and decides to collect
password files while there.

1) combined with 2) or 3) may be better.

I have reported this bug to sun, and received the following response:

  --- start: extract from bug report -----
 Bug Id: :     1035964
 Product:  sunos
 Category:  network
 Subcategory:  yp
 Release summary: 4.0.3export
 Bug/Rfe:  bug
 State:  closed
 Synopsis:  ypserv will send maps to anyone who can guess the domainame
 Keywords:  password, security, ypserv, maps, domainame
        We are addressing this in our future plans for naming services,
        we do not expect to make this change to any version of 4.X.
        Since it is not expected that this bug will be fixed in YP's lifetime,
        I am closing it out.
        Closed because:  will not fix
  --- end: extract from bug report -----

I am not completely satisfied with this response and am
trying to reopen the bug report with Dan Trickle's fix.

The source patch follows.

  ----- Forwarded from Dan Trickle ----
     I just saw your message in the zardoz list about ypserv.  Here is
a quick fix we just implemented.  It uses a /var/yp/sercurenets file
and, if present, only responds to IP addresses in the range given.
The format of the file is one of more lines of

netmask netaddr

     Both netmask and netaddr must be dotted quads.  Ours looks like

     You could even go so far as to list individual hosts with a
netmask of, but that is probably overkill.  It logs
denied access as well, which might be helpful these days.  Of course,
if they are already on one of our local machines, it does not help.

============================== ypserv.patch ==============================
RCS file: RCS/ypserv.c,v
retrieving revision 1.1
diff -c -r1.1 ypserv.c
*** /tmp/,RCSt1017343   Wed Apr  4 09:03:54 1990
--- ypserv.c    Tue Apr  3 13:46:50 1990
*** 121,127
        pmap_unset(YPPROG, YPVERS);
        pmap_unset(YPPROG, YPOLDVERS);
        ypget_command_line_args(argc, argv);
        if (silent) {

                pid = fork();

--- 121,127 -----
        pmap_unset(YPPROG, YPVERS);
        pmap_unset(YPPROG, YPOLDVERS);
        ypget_command_line_args(argc, argv);
!       get_secure_nets();
        if (silent) {

                pid = fork();
RCS file: RCS/ypserv_map.c,v
retrieving revision 1.1
diff -c -r1.1 ypserv_map.c
*** /tmp/,RCSt1017368   Wed Apr  4 09:03:59 1990
--- ypserv_map.c        Tue Apr  3 14:51:31 1990
*** 232,237
                return (TRUE);
        caller = svc_getcaller(transp);
        if ((caller->sin_family == AF_INET) &&
            (ntohs(caller->sin_port)) < IPPORT_RESERVED) {
                return (TRUE);

--- 232,239 -----
                return (TRUE);
        caller = svc_getcaller(transp);
+       if (!(check_secure_net(caller)))
+           return(FALSE);
        if ((caller->sin_family == AF_INET) &&
            (ntohs(caller->sin_port)) < IPPORT_RESERVED) {
                return (TRUE);
*** /tmp/,RCSt1017375   Thu Apr 12 10:10:04 1990
--- ypserv_net_secure.c Thu Apr  5 16:18:59 1990
*** 0 ****
--- 1,99 ----
+ /*
+  * Author:
+  *    Richard Watterson
+  *    Purdue University
+  *    Department of Computer Sciences
+  *    April 3, 1990
+  */
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <stdio.h>
+ #include <syslog.h>
+ #define ACCFILE "/var/yp/securenets"
+ #define MAXLINE 128
+ struct seclist {
+     u_long mask;
+     u_long net;
+     struct seclist *next;
+ };
+ static struct seclist *slist ;
+ static int nofile = 0;
+ get_secure_nets()
+ {
+     FILE *fp;
+     char strung[MAXLINE],nmask[MAXLINE],net[MAXLINE];
+     unsigned long maskin, netin;
+     struct seclist *tmp1,*tmp2;
+     int line = 0;
+     if (fp = fopen(ACCFILE,"r")) {
+       tmp1 = (struct seclist *) malloc(sizeof (struct seclist));
+       slist = tmp1;
+       while (fgets(strung,MAXLINE,fp)) {
+           line++;
+           if (strung[strlen(strung) - 1] != '\n'){
+               syslog(LOG_ERR|LOG_DAEMON,
+                      "ypserv: %s line %d: too long\n",ACCFILE,line);
+               exit(1);
+           }
+           if (strung[0] == '#')
+               continue;
+           if (sscanf(strung,"%16s%16s",nmask,net) < 2) {
+               syslog(LOG_ERR|LOG_DAEMON,
+                      "ypserv: %s line %d: missing fields\n",ACCFILE,line);
+               exit(1);
+           }
+           maskin = inet_addr(nmask);
+           if (maskin == -1) {
+               syslog(LOG_ERR|LOG_DAEMON,
+                      "ypserv: %s line %d: error in netmask\n",ACCFILE,line);
+               exit(1);
+           }
+           netin = inet_addr(net);
+           if (netin == -1) {
+               syslog(LOG_ERR|LOG_DAEMON,
+                      "ypserv: %s line %d: error in address\n",ACCFILE,line);
+               exit(1);
+           }
+           if ((maskin & netin) != netin) {
+               syslog(LOG_ERR|LOG_DAEMON,
+                      "ypserv: %s line %d: netmask does not match network\n",
+                      ACCFILE,line);
+               exit(1);
+           }
+           tmp1->mask = maskin;
+           tmp1->net = netin;
+           tmp1->next = (struct seclist *) malloc(sizeof (struct seclist));
+           tmp2 = tmp1;
+           tmp1 = tmp1->next;
+       }
+       tmp2->next = NULL;
+     }
+     else {
+       syslog(LOG_INFO|LOG_DAEMON,"ypserv: no %s file\n",ACCFILE);
+       nofile = 1 ;
+     }
+ }
+ check_secure_net(caller)
+ struct sockaddr_in *caller;
+ {
+     struct seclist *tmp;
+     tmp = slist ;
+     if (nofile)
+       return(1);
+     while (tmp != NULL) {
+       if ((caller->sin_addr.s_addr & tmp->mask) == tmp->net){
+           return(1);
+       }
+       tmp = tmp->next;
+     }
+     syslog(LOG_ERR|LOG_DAEMON,"ypserv: access denied for %s\n",
+          inet_ntoa(caller->sin_addr));
+     return(0);
+ }
----- End of forward from Dan Trickle ----


        End of Security Digest Volume 3 Issue 12