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.
