[13766] in Athena Bugs
telnetd patch to audit
daemon@ATHENA.MIT.EDU (brlewis@MIT.EDU)
Thu Aug 24 14:53:33 1995
From: brlewis@MIT.EDU
Date: Thu, 24 Aug 95 14:53:27 -0400
To: bugs@MIT.EDU
Cc: "Daniel G. Pouzzner" <douzzer@prez.mit.edu>
I was able to verify that with the old telnetd,
1) telnet with valid tickets succeeded
2) telnet with tickets from another host succeeded <-- bug
With the fix supplied here, I verified,
1) telnet with valid tickets succeeded
2) telnet with tickets from another host failed
The failure message given is
Can't decode authenticator (krb_rd_req)
It should be
Incorrect network address (krb_rd_req)
I think it's important that the fix be audited by someone familiar with
Kerberos, especially given the suspicious error message.
douzzer wrote,
>Any rcmd.* key in the ticket file will
>be sufficient to gain entry to any host using Athena telnetd.
this should be,
>An rcmd.foo key in the ticket file will
>be sufficient to gain entry from any host if foo is using Athena telnetd.
The risk here is that this bug makes it easier for someone stealing
tickets to exploit them undetected by copying them to another host and
using them from there. The cracker can then gain entry into hosts for
which the victim has already acquired rcmd keys, but cannot gain entry
into other hosts using Athena telnetd. (douzzer probably knows this,
but just wasn't writing clearly).
Patch to audit:
*** 1.12 1995/02/02 16:11:55
--- libtelnet/kerberos.c 1995/08/24 17:31:31
***************
*** 57,62 ****
--- 57,63 ----
#ifdef KRB4
#include <sys/types.h>
+ #include <netinet/in.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <des.h> /* BSD wont include this in krb.h, so we do it here */
***************
*** 318,323 ****
--- 319,326 ----
return(1);
}
+ struct sockaddr_in *PeerName=(struct sockaddr_in *)0;
+
void
kerberos4_is(ap, data, cnt)
Authenticator *ap;
***************
*** 331,339 ****
--- 334,344 ----
char realm[REALM_SZ];
char instance[INST_SZ];
int r;
+ u_long from_addr=0L; /* IP address of peer */
if (cnt-- < 1)
return;
+ if (PeerName) from_addr = PeerName->sin_addr.S_un.S_addr;
switch (*data++) {
case KRB_AUTH:
if (krb_get_lrealm(realm, 1) != KSUCCESS) {
***************
*** 353,382 ****
instance[0] = '*'; instance[1] = 0;
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! instance, 0, &adat, "");
if (r)
{ /* INSTANT HACK - JUST ADD GROSSNESS */
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "express", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "test", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "dec", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena-dec", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena-x", 0, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "x", 0, &adat, "");
}
if (r) {
--- 358,387 ----
instance[0] = '*'; instance[1] = 0;
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! instance, from_addr, &adat, "");
if (r)
{ /* INSTANT HACK - JUST ADD GROSSNESS */
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "express", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "test", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "dec", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena-dec", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "athena-x", from_addr, &adat, "");
if (r)
r = krb_rd_req(&auth, KRB_SERVICE_NAME,
! "x", from_addr, &adat, "");
}
if (r) {
*** 1.6 1995/04/27 00:18:15
--- telnetd/telnetd.c 1995/08/24 17:38:47
***************
*** 185,190 ****
--- 185,193 ----
#if defined(IPPROTO_IP) && defined(IP_TOS)
int tos = -1;
#endif
+ #ifdef KRB4
+ extern struct sockaddr_in *PeerName;
+ #endif
pfrontp = pbackp = ptyobuf;
netip = netibuf;
***************
*** 515,520 ****
--- 518,524 ----
perror("getpeername");
_exit(1);
}
+ PeerName = &from;
if (keepalive &&
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
(char *)&on, sizeof (on)) < 0) {