From owner-freebsd-hackers Sat Dec 14 01:30:39 1996 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.4/8.8.4) id BAA18406 for hackers-outgoing; Sat, 14 Dec 1996 01:30:39 -0800 (PST) Received: from pdx1.world.net (pdx1.world.net [192.243.32.18]) by freefall.freebsd.org (8.8.4/8.8.4) with ESMTP id BAA18390 for ; Sat, 14 Dec 1996 01:30:36 -0800 (PST) Received: from suburbia.net (suburbia.net [203.4.184.1]) by pdx1.world.net (8.7.5/8.7.3) with SMTP id BAA21656 for ; Sat, 14 Dec 1996 01:30:51 -0800 (PST) Received: (qmail 17540 invoked from network); 14 Dec 1996 09:00:36 -0000 Received: from unknown (HELO profane.iq.org) (203.4.184.215) by suburbia.net with SMTP; 14 Dec 1996 09:00:36 -0000 Received: (from proff@localhost) by profane.iq.org (8.8.4/8.8.2) id MAA04639; Sat, 14 Dec 1996 12:35:26 +1100 (EST) From: Julian Assange Message-Id: <199612140135.MAA04639@profane.iq.org> Subject: vulnerability in new pw suite To: security@freebsd.org Date: Sat, 14 Dec 1996 12:35:25 +1100 (EST) Cc: hackers@freebsd.org X-Mailer: ELM [version 2.4ME+ PL28 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 #include #include +#include +#include +#include +#include #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;ndefault_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'; /*