summaryrefslogtreecommitdiffstats
path: root/eBones
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1996-02-21 21:40:14 +0000
committerache <ache@FreeBSD.org>1996-02-21 21:40:14 +0000
commit98df79c16931ef02ab7229300615dca86fad47dc (patch)
treeb0848fa1c6dc4a050577c2eaf8f74eb65adfb782 /eBones
parentbd67217d9d096e3372106b02a86d0e53e3c5961a (diff)
downloadFreeBSD-src-98df79c16931ef02ab7229300615dca86fad47dc.zip
FreeBSD-src-98df79c16931ef02ab7229300615dca86fad47dc.tar.gz
Fix weak random number hole
Obtained from: CERT
Diffstat (limited to 'eBones')
-rw-r--r--eBones/README.PATCH60
-rw-r--r--eBones/usr.sbin/Makefile6
-rw-r--r--eBones/usr.sbin/fix_kdb_keys/Makefile10
-rw-r--r--eBones/usr.sbin/fix_kdb_keys/fix_kdb_keys.c191
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.c8
-rw-r--r--eBones/usr.sbin/kdb_init/kdb_init.c7
-rw-r--r--eBones/usr.sbin/kerberos/kerberos.c9
-rw-r--r--eBones/usr.sbin/ksrvutil/ksrvutil.c8
8 files changed, 284 insertions, 15 deletions
diff --git a/eBones/README.PATCH b/eBones/README.PATCH
new file mode 100644
index 0000000..33cb15f
--- /dev/null
+++ b/eBones/README.PATCH
@@ -0,0 +1,60 @@
+READ THIS ENTIRE FILE BEFORE PROCEEDING!
+
+This distribution contains a "diff" file suitable for using with the
+"patch" program to update your Kerberos (version 4) source tree. The
+gist of the patch is to replace calls to des_random_key() with calls
+to des_new_random_key().
+
+The primary difference is that des_random_key() uses a seeding
+technique which is predictable and therefore
+vulnerable. des_new_random_key() uses a feedback mechanism based on
+the Data Encryption Standard (DES) and is seeded with a secret (and
+therefore unknown to an attacker) value. This value is the database
+master key, which is a convenient secret value.
+
+This patch assumes that you have the new_rnd_key.c key module (which
+contains the definition and code for des_new_random_key()). It has
+been part of the standard Version 4 distribution since 1992 and is
+used in the admin server (our primary error at MIT was not upgrading
+all of Kerberos to use this newer generator. This patch finishes the
+job).
+
+In addition to the patch file for the Kerberos distribution this
+distribution also contains a program for changing critical system keys
+(namely the "krbtgt" and "changepw.kerberos" keys). When you
+originally built your Kerberos database these keys were chosen at
+random, using the vulnerable version of the kerberos random number
+generator. Therefore it is possible for an attacker to mount an attack
+to guess these values. If an attacker can determine the key for the
+"krbtgt" ticket, they can construct tickets claiming to be any
+kerberos principal. Similarly if an attacker can obtain the
+"changepw.kerberos" key, they can change anyone's password.
+
+The enclosed "fix_kdb_keys.c" (part of the patch file) program, which
+you run on the KDC server, will change these critical keys to new
+values using the newer random number generator. IMPORTANT: When you
+run fix_kdb_keys, all outstanding ticket granting tickets will
+immediately become invalid. This will be disruptive to your user
+community. We recommend that you either do this late at night or early
+in the morning before most users have logged in. Alternatively
+pre-announce a definitive time when you will run the program and
+inform your users that they will have to get new tickets at that time
+(using either "kinit" or simply by logging out and then in again).
+
+NOTE: The only client program modified is "ksrvutil" which is used to
+generate new server keys. All other client/server programs are
+unaffected. End users do *not* need to obtain new versions of programs
+that use Kerberos. This is because most random number generation in
+the Kerberos system is done on the KDC system. By fixing kerberos.c
+you have repaired most of the damage.
+
+To install this patch copy patch_krb to the toplevel of your Kerberos
+source tree. Then type:
+
+patch -p0 <patch_krb
+
+This will install changes to various kerberos modules to upgrade them
+to use des_new_random_key(). It also will install a new program,
+"fix_kdb_keys.c." After the patch is complete type "make world" at the
+toplevel of your Kerberos source tree. This will, among other things,
+build the fix_kdb_keys program.
diff --git a/eBones/usr.sbin/Makefile b/eBones/usr.sbin/Makefile
index 4d583fc..f37c844 100644
--- a/eBones/usr.sbin/Makefile
+++ b/eBones/usr.sbin/Makefile
@@ -1,7 +1,7 @@
# From: @(#)Makefile 5.1 (Berkeley) 6/25/90
-# $Id$
+# $Id: Makefile,v 1.1 1995/09/13 17:24:15 markm Exp $
-SUBDIR= ext_srvtab kadmind kdb_destroy kdb_edit kdb_init kdb_util \
- kerberos kprop ksrvutil kstash make_keypair
+SUBDIR= ext_srvtab fix_kdb_keys kadmind kdb_destroy kdb_edit kdb_init \
+ kdb_util kerberos kprop ksrvutil kstash make_keypair
.include <bsd.subdir.mk>
diff --git a/eBones/usr.sbin/fix_kdb_keys/Makefile b/eBones/usr.sbin/fix_kdb_keys/Makefile
new file mode 100644
index 0000000..6cbdd16
--- /dev/null
+++ b/eBones/usr.sbin/fix_kdb_keys/Makefile
@@ -0,0 +1,10 @@
+# From: @(#)Makefile 5.2 (Berkeley) 3/5/91
+# $Id: Makefile,v 1.7 1995/09/26 06:20:18 mark Exp $
+
+PROG= fix_kdb_keys
+CFLAGS+=-DKERBEROS -DDEBUG
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= YES
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/fix_kdb_keys/fix_kdb_keys.c b/eBones/usr.sbin/fix_kdb_keys/fix_kdb_keys.c
new file mode 100644
index 0000000..3719e78
--- /dev/null
+++ b/eBones/usr.sbin/fix_kdb_keys/fix_kdb_keys.c
@@ -0,0 +1,191 @@
+/*
+ * $Source: /afs/net/project/krb4/src/admin/RCS/kdb_edit.c,v $
+ * $Author: tytso $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services.
+ */
+
+/*
+ * exit returns 0 ==> success -1 ==> error
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#ifdef NEED_TIME_H
+#include <time.h>
+#endif
+#include <sys/time.h>
+
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+/* MKEYFILE is now defined in kdc.h */
+#include <kdc.h>
+
+char prog[32];
+char *progname = prog;
+int nflag = 0;
+int debug = 0;
+extern int krb_debug;
+
+Principal principal_data;
+
+static C_Block master_key;
+static Key_schedule master_key_schedule;
+static long master_key_version;
+
+static char realm[REALM_SZ];
+
+void fatal_error(), cleanup();
+void Usage();
+void change_principal();
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int i;
+
+ prog[sizeof prog - 1] = '\0'; /* make sure terminated */
+ strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
+ * program */
+
+ /* Assume a long is four bytes */
+ if (sizeof(long) != 4) {
+ fprintf(stderr, "%s: size of long is %d.\n", prog, sizeof(long));
+ exit(-1);
+ }
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i = 1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ debug = 1;
+ continue;
+
+ /* debug flag */
+ case 'l':
+ krb_debug |= 1;
+ continue;
+
+ case 'n': /* read MKEYFILE for master key */
+ nflag = 1;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: illegal flag \"%c\"\n", progname, argv[0][i]);
+ Usage(); /* Give message and die */
+ }
+ };
+
+ if (krb_get_lrealm(realm, 1)) {
+ fprintf(stderr, "Couldn't get local realm information.\n");
+ fatal_error();
+ }
+
+ kerb_init();
+ if (argc > 0) {
+ if (kerb_db_set_name(*argv) != 0) {
+ fprintf(stderr, "Could not open altername database name\n");
+ fatal_error();
+ }
+ }
+
+ if (kdb_get_master_key ((nflag == 0),
+ master_key, master_key_schedule) != 0) {
+ fprintf (stderr, "Couldn't read master key.\n");
+ fatal_error();
+ }
+
+ if ((master_key_version = kdb_verify_master_key(master_key,
+ master_key_schedule,
+ stdout)) < 0)
+ fatal_error();
+
+ des_init_random_number_generator(master_key);
+
+ change_principal("krbtgt", realm);
+ change_principal("changepw", KRB_MASTER);
+
+ cleanup();
+
+ printf("\nKerberos database updated successfully. Note that all\n");
+ printf("existing ticket-granting tickets have been invalidated.\n\n");
+
+ return(0);
+}
+
+void change_principal(input_name, input_instance)
+ char *input_name;
+ char *input_instance;
+{
+ int n, more;
+ C_Block new_key;
+
+ n = kerb_get_principal(input_name, input_instance, &principal_data,
+ 1, &more);
+ if (!n) {
+ fprintf(stderr, "Can't find principal database for %s.%s.\n",
+ input_name, input_instance);
+ fatal_error();
+ }
+ if (more) {
+ fprintf(stderr, "More than one entry for %s.%s.\n", input_name,
+ input_instance);
+ fatal_error();
+ }
+
+ des_new_random_key(new_key);
+
+ /* seal it under the kerberos master key */
+ kdb_encrypt_key (new_key, new_key,
+ master_key, master_key_schedule,
+ ENCRYPT);
+ memcpy(&principal_data.key_low, new_key, 4);
+ memcpy(&principal_data.key_high, ((long *) new_key) + 1, 4);
+ memset(new_key, 0, sizeof(new_key));
+
+ principal_data.key_version++;
+
+ if (kerb_put_principal(&principal_data, 1)) {
+ fprintf(stderr, "\nError updating Kerberos database");
+ fatal_error();
+ }
+
+ memset(&principal_data.key_low, 0, 4);
+ memset(&principal_data.key_high, 0, 4);
+}
+
+void fatal_error()
+{
+ cleanup();
+ exit(1);
+}
+
+void cleanup()
+{
+
+ memset(master_key, 0, sizeof(master_key));
+ memset(master_key_schedule, 0, sizeof(master_key_schedule));
+ memset(&principal_data, 0, sizeof(principal_data));
+}
+
+void Usage()
+{
+ fprintf(stderr, "Usage: %s [-n]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c
index 82bf9a4..eadbcf5 100644
--- a/eBones/usr.sbin/kdb_edit/kdb_edit.c
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c
@@ -8,7 +8,7 @@
* i.e., users or services.
*
* from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
- * $Id: kdb_edit.c,v 1.5 1995/08/03 17:15:54 mark Exp $
+ * $Id: kdb_edit.c,v 1.5 1995/09/07 21:37:17 markm Exp $
*/
/*
@@ -18,7 +18,7 @@
#if 0
#ifndef lint
static char rcsid[] =
-"$Id: kdb_edit.c,v 1.5 1995/08/03 17:15:54 mark Exp $";
+"$Id: kdb_edit.c,v 1.5 1995/09/07 21:37:17 markm Exp $";
#endif lint
#endif
@@ -173,6 +173,8 @@ main(argc, argv)
stdout)) < 0)
exit (-1);
+ des_init_random_number_generator(master_key);
+
/* lookup the default values */
n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
&default_princ, 1, &more);
@@ -282,7 +284,7 @@ change_principal()
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
- random_key(new_key);
+ des_new_random_key(new_key); /* yes, random */
#endif
bzero(pw_str, sizeof pw_str);
}
diff --git a/eBones/usr.sbin/kdb_init/kdb_init.c b/eBones/usr.sbin/kdb_init/kdb_init.c
index de99181..42d1b18 100644
--- a/eBones/usr.sbin/kdb_init/kdb_init.c
+++ b/eBones/usr.sbin/kdb_init/kdb_init.c
@@ -7,13 +7,13 @@
* already exists.
*
* from: kdb_init.c,v 4.0 89/01/24 21:50:45 jtkohl Exp $
- * $Id: kdb_init.c,v 1.4 1995/07/18 16:37:35 mark Exp $
+ * $Id: kdb_init.c,v 1.4 1995/09/07 21:37:20 markm Exp $
*/
#if 0
#ifndef lint
static char rcsid[] =
-"$Id: kdb_init.c,v 1.4 1995/07/18 16:37:35 mark Exp $";
+"$Id: kdb_init.c,v 1.4 1995/09/07 21:37:20 markm Exp $";
#endif lint
#endif
@@ -97,6 +97,7 @@ main(argc, argv)
fprintf (stderr, "Couldn't read master key.\n");
exit (-1);
}
+ des_init_random_number_generator(master_key);
if (
add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY) ||
@@ -140,7 +141,7 @@ add_principal(name, instance, aap_op)
bzero(new_key, sizeof(C_Block));
new_key[0] = 127;
#else
- random_key(new_key);
+ des_new_random_key(new_key);
#endif
kdb_encrypt_key (new_key, new_key, master_key, master_key_schedule,
ENCRYPT);
diff --git a/eBones/usr.sbin/kerberos/kerberos.c b/eBones/usr.sbin/kerberos/kerberos.c
index a15475d..c30f6a1 100644
--- a/eBones/usr.sbin/kerberos/kerberos.c
+++ b/eBones/usr.sbin/kerberos/kerberos.c
@@ -5,13 +5,13 @@
* <Copyright.MIT>.
*
* from: kerberos.c,v 4.19 89/11/01 17:18:07 qjb Exp $
- * $Id: kerberos.c,v 1.4 1995/09/07 21:37:27 markm Exp $
+ * $Id: kerberos.c,v 1.5 1995/09/17 00:39:00 gibbs Exp $
*/
#if 0
#ifndef lint
static char rcsid[] =
-"$Id: kerberos.c,v 1.4 1995/09/07 21:37:27 markm Exp $";
+"$Id: kerberos.c,v 1.5 1995/09/17 00:39:00 gibbs Exp $";
#endif lint
#endif
@@ -269,6 +269,7 @@ main(argc, argv)
bzero (master_key_schedule, sizeof (master_key_schedule));
exit (-1);
}
+ des_init_random_number_generator(master_key);
master_key_version = (u_char) kerror;
@@ -434,7 +435,7 @@ kerberos(client, pkt)
#ifdef NOENCRYPTION
bzero(session_key, sizeof(C_Block));
#else
- random_key(session_key);
+ des_new_random_key(session_key);
#endif
/* unseal server's key from master key */
bcopy(&s_name_data.key_low, key, 4);
@@ -565,7 +566,7 @@ kerberos(client, pkt)
#ifdef NOENCRYPTION
bzero(session_key, sizeof(C_Block));
#else
- random_key(session_key);
+ des_new_random_key(session_key);
#endif
krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
diff --git a/eBones/usr.sbin/ksrvutil/ksrvutil.c b/eBones/usr.sbin/ksrvutil/ksrvutil.c
index 1062ea5..08fa9f5 100644
--- a/eBones/usr.sbin/ksrvutil/ksrvutil.c
+++ b/eBones/usr.sbin/ksrvutil/ksrvutil.c
@@ -12,7 +12,7 @@
static char rcsid_ksrvutil_c[] =
"BonesHeader: /afs/athena.mit.edu/astaff/project/kerberos/src/kadmin/RCS/ksrvutil.c,v 4.1 89/09/26 09:33:49 jtkohl Exp ";
static const char rcsid[] =
- "$Id: ksrvutil.c,v 1.1 1995/07/18 16:40:11 mark Exp $";
+ "$Id: ksrvutil.c,v 1.5 1995/09/07 21:38:40 markm Exp $";
#endif lint
#endif
@@ -523,16 +523,20 @@ get_svc_new_key(new_key, sname, sinst, srealm, keyfile)
char *keyfile;
{
int status = KADM_SUCCESS;
+ CREDENTIALS c;
if (((status = krb_get_svc_in_tkt(sname, sinst, srealm, PWSERV_NAME,
KADM_SINST, 1, keyfile)) == KSUCCESS) &&
+ ((status = krb_get_cred(PWSERV_NAME, KADM_SINST, srealm, &c)) ==
+ KSUCCESS) &&
((status = kadm_init_link("changepw", KRB_MASTER, srealm)) ==
KADM_SUCCESS)) {
#ifdef NOENCRYPTION
bzero((char *) new_key, sizeof(des_cblock));
new_key[0] = (unsigned char) 1;
#else /* NOENCRYPTION */
- des_random_key(new_key);
+ des_init_random_number_generator(c.session);
+ (void) des_new_random_key(new_key);
#endif /* NOENCRYPTION */
return(KADM_SUCCESS);
}
OpenPOWER on IntegriCloud