Messages in this thread | | | Date | Thu, 5 Aug 1999 23:56:15 -0400 (EDT) | From | "Robert G. Brown" <> | Subject | Re: [OFFTOPIC] Re: password encryption |
| |
On Thu, 5 Aug 1999, Alan Curry wrote:
> Robert G. Brown writes the following: > > > >main(argc, argv) > > int argc; > > char **argv; > > { > > char *s,passwd[128],salt[8]; > > unsigned long i,iterations; > > > > if(argc != 3) { > > fprintf(stderr, "usage: makepw passwd salt\n"); > > exit(1); > > } > > argv++; > > sprintf(passwd,"%s",*argv); > > Buffer overflow waiting to happen
<Pow> Ugh. Got me right in the gut.
Perhaps I should explain.
First, I wrote this a LONG time ago (ten or fifteen years) for personal use -- it isn't designed to be proof against buffer overwrites or the like because it is strictly a userspace program, not a daemon and I generally don't even run it as root as there is no need to.
Second, it was designed to generate "standard unix" passwd's which (according to the man page) are only 8 characters significant.
Third, according to the crypt man page documentation ditto, it uses DES encryption, not MD5, and the man page also states that the salt is only two characters. Indeed, the salt is by convention the first two characters of the /etc/passwd encrypted passwd field and the DES crypt ignores more than eight characters in the input string and two in the salt ANYWAY.
Fourth, very similar routines (perhaps less sloppily written:-) were used in crack at the time I wrote this tiny utility code and may indeed still be there.
SO, flame away, but recognize that for its purpose (use by ME to generate DES encrypted passwd fields for a standard /etc/passwd file by hand a decade ago) it works just fine. OK, so I was lazy and sloppy using sprintf instead of strncpy and did no length checking...I was younger then.
> > /* Truncate passwd at eight characters on general principles.*/ > > passwd[8] = 0; > > Wrong. MD5 passwords can be significant to a lot more than 8 chars.
But the standard unix passwd command available on most systems (including those flavors of linux I've access to) only accept passwd's with eight or fewer characters. On my nice new RH 6 install, it says that the new passwd is "too similar to the old one" if I enter 10 characters none of which resemble those in my old one, but if I enter only the first 8 it is happy. Obviously, it uses the DES crypt and not MD5.
Perhaps the original poster wanted to generate MD5 passwds. On the other hand, perhaps he (like me) just wanted to be able to build encrypted passwd fields on demand to paste into a /etc/passwd file for new users, perhaps in a simple script (I have another variant of the same code that generates 1-N RANDOM new passwd's for the same purpose).
> > argv++; > > sprintf(salt,"%s",*argv); > > Another buffer overflow waiting to happen > > > /* Truncate salt at two characters, ditto. */ > > salt[2] = 0; > > Wrong. MD5 salt is longer than 2 chars. > > > s=crypt(passwd,salt); > > printf("%s\n",s); > > exit(0); > > } > > People, don't truncate things before passing them to crypt. It knows more > than you do about the right lengths of passwords and salt.
True enough. If you don't truncate the strings at all, (and clean up the code so it is buffer safe to protect you from segment faults in the event that you enter way too many characters) then you get the following behaviour:
gcc -O3 -lcrypt makepw.c -o makepw rgb@rgb|T:30>>!./ma ./makepw frogfrog abcdef abi219G9lnw4E rgb@rgb|T:31>>./makepw frogfrogfrog abcdef abi219G9lnw4E rgb@rgb|T:32>>./makepw frogfrogfrog ab abi219G9lnw4E
Note that crypt only keeps the first two characters of the salt and ignores more than eight characters of the passwd field. Presumably if you have replaced the standard DES crypt with an MD5 version, it will do better than this, but when I wrote this little code snippet I didn't have the MD5 version installed. I still don't. (IMHO) Most crack attempts succeed not because of the weakness of the DES encryption but rather because of the stupidity of users in choosing dumb passwd's that are easy to crack. At some point in the not too distant future, of course, we may all need to use MD5 (or any really slow and painful variant of crypt) just to slow down the encyption to the point where crack cannot exhaustively search all letter permutations, but this was not the point of my posting the code snippet -- I was just trying to illustrate the use of crypt in a practical frame.
Anyway, I humbly submit below a cleaned up version of the makepw program that uses strncpy instead of sprintf and no longer has the truncation. Since I don't have an MD5 crypt man page handy, I have no idea what the maximum buffer lengths are that it will tolerate for passwd and salt, but obviously if you do have that version of crypt you can read the man pages and adjust the MAXPW and MAXSALT (which are vast overkill anyway, in all probability, unless you like pass phrases and not pass words) to whatever it likes.
rgb
Robert G. Brown http://www.phy.duke.edu/~rgb/ Duke University Dept. of Physics, Box 90305 Durham, N.C. 27708-0305 Phone: 1-919-660-2567 Fax: 919-660-2525 email:rgb@phy.duke.edu
/* %< Snip snip snip ======================================== */ #include <stdio.h> #include <stdlib.h>
static char rcs_id[]="$Id: makepw.c,v 1.3 1999/08/06 03:51:06 rgb Exp $ (Robert G. Brown)";
char *crypt(); #define MAXPW 128 #define MAXSALT 128
main(int argc, char **argv) { char *s,passwd[MAXPW],salt[MAXSALT];
if(argc != 3) { fprintf(stderr, "usage: makepw passwd salt\n"); exit(1); } /* * Get the passwd field. Only the first eight characters matter to * the standard DES crypt() routine. */ argv++; strncpy(passwd,*argv,MAXPW); /* * Get the salt. Only the first two characters matter to the standard * DES crypt() routine, and will be the first two characters of the * output encrypted string s. */ argv++; strncpy(salt,*argv,MAXSALT); /* * Make the passwd and print it out. */ s=crypt(passwd,salt); printf("%s\n",s); exit(0);
}
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |