Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Dec 1996 12:35:25 +1100 (EST)
From:      Julian Assange <proff@iq.org>
To:        security@freebsd.org
Cc:        hackers@freebsd.org
Subject:   vulnerability in new pw suite
Message-ID:  <199612140135.MAA04639@profane.iq.org>

next in thread | raw e-mail | index | archive | help
The FreeBSD account administration pw suite is able to produce
"random" passwords for new accounts. Due to the simplicity of the
password generation algorithm involved, the passwords are easily
predictable amid a particular range of possibilities. This range
may be very narrow, depending on what sort of information is
available to the attacker.

The pid and the current time in seconds are ored (NOT xored)
together and used as the seed. Because of this, the probability
of a lower bit in the seed of being on is 3/4. The msb's of
the seed change very slowly and predictably over time and in
effect contain no entropy. 

If the attacker has access to the file system then the time the
account was created on can by guessed very accurately by
examining the creation date of the new account's directory, or
the creation date of the new account's mail spool file. 

With the time part of the seed known it is then possible to
generate an a mask to eliminate 50% of the remaining possible
pid values. The pid can be further approximated retrospectively
by correlation between time stamps and pid values from a wide
number of file system sources such as the pid of the sendmail
task used to deliver the new-user mail, to names of /tmp and
queue files. An active attack (looking for the "pw" process or
other signs of account creation) will of course locate the
pid very closely, if not exactly.

The attached patch addresses the problem.

-Julian A. (proff@suburbia.net)

--- /usr/src/usr.sbin/pw/pw_user.c.orig	Thu Dec 12 02:10:47 1996
+++ /usr/src/usr.sbin/pw/pw_user.c	Sat Dec 14 11:37:50 1996
@@ -33,6 +33,10 @@
 #include <sys/param.h>
 #include <dirent.h>
 #include <termios.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <md5.h>
 #include "pw.h"
 #include "bitmap.h"
 #include "pwupd.h"
@@ -738,19 +742,61 @@
 	return strcpy(buf, crypt(password, salt));
 }
 
+u_char *
+pw_genmd5rand (u_char *d)		/* cryptographically secure rng */
+{
+	MD5_CTX md5_ctx;
+	struct timeval tv, tvo;
+	struct rusage ru;
+	int n=0;
+	int t;
+	MD5Init (&md5_ctx);
+	t=getpid();
+	MD5Update (&md5_ctx, (u_char*)&t, sizeof t);
+	t=getppid();
+	MD5Update (&md5_ctx, (u_char*)&t, sizeof t);
+	gettimeofday (&tvo, NULL);
+	do {
+		getrusage (RUSAGE_SELF, &ru);
+		MD5Update (&md5_ctx, (u_char*)&ru, sizeof ru);
+		gettimeofday (&tv, NULL);
+		MD5Update (&md5_ctx, (u_char*)&tv, sizeof tv);
+	} while (n++<20 || tv.tv_usec-tvo.tv_usec<100*1000);
+	MD5Final (d, &md5_ctx);
+	return d;
+}
+
+static u_char *
+pw_getrand(u_char *buf, int len)
+{
+	int		fd;
+	fd = open("/dev/urandom", O_RDONLY);
+	if (!fd || read(fd, buf, len)!=len) {
+		int n;
+		for (n=0;n<len;n+=16) {
+			u_char ubuf[16];
+			pw_genmd5rand(ubuf);
+			memcpy(buf+n, ubuf, MIN(16, len-n));
+		}
+	}
+	close(fd);
+	return buf;
+}
 
 static char    *
 pw_password(struct userconf * cnf, struct cargs * args, char const * user)
 {
 	int             i, l;
 	char            pwbuf[32];
+	u_char		rndbuf[sizeof pwbuf];
 
 	switch (cnf->default_password) {
 	case -1:		/* Random password */
 		srandom((unsigned) (time(NULL) | getpid()));
 		l = (random() % 8 + 8);	/* 8 - 16 chars */
+		pw_getrand(rndbuf, l);
 		for (i = 0; i < l; i++)
-			pwbuf[i] = chars[random() % sizeof(chars)];
+			pwbuf[i] = chars[rndbuf[i] % sizeof(chars)];
 		pwbuf[i] = '\0';
 
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612140135.MAA04639>