TUCoPS :: Unix :: General :: kerb4-2.htm


TUCoPS :: Unix :: General :: kerb4-2.htm

Kerberos rsh, rcp and rlogin no check for permission
Vulnerability
 kerberos rsh, rcp and rlogin
Affected
 Systems running kerberos kth-krb4
Description
 There has been discovered a security-hole in kerberized rsh, rcp
 and rlogin. Every user on a kerberized system has a ticket-file.
 Only the owner should be able to read this file. The name of the
 ticketfile is stored in the environment-variable KRBTKFILE.
 The versions of rsh, rcp and rlogin in the kth-krb4 package are
 setuid to work with bsd-style rshd and rlogind. When they attempt
 to read the ticketfile, there is no check if the user starting
 the program has read access of the file. Thus, a user can use
 any other user on the system's ticketfile by simply changing an
 environment variable. To activate the bug, it is required that
 there are valid tickets for the target user laying around
 somewhere on your system (usually in /tmp/).
 The hole allows any user on the system to gain privilegies of any
 other user including root. Note also that it appears the bsdi
 version of su uses kerbose tickets if kerbose is configured, but
 the BSDI kerberosIV implementation does not appear to have the
 problem (the tf_init() routine which opens the ticket file checks
 to see that the real uid of the process is either root or owns
 the ticket file).
 The hole has been successfully tested on kth-kerberos, but is
 suspected to exist on any other versions of kerberos. The bug
 was discovered by Mattias Amnefelt.
