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);