COMMAND

    gopherd

SYSTEMS AFFECTED

    Gopherd 2.x

PROBLEM

    Michael Schiffman  found following  (Guardent Security  Advisory).
    There is a vulnerability in the way the standard Unix gopherd  2.x
    (a.k.a. UMN gopherd) creates a gopher DES key for  authentication.
    If properly exploited, this vulnerability allows a remote user  to
    gain unauthorized root access to affected systems.

    Guardent discovered and successfully exploited this  vulnerability
    under RedHat  Linux (although  the vulnerability  is not  platform
    specific) using Gopherd 2.3.

    A buffer overflow exists in UMN's gopherd 2.x, which is vulnerable
    to an exploit  during the generation  of a gopher  DES key (called
    GDESkey).   After  the  program  returns  from  the key generation
    function,  it  is  possible  to  get  arbitrary  code  executed by
    gopherd.  The key generation code is called when the gopher server
    attempts to decode a ticket that is received from a client in  the
    form  of:  "*  <username>  <ticket>".   This  ticket  is where the
    shellcode may be stashed.

    By default,  ALL UMN  gopherd 2.x  versions are  vulnerable unless
    compiled  with  the  NO_AUTHENTICATION  CPP  flag.  Compiling with
    NO_AUTHENTICATION,    however,     completely    disables     user
    authentication and is  probably not done.   Successful exploit  of
    this  bug  will  yield  superuser  access  to  the remote attacker
    unless  gopherd  is  started  with  the  "-u  user_id"  switch and
    "user_id" is something other than root.

SOLUTION

    Guardent's research and development team immediately notified  the
    University  of  Minnesota  and  provided  them  with a patch.  The
    latest gopherd has been fixed and is available for download at:

        ftp://boombox.micro.umn.edu/pub/gopher/Unix/gopher2_3.1.tar.gz

    You may opt to install Guardent's official patch manually by using
    the `patch` program:

    diff -ru gopher2_3.old/gopherd/authenticate.c gopher2_3/gopherd/authenticate.c
    --- gopher2_3.old/gopherd/authenticate.c	Sat Aug 12 16:34:47 2000
    +++ gopher2_3/gopherd/authenticate.c	Sat Aug 12 16:51:51 2000
    @@ -494,11 +494,12 @@
          char          keystr[256];
          char         *cp;
          Desnum        c;
    -     int i;
    +     int i, keysize;
    
    -     strcpy(keystr, user);
    -     strcat(keystr, ip);
    -     strcat(keystr, key);
    +     keysize = sizeof(keystr)-1, memset(keystr, 0, keysize+1);
    +     strncat(keystr, user, keysize), i = keysize - strlen(keystr);
    +     strncat(keystr, ip, i), i = keysize - strlen(keystr);
    +     strncat(keystr, key, i);
    
          Debug("Encoding key %s\n", keystr);

    2.3.1 patch:

    diff -ru gopher2_3.1.old/gopherd/authenticate.c
    gopher2_3.1/gopherd/authenticate.c
    --- gopher2_3.1.old/gopherd/authenticate.c	Sat Aug 12 16:34:57 2000
    +++ gopher2_3.1/gopherd/authenticate.c	Sat Aug 12 16:51:40 2000
    @@ -496,13 +496,10 @@
          Desnum        c;
          int i, keysize;
    
    -/*     strcpy(keystr, user);
    -     strcat(keystr, ip);
    -     strcat(keystr, key); */
    -	i = keysize = sizeof(keystr)-1;
    -	strncpy(keystr, user, i), i -= strlen(keystr);
    -	strncat(keystr, ip, i), i -= strlen(keystr);
    -	strncat(keystr, key, i), keystr[keysize] = '\0';
    +     keysize = sizeof(keystr)-1, memset(keystr, 0, keysize+1);
    +     strncat(keystr, user, keysize), i = keysize - strlen(keystr);
    +     strncat(keystr, ip, i), i = keysize - strlen(keystr);
    +     strncat(keystr, key, i);
    
          Debug("Encoding key %s\n", keystr);