Solution
 Disable the suid-bits on rcp, rsh and rlogin. This will disable
 the program's capabilities to fallback to the non-kerberised
 protocols if the a user fails to authenticate himself.
 Permanent fix should be changing the uid of the program to the
 user's uid as early as possible (patches from the development
 team are included, plus two other security patches for
 kth-kerberos). The enclosed patch to 0.9.6 fixes three security
 problems:
 1. the tgetent buffer overflow. This is fixed by simply not
 calling tgetent.
 2. vulnerability of setuid rsh, rlogin, and rcp.
 3. missing IP-nummer check in telnetd.
 This fix will of course be included in an upcoming version RSN.
 Index: appl/bsd/rcp.c
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/krb4/appl/bsd/rcp.c,v
 retrieving revision 1.43
 retrieving revision 1.44
 diff -u -w -r1.43 -r1.44
 --- rcp.c 1997年05月13日 09:41:26 1.43
 +++ rcp.c 1997年11月03日 11:18:02 1.44
 @@ -49,6 +49,9 @@
 static uid_t userid;
 static int pflag, iamremote, iamrecursive, targetshouldbedirectory;
 +static int argc_copy;
 +static char **argv_copy;
 +
 #define CMDNEEDS 64
 static char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d0円" */
 @@ -403,8 +406,9 @@
 kerberos(char **host, char *bp, char *locuser, char *user)
 {
 int sock = -1, err;
 -again:
 +
 if (use_kerberos) {
 + setuid(getuid());
 rem = KSUCCESS;
 errno = 0;
 if (dest_realm == NULL)
 @@ -439,13 +443,11 @@
 rem = sock;
 #endif
 if (rem < 0) {
 - use_kerberos = 0;
 - port = get_shell_port(use_kerberos, 0);
 if (errno == ECONNREFUSED)
 oldw("remote host doesn't support Kerberos");
 else if (errno == ENOENT)
 oldw("can't provide Kerberos authentication data");
 - goto again;
 + execv(_PATH_RCP, argv_copy);
 }
 } else {
 if (doencrypt)
 @@ -906,8 +908,28 @@
 {
 int ch, fflag, tflag;
 char *targ;
 + int i;
 set_progname(argv[0]);
 +
 + /*
 + * Prepare for execing ourselves.
 + */
 +
 + argc_copy = argc + 1;
 + argv_copy = malloc((argc_copy + 1) * sizeof(*argv_copy));
 + if (argv_copy == NULL)
 + err(1, "malloc");
 + argv_copy[0] = argv[0];
 + argv_copy[1] = "-K";
 + for(i = 1; i < argc; ++i) {
 + argv_copy[i + 1] = strdup(argv[i]);
 + if (argv_copy[i + 1] == NULL)
 + errx(1, "strdup: out of memory");
 + }
 + argv_copy[argc + 1] = NULL;
 +
 +
 fflag = tflag = 0;
 while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
 switch(ch) { /* User-visible flags. */
 @@ -951,8 +973,10 @@
 * kshell service, pass 0 for no encryption */
 port = get_shell_port(use_kerberos, 0);
 + userid = getuid();
 +
 #ifndef __CYGWIN32__
 - if ((pwd = k_getpwuid(userid = getuid())) == NULL)
 + if ((pwd = k_getpwuid(userid)) == NULL)
 errx(1, "unknown user %d", (int)userid);
 #endif
 Index: appl/bsd/rlogin.c
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/krb4/appl/bsd/rlogin.c,v
 retrieving revision 1.61
 retrieving revision 1.62
 diff -u -w -r1.61 -r1.62
 --- rlogin.c 1997年05月25日 01:14:47 1.61
 +++ rlogin.c 1997年11月03日 11:18:09 1.62
 @@ -594,14 +594,12 @@
 usage();
 }
 optind += argoff;
 - argc -= optind;
 - argv += optind;
 /* if haven't gotten a host yet, do so */
 - if (!host && !(host = *argv++))
 + if (!host && !(host = argv[optind++]))
 usage();
 - if (*argv)
 + if (argv[optind])
 usage();
 if (!(pw = k_getpwuid(uid = getuid())))
 @@ -609,7 +607,6 @@
 if (!user)
 user = pw->pw_name;
 -
 if (user_port)
 sv_port = user_port;
 else
 @@ -636,17 +633,8 @@
 get_window_size(0, &winsize);
 - try_connect:
 if (use_kerberos) {
 - struct hostent *hp;
 -
 - /* Fully qualify hostname (needed for krb_realmofhost). */
 - hp = gethostbyname(host);
 - if (hp != NULL && !(host = strdup(hp->h_name))) {
 - errno = ENOMEM;
 - err(1, NULL);
 - }
 -
 + setuid(getuid());
 rem = KSUCCESS;
 errno = 0;
 if (dest_realm == NULL)
 @@ -659,15 +647,22 @@
 rem = krcmd(&host, sv_port, user, term, 0,
 dest_realm);
 if (rem < 0) {
 - use_kerberos = 0;
 - if (user_port == 0)
 - sv_port = get_login_port(use_kerberos,
 - doencrypt);
 + int i;
 + char **newargv;
 +
 if (errno == ECONNREFUSED)
 warning("remote host doesn't support Kerberos");
 if (errno == ENOENT)
 warning("can't provide Kerberos auth data");
 - goto try_connect;
 + newargv = malloc((argc + 2) * sizeof(*newargv));
 + if (newargv == NULL)
 + err(1, "malloc");
 + newargv[0] = argv[0];
 + newargv[1] = "-K";
 + for(i = 1; i < argc; ++i)
 + newargv[i + 1] = argv[i];
 + newargv[argc + 1] = NULL;
 + execv(_PATH_RLOGIN, newargv);
 }
 } else {
 if (doencrypt)
 Index: appl/bsd/rsh.c
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/krb4/appl/bsd/rsh.c,v
 retrieving revision 1.36
 retrieving revision 1.37
 diff -u -w -r1.36 -r1.37
 --- rsh.c 1997年06月26日 13:48:35 1.36
 +++ rsh.c 1997年11月03日 11:18:14 1.37
 @@ -247,9 +247,6 @@
 err(1, "can't exec %s", _PATH_RLOGIN);
 }
 - argc -= optind;
 - argv += optind;
 -
 #ifndef __CYGWIN32__
 if (!(pw = k_getpwuid(uid = getuid())))
 errx(1, "unknown user id.");
 @@ -266,12 +263,12 @@
 if (doencrypt)
 nfork = 0;
 - args = copyargs(argv);
 + args = copyargs(argv+optind);
 sv_port=get_shell_port(use_kerberos, doencrypt);
 -try_connect:
 if (use_kerberos) {
 + setuid(getuid());
 rem = KSUCCESS;
 errno = 0;
 if (dest_realm == NULL)
 @@ -284,13 +281,22 @@
 rem = krcmd(&host, sv_port, user, args, &rfd2,
 dest_realm);
 if (rem < 0) {
 + int i;
 + char **newargv;
 +
 if (errno == ECONNREFUSED)
 warning("remote host doesn't support Kerberos");
 if (errno == ENOENT)
 warning("can't provide Kerberos auth data");
 - use_kerberos = 0;
 - sv_port=get_shell_port(use_kerberos, doencrypt);
 - goto try_connect;
 + newargv = malloc((argc + 2) * sizeof(*newargv));
 + if (newargv == NULL)
 + err(1, "malloc");
 + newargv[0] = argv[0];
 + newargv[1] = "-K";
 + for(i = 1; i < argc; ++i)
 + newargv[i + 1] = argv[i];
 + newargv[argc + 1] = NULL;
 + execv(_PATH_RSH, newargv);
 }
 } else {
 if (doencrypt)
 Index: appl/bsd/pathnames.h
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/krb4/appl/bsd/pathnames.h,v
 retrieving revision 1.23
 retrieving revision 1.24
 diff -u -w -r1.23 -r1.24
 --- pathnames.h 1996年11月17日 06:36:42 1.23
 +++ pathnames.h 1997年11月03日 11:17:19 1.24
 @@ -65,6 +65,9 @@
 #undef _PATH_RSH /* Redifine rsh */
 #define _PATH_RSH BINDIR "/rsh"
 +#undef _PATH_RCP /* Redifine rcp */
 +#define _PATH_RCP BINDIR "/rcp"
 +
 #undef _PATH_LOGIN
 #define _PATH_LOGIN BINDIR "/login"
 @@ -186,6 +189,8 @@
 #define _PATH_RLOGIN "/usr/athena/bin/rlogin"
 #undef _PATH_RSH
 #define _PATH_RSH "/usr/athena/bin/rsh"
 +#undef _PATH_RCP
 +#define _PATH_RCP "/usr/athena/bin/rcp"
 #undef _PATH_LOGIN
 #define _PATH_LOGIN "/usr/athena/bin/login"
 #endif
 Index: appl/telnet/libtelnet/kerberos.c
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/appl/telnet/libtelnet/kerberos.c,v
 retrieving revision 1.34
 retrieving revision 1.36
 diff -u -w -r1.34 -r1.36
 --- kerberos.c 1997年10月21日 21:15:24 1.34
 +++ kerberos.c 1997年11月03日 06:12:14 1.36
 @@ -265,9 +267,11 @@
 void
 kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
 {
 + struct sockaddr_in addr;
 char realm[REALM_SZ];
 char instance[INST_SZ];
 int r;
 + int addr_len;
 if (cnt-- < 1)
 return;
 @@ -288,8 +292,17 @@
 printf("\r\n");
 }
 k_getsockinst(0, instance, sizeof(instance));
 - if (r = krb_rd_req(&auth, KRB_SERVICE_NAME,
 - instance, 0, &adat, "")) {
 + addr_len = sizeof(addr);
 + if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) {
 + if(auth_debug_mode)
 + printf("getpeername failed\r\n");
 + Data(ap, KRB_REJECT, "getpeername failed", -1);
 + auth_finished(ap, AUTH_REJECT);
 + return;
 + }
 + r = krb_rd_req(&auth, KRB_SERVICE_NAME,
 + instance, addr.sin_addr.s_addr, &adat, "");
 + if (r) {
 if (auth_debug_mode)
 printf("Kerberos failed him as %s\r\n", name);
 Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1);
 Index: appl/telnet/telnetd/telnetd.c
 ===================================================================
 RCS file: /afs/pdc.kth.se/src/packages/kth-krb/src/appl/telnet/telnetd/telnetd.c,v
 retrieving revision 1.47
 retrieving revision 1.48
 diff -u -w -r1.47 -r1.48
 --- telnetd.c 1997年10月29日 01:26:58 1.47
 +++ telnetd.c 1997年11月03日 06:08:26 1.48
 @@ -647,21 +647,7 @@
 int
 terminaltypeok(char *s)
 {
 - char buf[1024];
 -
 - if (terminaltype == NULL)
 - return(1);
 -
 - /*
 - * tgetent() will return 1 if the type is known, and
 - * 0 if it is not known. If it returns -1, it couldn't
 - * open the database. But if we can't open the database,
 - * it won't help to say we failed, because we won't be
 - * able to verify anything else. So, we treat -1 like 1.
 - */
 - if (tgetent(buf, s) == 0)
 - return(0);
 - return(1);
 + return 1;
 }

AltStyle によって変換されたページ (->オリジナル) /

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH