I'd like to thank Chris Samuel and Peter Grandi for all their help in beta-testing early versions of Crack, and in Peter's case especially, for dropping me into the deep end of troff. Die, you bastard. As for Chris's major contribution, see "Scripts/plaster". 8-> For the v3.? versions of Crack, I'd like to thank Chris Myers, Randal Schwartz, Chris Lewis, and M.Maclaren. Also Brian Tompsett, for pointing me at the now infamous v3.2 bug, and for suggestions, patches, and enormous amounts of debugging information. To him should go the prize for "Most Vociferous Beta Tester Ever". For Crack v4.1, the greatest help has come from the members of the crack beta team, the most vociferous of whom are: brown@gov.llnl.ocelot, cavanaug@edu.uiuc.cogsci.lees, csx040@uk.ac.coventry.cch, dor@acl.lanl.gov, dowling@gov.ncifcrf, glad@daimi.aau.dk, kint@engr.washington.edu, korz@edu.columbia.cs.bach, morgan@edu.uky.engr, mycroft@edu.mit.ai.gnu, nelsonm@edu.orst.cs.storm, nestey@edu.colorado.denver.copper, nigelm@uk.ac.york.ohm, pcl@uk.ac.oxford.convex, phil@com.sequent, phill@com.sequent, pkh@uk.ac.nott.cs, sck@com.ibm.watson, shabby@edu.purdue.cc.mentor - especially Fred "Mr Statistics" Korz, Paul Leyland, and shabby@purdue for all the debugging info. Also a bit thanks to Michael Glad for being so helpful while we were writing a decent software interface between Crack and UFC. I also wish to acknowledge the help of Kent Landfield (moderator of comp.sources.misc) and Dan "COPS" Farmer, both of them for goading me into releasing a version of Crack with fcrypt() installed. Without them, I probably would have been too timid... Finally, my gratitude goes to my girlfriend Gilly, for her support during the bad times. You are the everything. -- INET: aem@aber.ac.uk JANET: aem@uk.ac.aber BITNET: aem%aber@ukacrl UUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk Alec Muffett, Somewhere in the UK, Probably lying under a tree drinking cider ********************************************************************** Several people have asked me why I don't write Crack so that it distributes dictionaries over the network and hacks the same password file on each machine, as opposed to spreading users over the network and using the same dictionaries. There are several reasons for this, which I will outline. The reasoning that spreading the dictionaries over the network is faster is correct in the case of cracking the passwords of ONE user - it is most efficient to run different dictionaries on him on several machines, and you will break his password eventually. Scaling this by a factor of 'n' users causes problems. Firstly, if a machine guesses one persons password, it must inform all others on the network not to waste time cracking him, but to get on with the other users. This is difficult and nasty. Secondly, it is not what Crack was designed to do. The name "Crack" is actually a misnomer - Crack really ought to be called "Passwdcheck" or something similar, but such names lack sex appeal. Crack is not a program designed to break the password of every user in the file. Rather, it is designed to find weak passwords in the file, by attacking those sorts of bad passwords which are most likely to be used, in the order in which they would most easily be found (ie: are most likely to be used by a moronic user). Crack is not designed to break user passwords; it is designed to break password files. This is a subtle but important distinction. If you want to break into a safe, you do not take a hammer at every bit of it in turn; instead, first you try some simple combinations, then you try blowing the hinges off, then you get out an acetylene torch and go for the bolt. If that doesnt work, THEN you start on the walls. You go for the bits which are most likely to be weak first. Consider a password file with 'n' users in it. Say that your ordinary, serial password cracker (eg: the one supplied with COPS) has a dictionary of 1000 words, and tries each word 6 ways (upper/lower/mixed case, permuted with forwards/backwards) Also consider that out of that 1000 users, only one (the last one) has a guessable password - "fred". Also say that it takes time 'T' seconds to encrypt a word. If you use the "try each user in turn" method, like the COPS password cracker, you will have to wait for a time:- 999 users * 1000 words * 6 ways * T = 5,994,000 T seconds before you get to that last user. Spreading this load around on a network only alleviates the number of words to be searched (divides them by the number of machines you are working on). Thus, if you use 10 machines, the machine which will guess "fred" will get to that last user in:- 999 * (1000 / 10) * 6 ways = 599,400 T seconds. Alternatively you can try it the Crack way - "fred" is a word which appears in a forwards dictionary. You will only wait:- 999 users * 1000 words * 1st way * T = 999,000 T seconds to get to that user. Now split the users across 10 machines (for simplicity, as outlined above):- (999 / 10) users * 1000 words * 1st way = 99,900 T seconds To get to his password, in ONLY 17% of the time taken by networking using the serial cracking method. This is only a boundary case, but I hope I have illustrated the concept. ********************************************************************** Crack has several other optimisations because of its structured password guesses. The figures below are entirely empirical, but I reckon that they're as good as any: The first pass that Crack makes is over the user data user information gleaned from the users' password field. In my test file, this gets about 4% of the passwords (out of a total of 15% guessed). This pass also completes very quickly, working as it does from a very small amount of data, but one which is very frequently used for passwords. The first sweep of the second pass, consisting of lowercase dictionary words, gets about another 5% of the passwords. The length of the first sweep depends on how much CPU and how many dictionaries I supply, but using the Ultrix /usr/dict/words and my bad_pws.dat, over 4 CPUs, it doesn't take much more that a few hours. For the further sweeps, the percentages cracked per sweep tail off, 2%, 1%, 0.5%... But they are the people with fairly exotic passwords, and it's only common sense that that they will take some time to crack. ********************************************************************** There is another major optimisation that I haven't mentioned. Because of the way the UNIX crypt() algorithm works, each encryption is "salted" with a two letter sequence which is stored as the first two characters of the encrypted password. This salting means that the word "fred" can be encrypted and appear in a password file in (literally) thousands of different ways - so long as each encryption has a different salt. Hence, it makes sense to do things in this manner: 1) sort and group the input data by encryption salt. 2) for each different groups' encryption salt * get a dictionary word * encrypt it using that salt (This is the time consuming bit) * compare the encryption with each member of the group with that salt * if it matches, you have guessed that users password. This knocks (empirical guesswork time again) up to one third of the dictionary encryptions off - thus saving you 0.3 of the time all the dictionary sweeps would ordinarily take. Crack gives this statistic when it says pwc: Loaded 'n' password entries into 'm' salted lines. (x%) where 'x' is the percentage of the total passwords loaded which have different salts. ********************************************************************** Some people have asked me how to generate safe passwords. This, has become a religious issue, and there are now several vociferous "password geeks" on USENET, who will say "my method is the best", in the same way that some mathematicians will try to compare so-called "random number generating algorithms". Such statements are pointless. I'm sorry for adding to the confusion, but I must say that I think they are wrong. Okay, so I am a security fatalist and a security philosopher, but I am not going to give and hard and fast answers; rather, I'd like to make some points and recommendations to the people out there. Security isn't a tangible thing, it is applied psychology. The whole point of a password is to prevent people accessing your system, getting into it from outside. Once someone is inside your system, assuming that they have the relevant knowledge of your O/S, it is safest to assume that anyone can get to be 'superuser'. Your only security once someone is on your system is called "security by obscurity". If your user has sufficient knowledge, you've "had it". The question isn't "How secure can my system be made?". The question really should be, "How much do I care, how much can I trust?". A system can be perfectly secure without any passwords at all, so long as it is in an environment of people who recognise its purpose and depend on it. I say this after having had acounts on several 'public' machines, which could have been taken to bits by any competent Unix person, but were largely safe - because when someone worked out who did anything nasty, the culprit was ostracised from the community. There _is_ a caveat to this, however. The problem is the sort of people who go around the world 'collecting' computer accounts and breaking machines, those who have either a childish mentality or an ulterior motive. The former are like the little boys who go around breaking windows and vandalising things 'for kicks'. They are the ones who see every password file as a "NO ENTRY" sign, and therefore, driven by what they think is anarchy and fun, they break in and smash the place up. Tell them that they are behaving like children, and they will behave moreso. The latter are driven by personal motives or money. Their reasons are too complex for me to analyse here. The 'babyish' hackers need a lesson (which I hope that eventually they learn) that true anarchy is for the general good, and is best achieved by fiat amongst the community. USENET is a good example - there is a lot of petty bickering and arguing, but an incredible amount of good comes out of it. It is anarchy that the greek philosophers would have approved of. What I am trying to say is that, when I say that if someone gets into your system, you've "had it", you should consider whether there is anything to have "had" in the first place. There is no point in getting yourself paranoid over security - if you do, you'll lose out. Don't be too paranoid. Be SENSIBLE instead, and secure your system according to it's needs, and not according to some 'holy bible' of absolute security. If someone gets into your system, you find out how they did it, patch the hole, check for back doors, brush yourself off, and start again. It's not the end of the world. What this statement doesn't address (yet) is the needs of system managers who have a REAL need for security - be it corporate data or research work - on their system. As I have said before, most O/S's have gaping holes in them that cannot be entirely filled, and so the crackers must be stopped on the doorstep. At the password login. People who say that they have a way of generating safe passwords are misinformed, IMHO. Saying that the password "wyufwqpl" is secure is as meaningful as saying that the number "4" is random. Password security, like any other form of computer security, is not absolute, but should be taken in context. You can't say that a certain method will provide secure, random passwords, because, in defining an algorithm to create these passwords, you will use only a subset of all the possible passwords that could ever exist. You have shrunk the 'search space' for the passwords. Someone merely has to write a password cracker which will search this small subset of passwords, in order to break your system. Passwords generated by any algorithm, human or computer based, are merly pseudo-secure, in the same way that numbers can be pseudo-random. For illustration of this aspect of password security, read the document "Password Security, A Case History" by Morris and Thompson. There is an incredibly large set of possible passwords in the world, and the best approach toward choosing a password is not to try to find a way to generate 'secure' passwords - there are no such things - but rather you should learn to choose passwords which are not easily searched for. Passwords which are out of the 'search space' of most password crackers like 'Crack'. Read the Crack documentation. See what sort of things other programs like Crack would search for. Think of some yourself. I am not going to specifically mention methods, you should really work something out for yourself. At the bottom line, the password "fred" is just as secure (random) as the password "blurflpox"; the only problem is that "fred" is in a more easily searched part of the "password space". Both of these passwords are more easily found than "Dxk&2+15^N" however. Now you must ask yourself if you can cope with remembering "Dxk&2+15^N". ********************************************************************** Some time ago, I was listening to the REM album 'Green' on the way back from the Cropredy folk festival, whilst thinking over things to do to Crack, and I was struck (not for the first time) by the words of the first verse to 'World Leader Pretend':- I sit at my table, and wage war upon myself. It seems like it's all, it's all for nothing. I know the barricades, and I know the mortar in the wall I recognise the weapons, I use them well. This is my mistake, let me make it good, I raised the wall, and I will be the one to knock it down... - writing password cracking programs gets to you after a bit.