home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume28
/
crack
/
part04
< prev
next >
Wrap
Internet Message Format
|
1992-03-19
|
57KB
From: aem@aber.ac.uk (Alec David Muffett)
Newsgroups: comp.sources.misc
Subject: v28i113: crack - The Unix Password Cracker, version 4.1, Part04/05
Message-ID: <1992Mar18.143916.24004@aber.ac.uk>
Date: 18 Mar 92 14:39:16 GMT
Approved: aem@aber.ac.uk
X-Md4-Signature: fd21f3ae9fb0b5b97354f85f58cce3dc
Submitted-by: aem@aber.ac.uk (Alec David Muffett)
Posting-number: Volume 28, Issue 113
Archive-name: crack/part04
Environment: UNIX
Supersedes: crack: Volume 25, Issue 5-9
#! /bin/sh
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 5)."
# Contents: Docs/readme.ms Sources/crack-fcrypt.c
# Wrapped by aem@aberfa on Wed Mar 18 14:08:37 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Docs/readme.ms' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Docs/readme.ms'\"
else
echo shar: Extracting \"'Docs/readme.ms'\" \(28998 characters\)
sed "s/^X//" >'Docs/readme.ms' <<'END_OF_FILE'
X.de C
X.ie n .B "\\$1" \\$2
X.el .CW "\\$1" \\$2
X..
X.TL
X"Crack Version 4.1"
X.br
XA Sensible Password Checker for Unix
X.AU
XAlec D.E. Muffett
X.AI
XUnix Software Engineer
XAberystwyth, Wales, UK
X.I "(aem@aber.ac.uk or alec_muffett@hicom.lut.ac.uk)"
X.AB
X.B Crack
Xis a freely available program designed to find standard Unix
Xeight-character DES encrypted passwords by standard guessing techniques
Xoutlined below. It is written to be flexible, configurable and fast,
Xand to be able to make use of several networked hosts via the Berkeley
X.C rsh
Xprogram (or similar), where possible.
X.AE
X.NH 1
XStatement of Intent
X.LP
XThis package is meant as a proving device to aid the construction of
Xsecure computer systems. Users of Crack are advised that they may get
Xseverly hassled by authoritarian type sysadmin dudes if they run Crack
Xwithout proper authorisation.
X.NH 1
XIntroduction to Version 4.0
X.LP
XCrack is now into it's fourth version, and has been reworked extensively
Xto provide extra functionality, and the purpose of this release is to
Xconsolidate as much of this new functionality into as small a package as
Xpossible. To this end, Crack may appear to be less configurable: it has
Xbeen written on the assumption that you run a fairly modern Unix, one
Xwith BSD functionality, and then patched in order to run on other
Xsystems.
X.LP
XThis, surprisingly enough, has led to neater code, and has made possible
Xthe introduction of greater flexibility which supercedes many of the
Xoptions that could be configured in earlier versions of Crack. In the
Xsame vein, some of the older options are now mandatory. These, such as
X.I "feedback mode"
Xand
X.C CRACK_PRINTOUT
Xare no longer supported as options and probably never will be again.
XThere is just a lot of wastage in not running with them, and too many
Xdependencies in other functions to bother programming around them.
X.LP
XThe user interface is basically identical to the previous versions,
Xalthough some people have asked about providing X-windows GUI's to
XCrack, I think it would be a waste of time to do so. Crack has far
Xless options than your ordinary version of
X.C /bin/ls .
X.NH 1
XIntroduction to Version 4.1
X.LP
XVersion 4.1 of the Crack program is an attempt to extend the features
Xintroduced in v4.0 and provide hooks for external libraries such as
XMichael Glad's wonderful
X.B UFC
Xcrypt() implementation, which (on some platforms) can outperform my
Xfcrypt() by a factor of 3. I have also been burdened with the task of
Xmaking Crack's memory handling bombproof (hah!) in the vague hope that
Xit will survive running out of memory on small machines.\**
X.FS
X- or even on large ones. Brian Tompsett at Hull tweaked Crack v3.3
Xuntil it could run to completion after filling the swapspace on each of a
Xnetwork of SparcStation2's. Due to restructuring work on v4.0, I have
Xhad to write my own sorting algorithm & re-implement all of his tweaks
Xfrom scratch, and can only hope that I have emulated the bombproofness
Xof this desirable (?) functionality.
X.FE
X.LP
XThe extensions that I mention above regard the addition of extra
Xprimitives to the dictionary processing language which permit the
Xproduction of more concise dictionaries containing words, more of which
Xare likely to be passwords. The idea is to gain efficiency by removing
Xsome of the dross from the generated dictionaries.
X.LP
XCrack should (generally) be more disk-space efficient now that the
Xprogram can spot dictionaries which have been compressed using
X.I compress
Xor
X.I pack
Xand will uncompress them on the fly as necessary (using
X.I zcat
Xor
X.I pcat
Xrespectively).\**
X.FS
XNote to people who are short on memory or swap: do remember that to do
Xthis Crack will have to
X.I fork()
X(via
X.I popen() )
Xand might not be able to create the uncompressing process. Hence, if
Xyou intend to swaplock your machine, don't compress the dictionaries.
XSwitch this off by editing the
X.C Crack
Xshellscript.
X.FE
X.NH 1
XCrack Methodology - Part 1: Internals
X.LP
XCrack takes as its input a series of password files and source
Xdictionaries. It merges the dictionaries, turns the password files into
Xa sorted list, and generates lists of possible passwords from the merged
Xdictionary or from information gleaned about users from the password
Xfile.
XIt does
X.B not
Xattempt to remedy the problem of allowing users to have guessable
Xpasswords, and it should
X.B NOT
Xbe used in place of getting a really good, secure
X.C passwd
Xprogram replacement.\**
X.FS
XSee the end of ths document for more information about
X.I passwd
Xreplacements.
X.FE
X.LP
XThe above paragraphs define the purpose of Crack, and embody a great
Xdeal of hard work, screams of
X.I Eureka! ,
Xdrunkeness, and a fair amount of swearing too. There is a lot
Xof thinking, philosophy, and empirical guesswork behind the way that
XCrack attacks password files, and although it is not perfect, I
Xcertainly hope that Crack will out-do most of it's competitors.
X.LP
XCrack works by making many individual passes over the password entries
Xthat you supply to it. Each pass generates password guesses based upon
Xa sequence of rules, supplied to the program by the
Xuser. The rules are specified in a simplistic language in the files
X.C gecos.rules
Xand
X.C dicts.rules ,
Xto be found in the
X.C Scripts
Xdirectory.
XThe distinction between these two files will be made clear later.
X.LP
XThe rules are written as a simple string of characters, with one rule to
Xa line. Blank lines, and comment lines beginning with a hash character
X.B #
Xare ignored. Trailing whitespace is also ignored. The instructions in
Xthe rule are followed from left to right, and are applied to the
Xdictionary words one by one, as the words are loaded. Some simple
Xpattern matching primitives are provided for selection purposes, so that
Xif the dictionary word does not match the pattern, it is ignored. This
Xsaves on time and memory. Before carrying on, I suggest that you browse
Xthrough
X.C Scripts/dicts.rules ,
Xtake a look at the rules supplied as defaults, and try to work out what
Xthey do.
X.LP
XThe rules are stored in two different files for two different purposes.
XRules in
X.C Scripts/gecos.rules
Xare applied to data generated by Crack from the pw_gecos and pw_gecos
Xentries of the user's password entry. The data fed to the gecos rules
Xfor the user
X.I "aem",
Xwho is
X.I "Alec David Muffett, Systems"
Xwould be:
X.I "aem",
X.I "Alec",
X.I "David",
X.I "Muffett",
X.I "Systems",
Xand a series of permutations of those words, either re-ordering the
Xwords and joining them together (eg:
X.I "AlecMuffett" ),
Xor making up new words based on initial letters of one word taken with
Xthe rest of another (eg:
X.I "AMuffett" ).\**
X.FS
X- and
X.I ASystems
Xand
X.I DSystems ,
Xand
X.I MSystems ,
Xetc... because Crack does not differentiate. Hence, care should be
Xtaken to check for redundancy when adding new rules, so as not to waste
Xtime during the gecos pass.
X.FE
X.LP
XThe entire set of rules in gecos.rules is applied to each of these
Xwords, which creates many more permutations and combinations, all of
Xwhich are tested. Hence testing the password gecos information under
XCrack v4.0 and upwards takes somewhat longer than previously, but it is
Xfar more thorough.
X.sp 1v
X.LP
XAfter a pass has been made over the data based on gecos information,
XCrack makes further passes over the password data using successive rules
Xfrom the
X.C Scripts/dicts.rules
Xby loading the whole of
X.C Dicts/bigdict
Xfile into memory, with the rule being applied to each word from that
Xfile. This generates a
X.I "resident dictionary" ,
Xwhich is sorted and uniqued so as to prevent wasting time on repetition.
XAfter each pass is completed, the memory used by the resident dictionary
Xis freed up, and (hopefully) re-used when the next dictionary is loaded.
X.LP
XThe
X.C Dicts/bigdict
Xdictionary is created by Crack by merging, sorting, and uniq'ing the
Xsource dictionaries, which are to be found in the directory
X.C DictSrc
Xand which may also be named in the Crack shellscript, via the
X.C $STDDICT
Xvariable. (The default value of $STDDICT is
X.C /usr/dict/words ).
X.LP
XThe file
X.C DictSrc/bad_pws.dat
Xis a dictionary which is meant to provide many of those common but
Xnon-dictionary passwords, such as
X.I 12345678
Xor
X.I qwerty .
X.LP
XIf you wish to provide a dictionary of your own, just copy it into the
X.C DictSrc
Xdirectory (use
X.C compress
Xon it if you wish to save space; Crack will unpack it whilst generating
Xthe big dictionary) and then delete the contents of the
X.C Dicts
Xdirectory by running
X.C Scripts/spotless .
XYour new dictionary will be merged in on the next run. For more
Xinformation on dictionary attacks, see the
X.I excellent
Xpaper called "Foiling the Cracker: A Survey of, and Improvements to,
XPassword Security" by Daniel Klein, available from
X.I "ftp.sei.cmu.edu"
Xin
X.I "~/pub/dvk/passwd.*" .
XAlso, please read the
X.C APPENDIX
Xfile supplied with this distribution.\**
X.FS
XExtra dictionaries (those detailed in Dan Klein's paper) can be
Xobtained via anonymous FTP from
X.I ftp.uu.net
X(137.39.1.9) as
X.I ~/pub/dictionaries.tar.Z ;
Xor check an
X.I Archie
Xdatabase for other possible sources of dictionaries.
X.FE
X.LP
XHaving described the method of cracking, perhaps we should now
Xinvestigate the algorithm used to overlay the cracking mechanism.
X.NH 1
XCrack Methodology - Part 2: Feedback Filters
X.LP
XAs is stated above, Crack permutes and loads dictionaries directly
Xinto memory, sorts and uniques them, before attempting to use each of
Xthe words as a guess for each users' password. If Crack correctly
Xguesses a password, it marks the user as
X.I done
Xand does not waste
Xfurther time on trying to break that users password.
X.LP
XOnce Crack has finished a dictionary pass, it sweeps the list of users
Xlooking for the passwords it has cracked. It stores the cracked passwords
Xin both plaintext and encrypted forms in a
X.I "feedback file"
Xin the directory
X.C Runtime .
XFeedback files have names of the form
X.C Runtime/F* .
X.LP
XThe purpose of this is so that, when Crack is next invoked, it may
Xrecognise passwords that it has successfully cracked before, and filter
Xthem from the input to the password cracker. This provides an
X.I instant
Xlist of crackable users who have not changed their passwords since the
Xlast time Crack was run. This list appears in a file with name
X.C out*
Xin the
X.C $CRACK_OUT
Xdirectory, or on
X.I stdout ,
Xif foreground mode is invoked (see
X.I Options ,
Xbelow).
X.LP
XIn a similar vein, when a Crack run terminates normally, it writes out
Xto the feedback file all encrypted passwords that it has
X.B NOT
Xsucceeded in cracking. Crack will then ignore all of these passwords
Xnext time you run it.
X.LP
XObviously, this is not desirable if you frequently change your
Xdictionaries or rules, and so there is a script provided,
X.C Scripts/mrgfbk
Xwhich sorts your feedback files, merges them into one, and optionally
Xremoves all traces of 'uncrackable' passwords, so that your next Crack
Xrun can have a go at passwords it has not succeeded in breaking before.
X.LP
X.C Mrgfbk
Xis invoked automatically if you run
X.C Scripts/spotless .
X.NH 1
XCrack Methodology - Part 3: Execution and Networking
X.LP
XEach time Crack is invoked, whether networked or not, it generates a
X.I diefile
Xwith a name of the form
X.C Runtime/D*
X(for network cracks, this file is generated by RCrack, and is of the form
X.C Runtime/DR*
Xwhich points to a
X.B real
Xdiefile, named
X.C Runtime/RD*
X- see below for details).
X.LP
XThese diefiles contain debugging information about the job, and are
Xgenerated so that all the jobs on the entire network can be called
Xquickly by invoking
X.C Scripts/plaster .
XDiefiles delete themselves after they have been run.
X.LP
XAs you will read in the sections below, Crack has a
X.C "-network"
Xoption: This is designed to be a simple method of automatically
Xspreading the load of password cracking out over several machines on a
Xnetwork, preferably if they are connected by some form of networked
Xfilestore.
X.LP
XWhen
X.C "Crack -network"
Xis invoked, it filters its input in the ordinary way, and then splits
Xits load up amongst several machines which are specified in the file
X.C Scripts/network.conf .
X.LP
XThis file contains a series of hostnames, power ratings, flags, etc,
Xrelevant to the running of Crack on each machine. Crack then calls
X.C Scripts/RCrack
Xto use the
X.C rsh
Xcommand (or similar) to invoke Crack on the other hosts. See the RCrack
Xscript, and the example network.conf file for details.
X.NH 1
XInstallation
X.LP
XCrack is one of those most unusual of beasties, a self-installing
Xprogram. Some people have complained about this apparent weirdness, but
Xit has grown up with Crack ever since the earliest network version, when
XI could not be bothered to log into several different machines with
Xseveral different architectures, just in order to build the binaries.
XOnce the necessary configuration options have been set, the executables
Xare created via
X.C make
Xby running the Crack shellscript .
X.LP
XCrack's configuration lies in two files, the
X.C Crack
Xshell script, which contains all the installation specific configuration
Xdata, and the file
X.C Sources/conf.h ,
Xwhich contains configuration options specific to various binary platforms.
X.LP
XIn the Crack shellscript, you will have to edit the
X.C CRACK_HOME
Xvariable to the correct value. This variable should be set to an
Xabsolute path name (names relative to
X.I ~username
Xare OK, so long as you have some sort of
X.C csh )
Xthrough which the directory containing Crack may be accessed on
X.B ALL
Xthe machines that Crack will be run on. There is a similar variable
X.C CRACK_OUT
Xwhich specifies where Crack should put its output files - by default,
Xthis is the same as
X.C "$CRACK_HOME" .
X.LP
XYou will also have to edit the file
X.C Sources/conf.h
Xand work out which switches to enable. Each
X.C #define
Xhas a small note explaining its purpose. Where I have been in doubt about
Xthe portability of certain library functions, usually I have re-written
Xit, so you should be OK. Let me know of your problems, if you have any.
X.LP
XIf you will be using
X.C "Crack -network"
Xyou will then have to generate a
X.C Scripts/network.conf
Xfile. This contains a list of hostnames to
X.C rsh
Xto, what their
X.I "binary type"
Xis (useful when running a network Crack on several different
Xarchitectures), a guesstimate of their
X.I "relative power"
X(take your slowest machine as unary, and measure all others relative to
Xit), and a list of per-host
X.I flags
Xto
X.B add
Xto those specified on the
X.C Crack
Xcommand line, when calling that host. There is an example of such a
Xfile provided in the Scripts directory - take a look at it.
X.LP
XIf ever you wish to specify a more precise figure as to the relative
Xpower of your machines, or you are simply at a loss, play with the
Xcommand
X.C "make tests"
Xin the source code directory. This can provide you with the number of
Xfcrypt()s that your machine can do per second, which is a number that
Xyou can plug into your
X.C network.conf
Xas a measure of your machines' power (after rounding the value to an
Xinteger).
X.NH 1
XUsage
X.LP
XOkay, so, let's assume that you have edited your
X.C Crack
Xscript, and your
X.C Sources/conf.h
Xfile, where do you go from here ?
X.LP
X.DS B
X.fi
X.C Crack
X[\c
X.I options ]
X[\c
X.I bindir ]
X.C /etc/passwd
X[...other passwd files]
X.sp 1v
X.C "Crack -network"
X[\c
X.I options ]
X.C /etc/passwd
X[...other passwd files]
X.DE
X.LP
XWhere
X.B bindir
Xis the optional name of the directory where you want the binaries
Xinstalled. This is useful where you want to be able to run versions of
XCrack on several different architectures. If
X.B bindir
Xdoes not exist, a warning will be issued, and the directory created.
X.QP
XNote:
X.B bindir
Xdefaults to the name
X.C generic
Xif not supplied.
X.QP
X.LP
X.B "Notes for Yellow Pages (NIS) Users:"
XI have occasional queries about how to get Crack running from a YP
Xpassword file. There are several methods, but by far the simplest is to
Xgenerate a passwd format file by running:-
X.DS B
X.C "ypcat passwd > passwd.yp"
X.DE
Xand then running Crack on this file.
X.NH 1
XOptions
X.IP "\fB-f\fP"
XRuns Crack in
X.I foreground
Xmode, ie: the password cracker is not backgrounded, and messages appear
Xon stdout and stderr as you would expect. This option is only really
Xuseful for very small password files, or when you want to put a wrapper
Xscript around Crack.
X.IP
XForeground mode is disabled if you try running
X.C "Crack -network -f"
Xon the command line, because of the insensibility of
X.C rsh ing
Xto several machines in turn, waiting for each one to finish before
Xcalling the next. However, please read the section about
X.I "Network Cracking without NFS/RFS" ,
Xbelow.
X.IP "\fB-v\fP"
XSets verbose mode, whereby Crack will print every guess it is trying on
Xa per-user basis. This is a very quick way of flooding your filestore,
Xbut useful if you think something is going wrong.
X.IP "\fB-m\fP"
XSends mail to any user whose password you crack by invoking
X.C Scripts/nastygram
Xwith their username as an argument. The reason for using the script is
Xso that a degree of flexibility in the format of the mail message is
Xsupplied; ie: you don't have to recompile code in order to change the
Xmessage.\**
X.FS
XI'm uncertain about the wisdom of mailing someone like this. If someone
Xbrowses your cracked user's mail somehow, it's like a great big neon
Xsign pointing at the user saying "This Is A Crackable Account - Go For
XIt!". Not to mention the false sense of security it engenders in the
XSystem Manager that he's "informed" the user to change his password.
XWhat if the user doesn't log on for 3 months? However, so many people
Xhave wired it into their own versions of Crack, I suppose it
X.B must
Xbe provided... AEM
X.FE
X.IP "\fB-nvalue\fP"
XSets the process to be
X.C nice() ed
Xto
X.I value ,
Xso, for example, the switch
X.C \&-n19
Xsets the Crack process to run at the lowest priority.
X.IP "\fB-network\fP"
XThrows Crack into network mode, in which it reads the
X.C Scripts/network.conf
Xfile, splits its input into chunks which are sized according to the
Xpower of the target machine, and calls
X.C rsh
Xto run Crack on that machine. Options for Crack running on the target
Xmachine may be supplied on the command line (eg: verbose or recover
Xmode), or in the network.conf file if they pertain to specific hosts
X(eg:
X.C nice()
Xvalues).
X.IP "\fB-r<pointfile>\fP"
XThis is only for use when running in
X.I recover
Xmode. When a running Crack starts pass 2, it periodically saves its
Xstate in a
X.I pointfile ,
Xwith a name of the form
X.C "Runtime/P.*"
XThis file can be used to recover where you were should a host crash.
XSimply invoke Crack in
X.B exactly
Xthe same manner as the last time, with the addition of the
X.C "-r"
Xswitch, (eg:
X.C "-rRuntime/Pfred12345" )
Xswitch. Crack will startup and read the file, and jump to roughly where
Xit left off. If you are cracking a very large password file, this can
Xsave oodles of time after a crash.
X.IP
XIf you were running a
X.I network
XCrack, then the jobs will again be spawned onto all the machines of the
Xoriginal Crack. The program will then check that the host it is running
Xon is the same as is mentioned in the pointfile. If it is not, it will
Xquietly die. Thus, assuming that you supply the same input data and do
Xnot change your
X.C network.conf
Xfile, Crack should pick up where it left off. This is a bit inelegant,
Xbut it's better than nothing at the moment.
X.IP
XThe method of error recovery outlined above causes headaches for users
Xwho want to do multiprocessing on parallel architectures. Crack is in
Xno way parallel, and because of the way it's structured (reading stdin
Xfrom shellscript frontends) it is a pain to divide the work amongst
Xseveral processes via
X.C fork() ing.
X.IP
XThe hack solution to get several copies of Crack running on one machine
Xwith
X.I n
Xprocessors at the moment is to insert
X.I n
Xcopies of the entry for your parallel machine into the
X.C Scripts/network.conf
Xfile. If you use the
X.C \&-r
Xoption in these circumstances however, you will get
X.I n
Xcopies of the recovered process running, only one of them will have the
Xcorrect input data.
X.IP
XThe old solution to this problem (see old documentation if you are
Xinterested) has been negated by the introduction of feedback mode, so
Xthe best bet in this particular situation is to wait until the other
Xjobs are done (and have written out lists of uncrackable passwords), and
Xthen re-start the jobs from scratch. Anyone whose password was not
Xcracked on the first run will be ignored on the second, if they have not
Xchanged it since. This is inelegant, but it's the best I can do in the
Xlimited time available.
X.NH
XSupport Scripts
X.LP
XThe
X.C Scripts
Xdirectory contains a small number of support and utility scripts, some
Xof which are designed to help Crack users check their progress.
XBriefly, the most useful ones are:-
X.IP "\fBScripts/shadmrg\fP"
XThis is a small (but hopefully readable) script for merging
X.C /etc/passwd
Xand
X.C /etc/shadow
Xon System V style shadow password systems. It produces the merged data
Xto stdout, and will need redirecting into a file before Crack can work
Xon it. The script is meant to be fairly lucid, on the grounds that I
Xworry that there are many shadowing schemes out there, and perhaps not
Xall have the same data format.
X.IP
X.B "I have not"
Xwired this facility into the Crack command itself because the world does
X.B NOT
Xrevolve around System V yet, regardless of what some people would have
Xme believe, and I believe that the lack of direct support for NIS
Xoutlined above, sets a precedent. There are just too many
Xincompatibilities in shadow password schemes for me to hardwire
Xanything.
X.IP "\fBScripts/plaster\fP"
Xwhich is named after a dumb joke, but is a simple frontend to the
X.C "Runtime/D*"
Xdiefiles that each copy of the password cracker generates. Invoking
X.C Scripts/plaster
Xwill kill off all copies of the password cracker you are running, over
Xthe network or otherwise.
X.IP "\fBScripts/status\fP"
XThis script
X.C rsh es
Xto each machine mentioned in the
X.C Scripts/network.conf
Xfile, and provides some information about processes and uptime on that
Xmachine. This is useful when you want to find out just how well your
Xpassword crackers are getting on during a
X.C "Crack -network" .
X.IP "\fBScripts/{clean,spotless}\fP"
XThese are really just frontends to a makefile. Invoking
X.C Scripts/clean
Xtidies up the Crack home directory, and removes probably unwanted files,
Xbut leaves the pre-processed dictionary
X.C bigdict
Xintact.
X.C Scripts/spotless
Xdoes the same as
X.C Scripts/clean
Xbut obliterates
X.C bigdict
Xand old output files too, and compresses the feedback files into one.
X.IP "\fBScripts/nastygram\fP"
XThis is the shellscript that is invoked by the password cracker to send
Xmail to users who have guessable passwords, if the
X.C -m
Xoption is used. Edit it at your leisure to suit your system.
X.IP "\fBScripts/guess2fbk\fP"
XThis script takes your
X.C out*
Xfiles as arguments and reformats the 'Guessed' lines into a slightly
Xmessy
X.I feedback
Xfile, suitable for storing with the others.
X.IP
XAn occasion where this might be useful is when your cracker has guessed
Xmany peoples passwords, and then died for some reason (a crash?) before
Xwriting out the guesses to a feedback file. Running
X.DS B
X.C "Scripts/guess2fbk out* >> Runtime/F.new"
X.DE
Xwill save the work that has been done.
X.NH 1
XNetwork Cracking without NFS/RFS
X.LP
XFor those users who have some form of
X.C rsh
Xcommand, but do not have a a networked filestore running between hosts,
Xthere is now a solution which will allow you to do networked cracking,
Xproposed to me by Brian Tompsett at Hull. Personally, I consider the
Xidea to be potty, but it fills in missing functionality in a wonderfully
Xtacky manner.
X.LP
XFrom the documentation above, you will note that Crack will undo the
X.C "-f"
X.I "(output in foreground)"
Xoption, if it is invoked with the
X.C "-network"
Xswitch at the same time (see the
X.I Options
Xsection above). This is true, but it does not apply if you specify
X.C "-f"
Xoption in the
X.C network.conf
Xfile.
X.LP
XThe practical upshot of doing this is that remote copies of Crack
Xcan be made to read from
X.I stdin
Xand write to
X.I stdout
Xover a network link, and thus remote processing is accomplished. I have
Xtweaked Crack in such a way, therefore, that if the
X.C "-f"
Xoption is specified amongst the crack-flags of a host in the
Xnetwork.conf, rather than backgrounding itself on the remote host, the
X.C rsh
Xcommand on the
X.B server
Xis backgrounded, and output is written directly to the files on the
Xserver's filestore.
X.LP
XThere are restrictions upon this method, mostly involving the number of
Xprocesses that a user may run on the server at any one time, and that
Xyou will have to collect feedback output together manually (dropping it
Xinto the
X.C Runtime
Xdirectory on the server). However, it works. Also, if you try to use
X.C rsh
Xas another user, you will suffer problems if
X.C rsh
Xinsists on reading something from your terminal (eg: a password for the
Xremote account). Also, recovering using checkpointing goes out the
Xwindow unless you specify the name of the pointfile as it is named
Xon the remote machine.
X.NH 1
XUFC Support and notes on fast crypt() implementations
X.LP
XThe stdlib version of the
X.C crypt()
Xsubroutine is incredibly slow. It is a
X.I massive
Xbottleneck to the execution of Crack and on typical platforms that you
Xget at universities, it is rare to find a machine which will achieve
Xmore than 50 standard crypt() s per second. On low-end diskless
Xworkstations, you may expect 2 or 3 per second. It was this slowness of
Xthe crypt() algorithm which originally supplied much of the security
XUnix needed.\**
X.FS
XSee: "Password Security, A Case History" by Bob Morris & Ken Thomson, in
Xthe Unix Programmer Docs.
X.FE
X.LP
XThere are now
X.B many
Ximplementations of faster versions of crypt()
Xto be found on the network. The one supplied with Crack v3.2 and
Xupwards is called
X.C fcrypt() .
XIt was originally written in May 1986 by Robert Baldwin at MIT, and is a
Xgood version of the crypt() subroutine. I received a copy from Icarus
XSparry at Bath University, who had made a couple of portability
Xenhancements to the code.
X.LP
XI rewrote most of the tables and the KeySchedule generating algorithm in
Xthe original
X.I fdes-init.c
Xto knock 40% off the execution overhead of fcrypt() in the form that it
Xwas shipped to me. I inlined a bunch of stuff, put it into a single
Xfile, got some advice from Matt Bishop and Bob Baldwin [both of whom I
Xam greatly indebted to] about what to do to the
X.C xform()
Xroutine and to the fcrypt function itself, and tidied up some
Xalgorithms. I have also added more lookup tables and reduced several
Xformula for faster use. Fcrypt() is now barely recognisable as being
Xbased on its former incarnation, and it is 3x faster.
X.LP
XOn a DecStation 5000/200, fcrypt() is about 16 times faster than the
Xstandard crypt (your mileage may vary with other architectures and
Xcompilers). This speed puts fcrypt() into the "moderately fast" league
Xof crypt implementations.
X.LP
XAmongst other crypt implementations available is
X.B UFC
Xby Michael Glad. UFC-crypt is a version of the crypt subroutine which
Xis optimised for machines with 32-bit long integers and generally
Xoutperforms my fcrypt() by a factor of between 1 and 3, for a tradeoff
Xof large memory usage, and memory-cache unfriendliness. Hooks for even
Xmore optimised assembler versions of crypt() are also provided for some
Xplatforms (Sun, HP, ...). Getting UFC to work on 16 bit architectures
Xis nearly impossible.
X.LP
XHowever, on most architectures, UFC generates a stunning increase in the
Xpower of Crack, and so, from v4.1 onwards, Crack is written to
Xautomatically make use of UFC if it can find it. All that you have to
Xdo is to obtain a suitable copy of UFC (preferably a version which
Xmentions that it is compatible with
X.C "Crack v4.1" ,
Xand unpack it into a directory called
X.C ufc-crypt
Xin
X.C $CRACK_HOME ,
Xand then delete your old binaries. UFC will then be detected, compiled,
Xtested and used in preference to fcrypt() by the Crack program, wherever
Xpossible.
X.NH 1
XConclusions
X.LP
XWhat can be done about brute force attacks on your password file ?
X.LP
XYou must get a drop-in replacement for the
X.C passwd
Xand
X.C yppasswd
Xcommands; one which will stop people from choosing bad passwords in the
Xfirst place. There are several programs to do this; Matt Bishop's
X.C "passwd+"
Xand Clyde Hoover's
X.C "npasswd"
Xprogram are good examples which are freely available. Consult an
X.B Archie
Xdatabase for more details on where you can get them from.
X.LP
XIt would be nice if an organisation (such as
X.B CERT ?)
Xcould be persuaded to supply skeletons of
X.I sensible
Xpasswd commands for the public good, as well as an archive of security
Xrelated utilities\**
Xon top of the excellent
X.C COPS .
X.FS
X.C COPS
Xis available for anonymous FTP from
X.I "cert.sei.cmu.edu"
X(128.237.253.5) in
X.I ~/cops
X.FE
XHowever, for Unix security to improve on a global scale, we will also
Xrequire pressure on the vendors, so that programs are written correctly
Xfrom the beginning.
END_OF_FILE
if test 28998 -ne `wc -c <'Docs/readme.ms'`; then
echo shar: \"'Docs/readme.ms'\" unpacked with wrong size!
fi
# end of 'Docs/readme.ms'
fi
if test -f 'Sources/crack-fcrypt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Sources/crack-fcrypt.c'\"
else
echo shar: Extracting \"'Sources/crack-fcrypt.c'\" \(24546 characters\)
sed "s/^X//" >'Sources/crack-fcrypt.c' <<'END_OF_FILE'
X/*
X * This program is copyright Alec Muffett 1991 except for some portions of
X * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
X * and Alec Muffett. The author(s) disclaims all responsibility or liability
X * with respect to it's usage or its effect upon hardware or computer
X * systems, and maintain copyright as set out in the "LICENCE" document which
X * accompanies distributions of Crack v4.0 and upwards.
X */
X
X/*
X * Misc defs for the fast password transform optimisations.
X */
X
X#include "crack.h"
X
X#define reg register
X#define uns unsigned
X#define unsb uns char
X#define unsl uns long
X
X/*
X * Types for the different ways to represent DES bit patterns. Bits are
X * always right justified within fields. Bits which have lower indices in
X * the NBS spec are stored in the vax bits with less significance (e.g., Bit
X * 1 of NBS spec is stored in the bit with weight 2 ** 0 to the Vax.
X */
X
X#define obpb1 unsb /* One bit per byte. */
X#define sbpb6 unsb /* Six bits per byte, 6 held. */
X#define sbpb6R unsb /* Six bits per byte Reversed order, 6 held. */
X#define sbpb24 unsl /* Six bits per byte, 24 held. */
X#define ebpb24 unsl /* Eight bits per bit, 24 held. */
X#define fbpb4 unsb /* Four bits per byte, 4 held. */
X#define fbpb4R unsb /* Four bits per byte Reversed order, 4 held. */
X
X/*
X * The operation (6 * x) is often better optimised as this (for really
X * braindead compilers) - AEM
X */
X
X#ifdef BRAINDEAD6
X#define SIX_TIMES(exprn) (((exprn) << 2) + ((exprn) << 1))
X#else
X#define SIX_TIMES(exprn) (6 * (exprn))
X#endif /* BRAINDEAD6 */
X
X/* DES transformation type... */
X
Xunion SDATA
X{
X sbpb24 b[2];
X sbpb6 c[8];
X};
X#ifndef FDES_4BYTE /* Thanks to Matt Bishop for this idea -AEM. */
X#define SIZEFIX 0
X#define INDIRECT(a,b) (a)[b]
X#else
X#define SIZEFIX 2 /* "n" where 2^n == sizeof(sbpb24) */
X#define INDIRECT(a,b) (*((sbpb24 *)(((unsigned char *) a) + (b))))
X#endif
X
X/*
X * These used to be rather slow and frequently used functions - AEM
X */
X
X#define TF_TO_SIXBIT(tf) \
X (sbpb24)((tf & 077L) | \
X ((tf & 07700L) << 2) | \
X ((tf & 0770000L) << 4) | \
X ((tf & 077000000L) << 6))
X
X#define SIXBIT_TO_TF(sb) \
X (ebpb24)((sb & 0x3fL) | \
X ((sb & 0x3f00L) >> 2) | \
X ((sb & 0x3f0000L) >> 4) | \
X ((sb & 0x3f000000L) >> 6))
X
X/*
X * Data segment gathered into one place, try to keep this stuff long aligned
X * - AEM
X */
X
Xstatic char iobuf[16];
Xstatic obpb1 crypt_block[72]; /* 72 is next multiple of 8 bytes after 66 */
Xstatic sbpb24 KS[32];
Xstatic sbpb24 S0H[64], S1H[64], S2H[64], S3H[64];
Xstatic sbpb24 S4H[64], S5H[64], S6H[64], S7H[64];
Xstatic sbpb24 S0L[64], S1L[64], S2L[64], S3L[64];
Xstatic sbpb24 S4L[64], S5L[64], S6L[64], S7L[64];
Xstatic sbpb24 out96[4];
X
X/*
X * Start of the real thing
X */
X
Xvoid
Xfsetkey ()
X{
X /*
X * This used to be utterly horrendous. It still is, but it's much, much,
X * smaller... (and quite a bit faster...) - AEM
X */
X static unsb KeyToKS[] =
X {
X 9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24,
X 43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29,
X 4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30,
X 1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16,
X 35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21,
X 27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22,
X 50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0,
X 48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5,
X 11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6,
X 34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49,
X 32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52,
X 62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53,
X 18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33,
X 16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36,
X 46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37,
X 2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17,
X 0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20,
X 30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21,
X 51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1,
X 49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4,
X 14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5,
X 35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50,
X 33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19,
X 61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52,
X 56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42,
X 25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11,
X 53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44,
X 40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26,
X 9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62,
X 37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28,
X 24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10,
X 58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46,
X 21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12,
X 8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59,
X 42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30,
X 5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27,
X 57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43,
X 26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14,
X 52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11,
X 41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56,
X 10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61,
X 36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62,
X 25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40,
X 59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45,
X 20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46,
X 17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32,
X 51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37,
X 12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38
X };
X
X reg int i;
X reg unsigned long r;
X reg unsb *k;
X
X k = KeyToKS;
X
X for (i = 0; i < 32; i++)
X {
X /* 16-bit tweaks suggested by cip_maz@fb6tcp.physik.uni-paderborn.de */
X /* inlining speedup tweak suggested by tahorsley@csd.harris.com */
X /* (strange addition compensates missing TF_TO_SIXBIT) */
X r = (unsigned long) crypt_block[*(k++)];
X r |= (unsigned long) crypt_block[*(k++)] << 1;
X r |= (unsigned long) crypt_block[*(k++)] << 2;
X r |= (unsigned long) crypt_block[*(k++)] << 3;
X r |= (unsigned long) crypt_block[*(k++)] << 4;
X r |= (unsigned long) crypt_block[*(k++)] << 5;
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 6);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 7);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 8);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 9);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 10);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 11);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 12);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 13);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 14);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 15);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 16);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 17);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 18);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 19);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 20);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 21);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 22);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 23);
X KS[i] = r;
X }
X}
X
Xvoid
XXForm (saltvalue)
X sbpb24 saltvalue;
X{
X#ifdef BIG_ENDIAN /* Icarus Sparry, Bath - mod AEM */
X#define STEP --
X#define START &sdata.c[7]
X#define Dl sdata.b[1]
X#define Dh sdata.b[0]
X#else
X#ifdef LITTLE_ENDIAN
X#define STEP ++
X#define START &sdata.c[0]
X#define Dl sdata.b[0]
X#define Dh sdata.b[1]
X#endif
X /* else error */
X#endif
X union SDATA sdata;
X reg sbpb24 Rl;
X reg sbpb24 Rh;
X reg sbpb24 Ll;
X reg sbpb24 Lh;
X reg sbpb6 *dp;
X int loop;
X int kloop;
X sbpb24 *kp;
X reg sbpb24 k;
X#ifdef FDES_8BYTE
X reg sbpb24 tmpi;
X#endif /* FDES_8BYTE */
X
X Ll = Lh = Rl = Rh = 0;
X
X for (loop = 25; loop--; /* nothing */ )
X {
X kp = KS;
X for (kloop = 8; kloop--; /* nothing */ )
X {
X k = (Rl ^ Rh) & saltvalue;
X#ifndef FDES_8BYTE
X Dl = (k ^ Rl ^ *kp++) << SIZEFIX;
X Dh = (k ^ Rh ^ *kp++) << SIZEFIX;
X#else
X /* hack to make things work better - matthew kaufman */
X /* I haven't tried any of this - I don't have a cray... AEM */
X tmpi = (k ^ Rl ^ *kp++);
X sdata.c[3] = (tmpi >> 24) & 0x00ff;
X sdata.c[2] = (tmpi >> 16) & 0x00ff;
X sdata.c[1] = (tmpi >> 8) & 0x00ff;
X sdata.c[0] = (tmpi) & 0x00ff;
X tmpi = (k ^ Rh ^ *kp++);
X sdata.c[7] = (tmpi >> 24) & 0x00ff;
X sdata.c[6] = (tmpi >> 16) & 0x00ff;
X sdata.c[5] = (tmpi >> 8) & 0x00ff;
X sdata.c[4] = (tmpi) & 0x00ff;
X#endif /* FDES_8BYTE */
X
X dp = START;
X Lh ^= INDIRECT (S0H, *dp);
X Ll ^= INDIRECT (S0L, *dp STEP);
X Lh ^= INDIRECT (S1H, *dp);
X Ll ^= INDIRECT (S1L, *dp STEP);
X Lh ^= INDIRECT (S2H, *dp);
X Ll ^= INDIRECT (S2L, *dp STEP);
X Lh ^= INDIRECT (S3H, *dp);
X Ll ^= INDIRECT (S3L, *dp STEP);
X Lh ^= INDIRECT (S4H, *dp);
X Ll ^= INDIRECT (S4L, *dp STEP);
X Lh ^= INDIRECT (S5H, *dp);
X Ll ^= INDIRECT (S5L, *dp STEP);
X Lh ^= INDIRECT (S6H, *dp);
X Ll ^= INDIRECT (S6L, *dp STEP);
X Lh ^= INDIRECT (S7H, *dp);
X Ll ^= INDIRECT (S7L, *dp STEP);
X
X k = (Ll ^ Lh) & saltvalue;
X#ifndef FDES_8BYTE
X Dl = (k ^ Ll ^ *kp++) << SIZEFIX;
X Dh = (k ^ Lh ^ *kp++) << SIZEFIX;
X#else
X tmpi = (k ^ Ll ^ *kp++);
X sdata.c[3] = (tmpi >> 24) & 0x00ff;
X sdata.c[2] = (tmpi >> 16) & 0x00ff;
X sdata.c[1] = (tmpi >> 8) & 0x00ff;
X sdata.c[0] = (tmpi) & 0x00ff;
X tmpi = (k ^ Lh ^ *kp++);
X sdata.c[7] = (tmpi >> 24) & 0x00ff;
X sdata.c[6] = (tmpi >> 16) & 0x00ff;
X sdata.c[5] = (tmpi >> 8) & 0x00ff;
X sdata.c[4] = (tmpi) & 0x00ff;
X#endif /* FDES_8BYTE */
X
X dp = START;
X Rh ^= INDIRECT (S0H, *dp);
X Rl ^= INDIRECT (S0L, *dp STEP);
X Rh ^= INDIRECT (S1H, *dp);
X Rl ^= INDIRECT (S1L, *dp STEP);
X Rh ^= INDIRECT (S2H, *dp);
X Rl ^= INDIRECT (S2L, *dp STEP);
X Rh ^= INDIRECT (S3H, *dp);
X Rl ^= INDIRECT (S3L, *dp STEP);
X Rh ^= INDIRECT (S4H, *dp);
X Rl ^= INDIRECT (S4L, *dp STEP);
X Rh ^= INDIRECT (S5H, *dp);
X Rl ^= INDIRECT (S5L, *dp STEP);
X Rh ^= INDIRECT (S6H, *dp);
X Rl ^= INDIRECT (S6L, *dp STEP);
X Rh ^= INDIRECT (S7H, *dp);
X Rl ^= INDIRECT (S7L, *dp STEP);
X }
X
X Ll ^= Rl;
X Lh ^= Rh;
X Rl ^= Ll;
X Rh ^= Lh;
X Ll ^= Rl;
X Lh ^= Rh;
X }
X
X /*
X * for reasons that I cannot explain, if I insert the contents of the
X * UnXForm function right HERE, making the tweaks as necessary to avoid
X * using out96[] to pass data, I LOSE 30% of my speed. I don't know why.
X * Hence, I continue to use out96[]...
X */
X {
X reg sbpb24 *qp;
X qp = out96;
X *qp++ = Ll;
X *qp++ = Lh;
X *qp++ = Rl;
X *qp++ = Rh;
X }
X}
X
Xvoid
XUnXForm ()
X{
X reg sbpb24 Rl;
X reg sbpb24 Rh;
X reg sbpb24 Ll;
X reg sbpb24 Lh;
X reg obpb1 *ptr;
X reg long int mask;
X register long int *lip;
X
X Ll = SIXBIT_TO_TF (out96[0]);
X Lh = SIXBIT_TO_TF (out96[1]);
X Rl = SIXBIT_TO_TF (out96[2]);
X Rh = SIXBIT_TO_TF (out96[3]);
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (mask = (sizeof (crypt_block) / sizeof (long int)); mask--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X ptr = crypt_block;
X mask = 0x000400L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x400000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000400L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x400000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000200L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x200000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000200L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x200000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000100L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x100000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000100L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x100000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000080L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x080000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000080L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x080000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000010L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x010000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000010L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x010000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000008L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x008000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000008L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x008000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000004L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x004000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000004L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x004000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000002L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x002000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000002L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x002000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X}
X
Xchar *
Xfcrypt (pw, salt)
X char *pw;
X char *salt;
X{
X /* Table lookups for salts reduce fcrypt() overhead dramatically */
X static sbpb24 salt0[] =
X {
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 6, 7, 8, 9, 10, 11, 12,
X 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
X 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
X 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
X 12, 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4
X };
X static sbpb24 salt1[] =
X {
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
X 320, 384, 448, 512, 576, 640, 704, 320, 384, 448, 512, 576, 640,
X 704, 768, 832, 896, 960, 1024, 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560,
X 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
X 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
X 3904, 3968, 4032, 0, 64, 128, 192, 256, 320, 384, 448, 512, 576,
X 640, 704, 768, 832, 896, 960, 1024, 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
X 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024,
X 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256
X };
X
X /* final perutation desalting */
X static obpb1 final[] =
X {
X 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66,
X 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
X 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103,
X 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
X 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
X 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
X 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
X 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
X 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
X 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
X 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
X 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
X 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
X 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
X 247, 248, 249, 250, 251, 252, 253, 254, 255,
X /* Truncate overflow bits at 256 */
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
X 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58
X };
X
X reg int i, j, k;
X reg long int *lip;
X sbpb24 saltvalue;
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X for (i = 0; (k = *pw) && i < 64; pw++)
X {
X crypt_block[i++] = (k >> 6) & 01;
X crypt_block[i++] = (k >> 5) & 01;
X crypt_block[i++] = (k >> 4) & 01;
X crypt_block[i++] = (k >> 3) & 01;
X crypt_block[i++] = (k >> 2) & 01;
X crypt_block[i++] = (k >> 1) & 01;
X crypt_block[i++] = (k >> 0) & 01;
X i++; /* have to skip one here (parity bit) */
X }
X
X fsetkey ( /* crypt_block */ );
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X iobuf[0] = salt[0];
X iobuf[1] = salt[1];
X
X saltvalue = salt0[iobuf[0]] | salt1[iobuf[1]];
X saltvalue = TF_TO_SIXBIT (saltvalue);
X
X XForm (saltvalue);
X UnXForm ();
X
X for (i = 0; i < 11; i++)
X {
X k = 0;
X
X for (j = 0; j < 6; j++)
X {
X k = (k << 1) | crypt_block[SIX_TIMES (i) + j];
X }
X iobuf[i + 2] = final[k];
X }
X
X iobuf[i + 2] = 0;
X
X if (iobuf[1] == 0)
X {
X iobuf[1] = iobuf[0];
X }
X return (iobuf);
X}
X/********* INITIALISATION ROUTINES *********/
X
Xfbpb4
XlookupS (tableno, t6bits)
X unsl tableno;
X sbpb6R t6bits;
X{
X static fbpb4R S[8][64] =
X {
X 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
X 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
X 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
X 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
X
X 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
X 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
X 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
X 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
X
X 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
X 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
X 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
X 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
X
X 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
X 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
X 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
X 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
X
X 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
X 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
X 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
X 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
X
X 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
X 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
X 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
X 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
X
X 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
X 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
X 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
X 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
X
X 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
X 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
X 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
X 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
X };
X sbpb6 fixed6bits;
X fbpb4R r;
X fbpb4 fixedr;
X
X fixed6bits = (((t6bits >> 0) & 01) << 5) +
X (((t6bits >> 1) & 01) << 3) +
X (((t6bits >> 2) & 01) << 2) +
X (((t6bits >> 3) & 01) << 1) +
X (((t6bits >> 4) & 01) << 0) +
X (((t6bits >> 5) & 01) << 4);
X
X r = S[tableno][fixed6bits];
X
X fixedr = (((r >> 3) & 01) << 0) +
X (((r >> 2) & 01) << 1) +
X (((r >> 1) & 01) << 2) +
X (((r >> 0) & 01) << 3);
X
X return (fixedr);
X}
X
Xvoid
Xinit (tableno, lowptr, highptr)
X unsl tableno;
X sbpb24 *lowptr, *highptr;
X{
X
X static unsb P[] =
X {
X 15, 6, 19, 20,
X 28, 11, 27, 16,
X 0, 14, 22, 25,
X 4, 17, 30, 9,
X 1, 7, 23, 13,
X 31, 26, 2, 8,
X 18, 12, 29, 5,
X 21, 10, 3, 24,
X };
X
X static unsb E[] =
X {
X 31, 0, 1, 2, 3, 4,
X 3, 4, 5, 6, 7, 8,
X 7, 8, 9, 10, 11, 12,
X 11, 12, 13, 14, 15, 16,
X 15, 16, 17, 18, 19, 20,
X 19, 20, 21, 22, 23, 24,
X 23, 24, 25, 26, 27, 28,
X 27, 28, 29, 30, 31, 0,
X };
X
X static obpb1 tmp32[32];
X static obpb1 tmpP32[32];
X static obpb1 tmpE[48];
X
X int j, k, i;
X int tablenoX4;
X reg sbpb24 spare24;
X
X tablenoX4 = tableno * 4;
X
X for (j = 0; j < 64; j++)
X {
X k = lookupS (tableno, j);
X
X for (i = 0; i < 32; i++)
X {
X tmp32[i] = 0;
X }
X
X for (i = 0; i < 4; i++)
X {
X tmp32[tablenoX4 + i] = (k >> i) & 01;
X }
X
X for (i = 0; i < 32; i++)
X {
X tmpP32[i] = tmp32[P[i]];
X }
X
X for (i = 0; i < 48; i++)
X {
X tmpE[i] = tmpP32[E[i]];
X }
X
X lowptr[j] = 0L;
X highptr[j] = 0L;
X
X for (i = 0; i < 24; i++)
X {
X lowptr[j] |= (unsigned long) tmpE[i] << i;
X }
X
X for (k = 0, i = 24; i < 48; i++, k++)
X {
X highptr[j] |= (unsigned long) tmpE[i] << k;
X }
X
X spare24 = lowptr[j]; /* to allow for macro expansion */
X lowptr[j] = TF_TO_SIXBIT (spare24);
X
X spare24 = highptr[j]; /* to allow for macro expansion */
X highptr[j] = TF_TO_SIXBIT (spare24);
X }
X}
X
X
Xint
Xinit_des ()
X{
X init (0L, S0L, S0H);
X init (1L, S1L, S1H);
X init (2L, S2L, S2H);
X init (3L, S3L, S3H);
X init (4L, S4L, S4H);
X init (5L, S5L, S5H);
X init (6L, S6L, S6H);
X init (7L, S7L, S7H);
X return (0);
X}
END_OF_FILE
if test 24546 -ne `wc -c <'Sources/crack-fcrypt.c'`; then
echo shar: \"'Sources/crack-fcrypt.c'\" unpacked with wrong size!
fi
# end of 'Sources/crack-fcrypt.c'
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
exit 0 # Just in case...