Google 網路論壇不再支援新的 Usenet 貼文或訂閱項目,但過往內容仍可供查看。

CRACK: A Sensible Unix Password Cracker

瀏覽次數:38 次
跳到第一則未讀訊息

Alec David Muffett

未讀,
1991年7月15日 下午2:36:371991/7/15
收件者:
"Crack" (with a capital C) is a program I have been developing over the
past 18 months, in parallel with some major mucking about that I've been
doing to the crypt() function. Crack takes a 'sensible' approach to
searching for dictionary or user-related passwords, and produces a
report not dis-similar to that generated by COPS' "pass.c".

It has been tested and works without mods on Ultrix 3.x and Ultrix 4.x,
and SunOS 4.x, although in order for it to drop easily onto other
machines I have crippled a few functions a little: see "PROGS/crack.h"
for options that you can #define to get a little speed back.

It does nothing particularly clever other than to do things in a orderly
manner and do them quickly, and therefore I have no qualms about
releasing this software to the net. There are many other optimisations
that could be done to the code (replacing malloc(), etc, springs to
mind), but for portability I have not done so to the first release.
Please let me know how you get on.

alec
--
INET: a...@aber.ac.uk JANET: a...@uk.ac.aber BITNET: aem%aber@ukacrl
UUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac...@nsfnet-relay.ac.uk
SNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB

--------- 8< snip, snip 8< --------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# 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 1 (of 1)."
# Contents: CRACK CRACK/Crack CRACK/DICTS CRACK/Makefile CRACK/PROGS
# CRACK/PROGS/-i CRACK/PROGS/Makefile CRACK/PROGS/crack-lib.c
# CRACK/PROGS/crack-pp.c CRACK/PROGS/crack-pwc.c CRACK/PROGS/crack.h
# CRACK/PROGS/sh.makedict CRACK/README CRACK/bad_pws.dat
# Wrapped by aem@aberda on Mon Jul 15 19:08:05 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'CRACK' ; then
echo shar: Creating directory \"'CRACK'\"
mkdir 'CRACK'
fi
if test -f 'CRACK/Crack' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/Crack'\"
else
echo shar: Extracting \"'CRACK/Crack'\" \(492 characters\)
sed "s/^X//" >'CRACK/Crack' <<'END_OF_FILE'
X#!/bin/csh
X
Xset op=hack-me.$$
Xset tmp=/tmp/pwf$$
Xset bin=PROGS
Xset dicts=DICTS
X
Xif ( "$1" == "" ) then
X echo "Usage: $0 passwdfile [passwdfile...]"
X exit 1
Xendif
X
Xecho "Crack 2.7a Password Cracker by ADE Muffett, 1991"
X
Xmake
X
Xcp /dev/null $tmp # "touch $tmp", "> $tmp", whatever...
X
Xforeach file ($*)
X awk '/^[A-Za-z0-9]/{print "'$file'" ":" $0}' < $file >> $tmp
Xend
X
Xecho "Backgrounding job. Output will be in $op"
X
Xsort -t: +2 $tmp | $bin/crack-pwc $dicts/dict.* >& $op &
X
Xsleep 5
X
Xrm $tmp
END_OF_FILE
if test 492 -ne `wc -c <'CRACK/Crack'`; then
echo shar: \"'CRACK/Crack'\" unpacked with wrong size!
fi
chmod +x 'CRACK/Crack'
# end of 'CRACK/Crack'
fi
if test ! -d 'CRACK/DICTS' ; then
echo shar: Creating directory \"'CRACK/DICTS'\"
mkdir 'CRACK/DICTS'
fi
if test -f 'CRACK/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/Makefile'\"
else
echo shar: Extracting \"'CRACK/Makefile'\" \(725 characters\)
sed "s/^X//" >'CRACK/Makefile' <<'END_OF_FILE'
X###
X# add other dictionaries here, relative to "."
X###
XDICTSRC= /usr/dict/words bad_pws.dat
X
X###
X# Not-so configurable bitz...
X###
XBINDIR= PROGS
XDICTDIR= DICTS
XPPDRIVER= $(BINDIR)/sh.makedict
XDICTSTAMP= $(DICTDIR)/dict-stamp
X
Xall: # I love recursion...
X ( cd $(BINDIR) ; make )
X ( make $(DICTSTAMP) )
X
X$(DICTSTAMP): $(PP) $(DICTSRC)
X $(PPDRIVER) $(DICTDIR) $(DICTSRC)
X touch $(DICTSTAMP)
X
Xtests:
X ( cd $(BINDIR) ; make tests )
X
Xalotfaster:
X ( cd $(BINDIR) ; make alotfaster )
X
Xclean:
X -( cd $(DICTDIR) && rm * )
X -rm die hack-me.* dict.?
X
Xspotless:
X ( cd $(BINDIR) && make clean )
X ( make clean )
X
Xprint:
X lpr -p Makefile \
X Crack \
X README \
X PROGS/Makefile \
X PROGS/*.h \
X PROGS/*.c \
X PROGS/sh.*
END_OF_FILE
if test 725 -ne `wc -c <'CRACK/Makefile'`; then
echo shar: \"'CRACK/Makefile'\" unpacked with wrong size!
fi
# end of 'CRACK/Makefile'
fi
if test ! -d 'CRACK/PROGS' ; then
echo shar: Creating directory \"'CRACK/PROGS'\"
mkdir 'CRACK/PROGS'
fi
if test -f 'CRACK/PROGS/-i' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/-i'\"
else
echo shar: Extracting \"'CRACK/PROGS/-i'\" \(0 characters\)
sed "s/^X//" >'CRACK/PROGS/-i' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'CRACK/PROGS/-i'`; then
echo shar: \"'CRACK/PROGS/-i'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/-i'
fi
if test -f 'CRACK/PROGS/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/Makefile'\"
else
echo shar: Extracting \"'CRACK/PROGS/Makefile'\" \(513 characters\)
sed "s/^X//" >'CRACK/PROGS/Makefile' <<'END_OF_FILE'
X###
X# Configurtable bitz...
X###
XCFLAGS= -O2 # -Bstatic # (Static linking for SunOS fix)
X
X###
X# Not-so configurable bitz...
X###
XPWC= crack-pwc
XPP= crack-pp
X
X###
X# Positively hard to configure bitz...
X###
XCRACKMOD= crack-lib.o
X
Xall: $(PP) $(PWC)
X
X$(PP): $(PP).o $(CRACKMOD)
X $(CC) $(CFLAGS) -o $@ crack-pp.o $(CRACKMOD)
X
X$(PWC): $(PWC).o $(CRACKMOD)
X $(CC) $(CFLAGS) -o $@ crack-pwc.o $(CRACKMOD)
X
Xalotfaster:
X $(CC) -O4 -o $(PWC) \
X crack-pwc.c crack-lib.c
X
Xclean:
X -rm $(PP) $(PWC) *.o *.u $(DICTSTAMP)
END_OF_FILE
if test 513 -ne `wc -c <'CRACK/PROGS/Makefile'`; then
echo shar: \"'CRACK/PROGS/Makefile'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/Makefile'
fi
if test -f 'CRACK/PROGS/crack-lib.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/crack-lib.c'\"
else
echo shar: Extracting \"'CRACK/PROGS/crack-lib.c'\" \(1764 characters\)
sed "s/^X//" >'CRACK/PROGS/crack-lib.c' <<'END_OF_FILE'
X#include "crack.h"
X
X/*
X * This program is copyright (c) Alec Muffett 1991 except for certain
X * portions of code ("fdes-crypt.c") copyright (c) Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems. This software is in the public domain and is freely
X * redisrtibutable PROVIDED that this copyright notice remains intact.
X */
X
Xvoid
XTrim (string) /* remove trailing whitespace from a string */
X register char *string;
X{
X register char *ptr;
X
X for (ptr = string; *ptr; ptr++);
X while ((--ptr >= string) && isspace (*ptr));
X *(++ptr) = '\0';
X}
X
Xchar *
XReverse (str) /* return a pointer to a reversal */
X register char *str;
X{
X register int i;
X register int j;
X register char *ptr;
X static char area[STRINGSIZE];
X
X j = i = strlen (str);
X while (*str)
X {
X area[--i] = *str++;
X }
X area[j] = '\0';
X return (area);
X}
X
Xchar *
XUppercase (str) /* return a pointer to an uppercase */
X register char *str;
X{
X register char *ptr;
X static char area[STRINGSIZE];
X
X ptr = area;
X while (*str)
X {
X *(ptr++) = islower (*str) ? toupper (*str) : *str;
X str++;
X }
X *ptr = '\0';
X
X return (area);
X}
X
Xchar *
XLowercase (str) /* return a pointer to an lowercase */
X register char *str;
X{
X register char *ptr;
X static char area[STRINGSIZE];
X
X ptr = area;
X while (*str)
X {
X *(ptr++) = isupper (*str) ? tolower (*str) : *str;
X str++;
X }
X *ptr = '\0';
X
X return (area);
X}
X
Xchar *
XClone (string)
X char *string;
X{
X int len;
X char *retval;
X
X retval = (char *) malloc (strlen (string) + 1);
X strcpy (retval, string);
X return (retval);
X}
END_OF_FILE
if test 1764 -ne `wc -c <'CRACK/PROGS/crack-lib.c'`; then
echo shar: \"'CRACK/PROGS/crack-lib.c'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/crack-lib.c'
fi
if test -f 'CRACK/PROGS/crack-pp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/crack-pp.c'\"
else
echo shar: Extracting \"'CRACK/PROGS/crack-pp.c'\" \(3019 characters\)
sed "s/^X//" >'CRACK/PROGS/crack-pp.c' <<'END_OF_FILE'
X#include "crack.h"
X
X/*
X * This program is copyright (c) Alec Muffett 1991 except for certain
X * portions of code ("fdes-crypt.c") copyright (c) Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems. This software is in the public domain and is freely
X * redisrtibutable PROVIDED that this copyright notice remains intact.
X */
X
X/* These used to be enums. Oh well... non-portability rules OK */
X#define ORDER_LCF 0
X#define ORDER_LCFP 1
X#define ORDER_MCF 2
X#define ORDER_UCF 3
X#define ORDER_LCB 4
X#define ORDER_UCB 5
X#define ORDER_MCB 6
X#define NUMFILES 7
X
Xint
Xmain (argc, argv)
X int argc;
X char *argv[];
X{
X register int i;
X register char *ptr;
X int all_digits;
X int all_letters_upper;
X int all_letters_lower;
X char buffer[STRINGSIZE];
X
X FILE *fp;
X FILE *fps[NUMFILES];
X
X if (argc == 1)
X {
X printf ("Usage:\t%s dictsrc [dictsrc ...]\n", argv[0]);
X exit (1);
X }
X
X for (i = 0; i < NUMFILES; i++)
X {
X char scratch[255];
X
X sprintf(scratch, "dict.%c", i + 'a');
X if (!(fps[i] = fopen (scratch, "w")))
X {
X perror (scratch);
X exit (3);
X }
X }
X
X for (i = 1; argv[i]; i++)
X {
X if (!(fp = fopen (argv[i], "r")))
X {
X perror (argv[i]);
X exit (1);
X }
X
X printf ("dictpp: sourcing from file '%s'\n", argv[i]);
X
X while (fgets (buffer, STRINGSIZE, fp))
X {
X Trim (buffer);
X if (!*buffer || !buffer[1]) /* skip single letters */
X {
X continue;
X }
X
X#ifndef SHORT_PASSWDS
X if (strlen (buffer) < 5)
X {
X continue;
X }
X#endif
X all_letters_upper = 1;
X all_letters_lower = 1;
X all_digits = 1;
X
X for (ptr = buffer; *ptr; ptr++)
X {
X if (!isdigit(*ptr))
X {
X all_digits = 0;
X }
X
X if (isupper (*ptr))
X {
X all_letters_lower = 0;
X } else if (islower (*ptr))
X {
X all_letters_upper = 0;
X }
X }
X
X if (all_digits)
X {
X fprintf (fps[ORDER_LCF], "%.8s\n", buffer);
X continue; /* hehehehehe */
X }
X
X if (!all_letters_upper)
X {
X fprintf (fps[ORDER_UCF], "%.8s\n", Uppercase (buffer));
X fprintf (fps[ORDER_UCB], "%.8s\n", Uppercase (Reverse (buffer)));
X } else
X {
X fprintf (fps[ORDER_UCF], "%.8s\n", buffer);
X fprintf (fps[ORDER_UCB], "%.8s\n", Reverse (buffer));
X }
X
X if (!all_letters_lower)
X {
X fprintf (fps[ORDER_LCF], "%.8s\n", Lowercase (buffer));
X fprintf (fps[ORDER_LCB], "%.8s\n", Lowercase (Reverse (buffer)));
X } else
X {
X fprintf (fps[ORDER_LCF], "%.8s\n", buffer);
X fprintf (fps[ORDER_LCB], "%.8s\n", Reverse (buffer));
X if (buffer[strlen(buffer) - 1] != 's')
X {
X fprintf (fps[ORDER_LCFP], "%.8ss\n", buffer);
X }
X }
X
X if (!all_letters_lower && !all_letters_upper)
X {
X fprintf (fps[ORDER_MCF], "%.8s\n", buffer);
X fprintf (fps[ORDER_MCB], "%.8s\n", Reverse (buffer));
X }
X }
X fclose (fp);
X }
X
X for (i = 0; i < NUMFILES; i++)
X {
X fclose (fps[i]);
X }
X}
END_OF_FILE
if test 3019 -ne `wc -c <'CRACK/PROGS/crack-pp.c'`; then
echo shar: \"'CRACK/PROGS/crack-pp.c'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/crack-pp.c'
fi
if test -f 'CRACK/PROGS/crack-pwc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/crack-pwc.c'\"
else
echo shar: Extracting \"'CRACK/PROGS/crack-pwc.c'\" \(9199 characters\)
sed "s/^X//" >'CRACK/PROGS/crack-pwc.c' <<'END_OF_FILE'
X#include "crack.h"
X#undef VERBOSE
X#undef LISTING
X
X/* LOOK FOR CONFIGURATION OPTIONS IN "crack.h" */
X
X/*
X * This program is copyright (c) Alec Muffett 1991 except for certain
X * portions of code ("fdes-crypt.c") copyright (c) Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems. This software is in the public domain and is freely
X * redisrtibutable PROVIDED that this copyright notice remains intact.
X */
X
X/*
X * crack-pwc.c - an optimised password cracker. (c) ADE Muffett, Dec 1990.
X * Totally rewritten from an 'standard' password cracker that had been
X * floating about on ther network. Apart from the entire re-write, to save my
X * sanity, this thing orders passwords to minimise calls to crypt(). Use
X * fcrypt() where you have it.
X */
X
Xstruct ENTRY
X{
X int done;
X char *filename;
X struct passwd passwd;
X struct ENTRY *across;
X struct ENTRY *next;
X};
X
Xstatic struct ENTRY *root;
X
X/*
X * DIDDY LITTLE USEFUL FUNCTIONS
X */
X
Xvoid
XLog (fmt, a, b, c, d, e, f, g, h, i, j)
X char *fmt;
X{
X long t;
X
X time (&t);
X printf ("pwc: %-15.15s ", ctime (&t) + 4);
X printf (fmt, a, b, c, d, e, f, g, h, i, j);
X fflush (stdout);
X}
X/*
X * STRUCTURE SPECIFIC FUNCTIONS
X */
X
Xchar *
XPWSkip (p) /* jump the ':' in a pwent */
X register char *p;
X{
X while (*p && *p != ':')
X {
X p++;
X }
X if (*p)
X {
X *p++ = '\0';
X }
X return (p);
X}
X
Xstruct ENTRY *
XParse (buffer) /* break up input into a structure */
X register char *buffer;
X{
X register char *p;
X register struct ENTRY *retval;
X
X retval = (struct ENTRY *) malloc (sizeof (struct ENTRY));
X retval -> next = retval -> across = NULL;
X retval -> done = 0;
X Trim (buffer);
X
X p = Clone (buffer);
X retval -> filename = p;
X p = PWSkip (p);
X retval -> passwd.pw_name = p;
X p = PWSkip (p);
X retval -> passwd.pw_passwd = p;
X p = PWSkip (p);
X retval -> passwd.pw_uid = 1;
X p = PWSkip (p);
X retval -> passwd.pw_gid = 1;
X p = PWSkip (p);
X retval -> passwd.pw_gecos = p;
X p = PWSkip (p);
X retval -> passwd.pw_dir = p;
X p = PWSkip (p);
X retval -> passwd.pw_shell = p;
X return (retval);
X}
X/*
X * START OF MODULES
X */
X
Xvoid
XLoadData () /* load sorted entries into memory */
X{
X char *ptr;
X char salt[2];
X char buffer[STRINGSIZE];
X int numlines;
X int numentries;
X register struct ENTRY *new_element;
X register struct ENTRY *current_line;
X
X numlines = 0;
X numentries = 0;
X current_line = NULL;
X
X while (fgets (buffer, STRINGSIZE, stdin))
X {
X if (!*buffer || isspace (*buffer))
X {
X continue;
X }
X new_element = Parse (buffer);
X
X ptr = new_element -> passwd.pw_passwd;
X if (!ptr[0] || ptr[0] == '*')
X {
X continue;
X }
X numentries++;
X
X if (ptr[0] == salt[0] && ptr[1] == salt[1])
X {
X new_element -> across = current_line;
X current_line = new_element;
X
X } else
X {
X if (current_line)
X {
X current_line -> next = root;
X }
X root = current_line;
X current_line = new_element;
X numlines++;
X salt[0] = ptr[0];
X salt[1] = ptr[1];
X }
X }
X
X if (current_line) /* last one tends to hang about */
X {
X current_line -> next = root;
X root = current_line;
X numlines++;
X }
X Log ("Loaded %d password entries into %d salted lines.\n",
X numentries, --numlines);
X
X return;
X}
X/*
X * PASSWORD CRACKING LOW LEVEL FUNCTIONS
X */
X
Xint
XTryManyUsers (eptr, guess) /* returns 0 if all done this line */
X register struct ENTRY *eptr;
X char *guess;
X{
X register int retval;
X char guess_crypted[STRINGSIZE];
X
X if (eptr -> done && !eptr -> across)
X {
X return (0);
X }
X strcpy (guess_crypted, crypt (guess, eptr -> passwd.pw_passwd));
X
X retval = 0;
X
X while (eptr)
X {
X#ifdef VERBOSE
X Log ("Trying '%s' on %s from line %s\n",
X guess,
X eptr -> passwd.pw_name,
X eptr -> filename);
X#endif
X if (!strcmp (guess_crypted, eptr -> passwd.pw_passwd))
X {
X if (!eptr -> done) /* haven't printed it before */
X {
X Log ("Guessed %s (%s in %s) [%s] \n",
X eptr -> passwd.pw_name,
X eptr -> passwd.pw_shell,
X eptr -> filename,
X#ifdef CRACK_PRINT
X guess
X#else
X ""
X#endif /* CRACK_PRINT */
X );
X }
X eptr -> done = 1;
X }
X retval += (!eptr -> done);
X eptr = eptr -> across;
X }
X
X return (retval);
X}
X
Xint
XTryOneUser (eptr, guess) /* returns non-null on guessed user */
X register struct ENTRY *eptr;
X register char *guess;
X{
X if (!guess || !*guess || eptr -> done)
X {
X return (0);
X }
X#ifdef VERBOSE
X Log ("Trying '%s' on %s from %s\n",
X guess,
X eptr -> passwd.pw_name,
X eptr -> filename);
X#endif
X if (strcmp (crypt (guess, eptr -> passwd.pw_passwd),
X eptr -> passwd.pw_passwd))
X {
X return (0);
X }
X eptr -> done = 1;
X Log ("Guessed %s (%s in %s) [%s] \n",
X eptr -> passwd.pw_name,
X eptr -> passwd.pw_shell,
X eptr -> filename,
X#ifdef CRACK_PRINT
X guess
X#else
X ""
X#endif /* CRACK_PRINT */
X );
X
X return (1);
X}
X/*
X * TOP LEVEL CRACKING FUNCTION INTERFACE ROUTINE - SINGLE USER ONLY
X */
X
Xint
XWordTry (entry_ptr, guess)
X register struct ENTRY *entry_ptr;
X register char *guess;
X{
X int all_lower;
X int all_upper;
X register char *ptr;
X char guess2[STRINGSIZE];
X
X if (!guess[1]) /* avoid wasting time on initials */
X {
X return (0);
X }
X if (TryOneUser (entry_ptr, guess) ||
X TryOneUser (entry_ptr, Reverse (guess)))
X {
X return (1);
X }
X all_upper = all_lower = 1;
X ptr = guess;
X
X for (ptr = guess; *ptr; ptr++)
X {
X if (islower (*ptr))
X {
X all_upper = 0;
X } else if (isupper (*ptr))
X {
X all_lower = 0;
X }
X }
X
X if (!all_lower)
X {
X strcpy (guess2, Lowercase (guess));
X if (TryOneUser (entry_ptr, guess2) ||
X TryOneUser (entry_ptr, Reverse (guess2)))
X {
X return (1);
X }
X }
X if (!all_upper)
X {
X strcpy (guess2, Uppercase (guess));
X if (TryOneUser (entry_ptr, guess2) ||
X TryOneUser (entry_ptr, Reverse (guess2)))
X {
X return (1);
X }
X }
X return (0);
X}
X/*
X * END OF PASSWORD GUESSING LAYERS
X */
X
Xvoid
XPass1 ()
X{
X int cracked;
X struct ENTRY *head;
X register char *ptr;
X register char *ptr2;
X char junk[STRINGSIZE];
X register struct ENTRY *this;
X
X Log ("starting pass1 password information\n");
X
X for (head = root; head; head = head -> next)
X {
X for (this = head; this; this = this -> across)
X {
X#ifdef CRACK_USERNAME
X /* username */
X ptr = this -> passwd.pw_name;
X if (WordTry (this, ptr))
X {
X continue;
X }
X#endif /* CRACK_USERNAME */
X
X#ifdef CRACK_USERNAME2
X /* usernameusername */
X strcpy (junk, ptr);
X strcat (junk, ptr);
X if (WordTry (this, junk))
X {
X continue;
X }
X#endif /* CRACK_USERNAME2 */
X
X#ifdef CRACK_GECOS
X /* Gecos information field */
X cracked = 0;
X ptr = junk;
X strcpy (junk, this -> passwd.pw_gecos);
X if (*ptr == '-') /* never seen this, but... */
X {
X ptr++;
X }
X if (ptr2 = strchr (ptr, ';')) /* trim off junk */
X {
X *ptr2 = '\0';
X }
X if (ptr2 = strchr (ptr, ',')) /* trim off more junk */
X {
X *ptr2 = '\0';
X }
X for (;;)
X {
X if (ptr2 = strchr (ptr, ' '))
X {
X *(ptr2++) = '\0';
X }
X if (WordTry (this, ptr))
X {
X cracked++;
X break;
X }
X if (ptr2)
X {
X ptr = ptr2;
X while (*ptr && isspace (*ptr))
X {
X ptr++;
X }
X } else
X {
X break;
X }
X }
X
X if (cracked)
X {
X continue;
X }
X#endif /* CRACK_GECOS */
X }
X }
X return;
X}
X
Xvoid
XPass2 (dictfile)
X char *dictfile;
X{
X FILE *fp;
X int dictnum;
X register int i;
X char *dict[MAXDICTSIZE];
X char buffer[STRINGSIZE];
X register struct ENTRY *head;
X
X Log ("starting pass2 on dictionary %s\n", dictfile);
X
X if (!(fp = fopen (dictfile, "r")))
X {
X perror (dictfile);
X return;
X }
X for (dictnum = 0;
X dictnum < MAXDICTSIZE && fgets (buffer, STRINGSIZE, fp);
X dictnum++)
X {
X Trim (buffer);
X if (!*buffer)
X {
X continue;
X }
X dict[dictnum] = Clone (buffer);
X }
X
X if (dictnum >= MAXDICTSIZE)
X {
X Log ("dictionary %s too big, truncated at %d words\n",
X dictfile, MAXDICTSIZE);
X }
X fclose (fp);
X
X Log ("loaded %d words from %s\n", dictnum, dictfile);
X for (head = root; head; head = head -> next)
X {
X for (i = 0; i < dictnum; i++)
X {
X if (!TryManyUsers (head, dict[i]))
X {
X break;
X }
X }
X }
X
X Log ("Freeing memory of %s\n", dictfile);
X while (dictnum >= 0)
X {
X if (dict[dictnum])
X {
X free (dict[dictnum]);
X }
X dictnum--;
X }
X}
X
Xint
Xmain (argc, argv)
X int argc;
X char *argv[];
X{
X int i;
X FILE *fp;
X char *file;
X static char die[] = "die";
X
X if (argc < 2)
X {
X fprintf (stderr, "Usage:\t%s dictfile [dictfile ...]\n", argv[0]);
X exit (1);
X }
X if (!(fp = fopen (die, "w")))
X {
X perror (die);
X exit (2);
X }
X fprintf (fp, "#!/bin/sh\nkill -9 %d\n", getpid ());
X fclose (fp);
X chmod (die, 0700);
X
X#ifdef FCRYPT
X init_des ();
X#endif
X
X LoadData ();
X
X Pass1 ();
X
X for (i = 1; argv[i]; i++)
X {
X Pass2 (argv[i]);
X }
X
X Log ("Finished.\n");
X return (0);
X}
END_OF_FILE
if test 9199 -ne `wc -c <'CRACK/PROGS/crack-pwc.c'`; then
echo shar: \"'CRACK/PROGS/crack-pwc.c'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/crack-pwc.c'
fi
if test -f 'CRACK/PROGS/crack.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/crack.h'\"
else
echo shar: Extracting \"'CRACK/PROGS/crack.h'\" \(1733 characters\)
sed "s/^X//" >'CRACK/PROGS/crack.h' <<'END_OF_FILE'
X/* Configurable bits */
X
X/*
X * This program is copyright (c) Alec Muffett 1991 except for certain
X * portions of code ("fdes-crypt.c") copyright (c) Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems. This software is in the public domain and is freely
X * redisrtibutable PROVIDED that this copyright notice remains intact.
X */
X
X#define CRACK_USERNAME /* use the username as a guess */
X#define CRACK_USERNAME2 /* use the username (doubled) as a guess */
X#define CRACK_GECOS /* use elements of gecos field as guesses */
X#define CRACK_PRINT /* print guessed output to file */
X#undef BRAINDEAD6 /* see fdes.h, if you have it */
X#undef FCRYPT /* #undef this line if you don't have
X * fcrypt(). See "fdes.h" if you do. */
X
X#define BZERO /* #undef this line if your bzero() is slow
X * or non-existent - else DEFINE IT! */
X
X#undef FAST_TOCASE /* #undef this line if you haven't got macros
X * called _tolower() & _toupper() - check
X * manuals for toupper(3) */
X
X#undef SHORT_PASSWDS /* #define this line if you want to check
X * dictionary words < 5 chars long */
X
X#define MAXDICTSIZE 32000 /* this value can be tweaked, but if it is
X * too small, the program will tell you */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <pwd.h>
X
X/* end of configurable bits */
X
X#define STRINGSIZE 255
X
Xvoid Trim ();
Xchar *Reverse ();
Xchar *Uppercase ();
Xchar *Lowercase ();
Xchar *Clone ();
X
X#ifdef FAST_TOCASE
X#define toupper(x) _toupper(x)
X#define tolower(x) _tolower(x)
X#endif
X
X#ifdef FCRYPT
X#define crypt(a,b) fcrypt(a,b)
X#endif
X
X#define RISC
X
X#undef CISC
END_OF_FILE
if test 1733 -ne `wc -c <'CRACK/PROGS/crack.h'`; then
echo shar: \"'CRACK/PROGS/crack.h'\" unpacked with wrong size!
fi
# end of 'CRACK/PROGS/crack.h'
fi
if test -f 'CRACK/PROGS/sh.makedict' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/PROGS/sh.makedict'\"
else
echo shar: Extracting \"'CRACK/PROGS/sh.makedict'\" \(256 characters\)
sed "s/^X//" >'CRACK/PROGS/sh.makedict' <<'END_OF_FILE'
X#!/bin/sh
X
Xpp="PROGS/crack-pp" # I'll fix this elegantly some other time...
Xdictdir=$1
X
Xshift
X
Xif [ ! -f $pp ]
Xthen
X echo "$0: No preprocessor $pp"
X exit 1
Xfi
X
Xrm $dictdir/dict.*
X
X$pp $*
X
Xfor i in dict.*
Xdo
X sort $i | uniq > $dictdir/$i
X rm $i
Xdone
Xexit 0
END_OF_FILE
if test 256 -ne `wc -c <'CRACK/PROGS/sh.makedict'`; then
echo shar: \"'CRACK/PROGS/sh.makedict'\" unpacked with wrong size!
fi
chmod +x 'CRACK/PROGS/sh.makedict'
# end of 'CRACK/PROGS/sh.makedict'
fi
if test -f 'CRACK/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/README'\"
else
echo shar: Extracting \"'CRACK/README'\" \(6264 characters\)
sed "s/^X//" >'CRACK/README' <<'END_OF_FILE'
X**************************************************************************
X CRACK: A Unix password cracking program.
X**************************************************************************
X
XThis is the sort of program I dreamt about whilst I was hacking big Unix
Xsites a few years ago. It takes a series of passwd format files, sorts
Xthem by their encryption salt, and gradually hacks through them finding
Xpasswords as it goes.
X
XUsage:
X Crack /etc/passwd [ other passwd format files... ]
X
XHopefully, if I've set it up correctly, it will work out what files it
Xneeds, where they are, what needs to be made, etc... it should do it
Xall for you. If not, play around with the source, starting with the
Xdefines at the top of "crack.h" in the directory "PROGS".
X
XNB: The public version of this program does absolutely nothing "clever"
Xat all, other than to attack passwords in sensible order. This is why I
Xfeel I can post it to the net without fear of recrimination. If you
Xthink that I am a moron and that the program is in itself dangerous, I
Xsuggest that you carefully consider the fact that any 'moron' could have
Xwritten this program.
X
X*** Operating System Specific Notes ***
X
XThe program you are using will be have been tested on:-
X
X Ultrix 4.1
X SunOS 4.0
X
XIf there are any amendments that you have to make to get it going on
Xyour system, please let me know about them so that I can work it into
Xthe next release. I'm afraid I'm a bit restricted in what machines I
Xcan test it on. Have a look in "PROGS/crack.h" if it doesn't work.
X
XNote to SunOS users:-
X
X*IF* "crack-pwc" coredumps with a bus-error, do a "make spotless", and
Xadd the "-Bstatic" switch to CFLAGS in "PROGS/Makefile". Something
Xmakes etext() crash sporadically when accessing the dynamically linked
Xversion of malloc(). Static linking fixes this.
X
X*** Philosophy & Caveats ***
X
X"Crack" makes two passes over its source data:- the first based upon
Xwhat it can make of the users' passwd entry, and the second throws
Xordered dictionaries at the passwords. The first pass is usually very
Xfruitful, and gets lots of results quickly.
X
XIn the first pass, passwords are tried in plaintext, forced lowercase
Xand forced uppercase, forward and reversed (total of six permutations).
XIt can check 2500 password entries in about 20 minutes using the
Xstandard crypt() on a DecStation 5000/200. This is so little overhead
Xthat the forward/reverse/recasing switches that some of you are used to
X(eg: from the COPS password checker) have been removed, but see also
Xbelow.
X
XFor pass 2, "Crack" assumes you have a "/usr/dict/words". If not, edit
Xthe "Makefile" to have the pathname of a suitable dictionary, or add
Xextra dictionaries to the list. "Crack" takes multiple dictionaries,
Xsorts and uniq's them, and then preprocesses them into different files.
XIt then throws each file (one by one) at your password selection. This
Xmethod removes a lot of runtime overhead.
X
XThe preprocessed files (put into the directory "DICTS") are arranged and
Xprocessed in numerical order of formats most likely to be a guessable
Xpassword:-
X
X dict.0 forced lowercase words, forwards
X dict.1 plaintext (but lowercase) words, pluralised
X dict.2 plaintext mixedcase words, forwards
X dict.3 forced uppercase words, forwards
X dict.4 forced lowercase words, backwards
X dict.5 forced uppercase words, backwards
X dict.6 plaintext mixedcase words, backwards
X
XProcessing them in this order increases the chance of getting a users'
Xpassword quickly.
X
XSince each preprocessed file represents a different format of password
Xguess, all you need do to stop yourself from doing a certain pass is to
Xremove the unwanted file. This is rarely a sensible thing to do, since
Xusually what you are trying to do is to speed things up, but since
X"Crack" does things in a sensible order anyway, it's hardly worth
Xtweaking the dictionaries other than to add new words.
X
XLet me repeat the caveat that was attached to the ancient pwchkr.c:-
XThis program burns a lot of CPU! An awful lot! So if your system runs
Xlike a snail, don't come screaming to me. I've half a mind to put
X"nice(19);" as the first statement in main().
X
X*** Fcrypt() usage ***
X
X"Crack" can utilise fcrypt() written in 1986 by Robert Baldwin @MIT,
Xwhich is a pretty darn good version of the crypt() subroutine. I
Xreceived a copy of "fdes-xform.c" which was variously hacked about for
Xportability by Icarus Sparry at Bath. Fcrypt() used to do 390-ish
Xencryptions per second.
X
XI rewrote most of the tables and the KeySchedule generating algorithm in
X"fdes-init.c" to knock 40% off the execution overhead of fcrypt() in the
Xform that it was shipped to me. I then inlined a bunch of stuff, put it
Xinto a single file, got some advice from Matt Bishop [thanks Matt] about
Xwhat to do to xform(), and tidied up some algorithms.
X
XOn a DecStation 5000/200, fcrypt() will now do 575-ish transforms per
Xsecond <grin!>. Do a "make tests" to find out what your system is like.
X
XNOTE: fcrypt() is *NOT* distributed as standard with this package.
X
X*** Signature ***
X
XSuggestions for improvements to me please, and I'll keep the updates
Xcoming... I already know about the clearing/copying data subroutines.
X
XIf you're feeling gung-ho, play with the highly optimised:-
X
X make alotfaster
X
X...option. It seems to work OK on Ultrix 4.1.
X
X Alec Muffett>>>++>>, July 15 1991
X--
Xp.s. I've pinched the internet worm password file from COPS, hacked it
X about a bit, and supplied it here as "bad_pws.dat". It is wired
X into the Makefile as an additional dictionary - AEM
X--
XINET: a...@aber.ac.uk JANET: a...@uk.ac.aber BITNET: aem%aber@ukacrl
XUUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac...@nsfnet-relay.ac.uk
XSNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB
X
X*** stddisclaimer.h ***
X
X/*
X * This program is copyright (c) Alec Muffett 1991 except for certain
X * portions of code ("fdes-crypt.c") copyright (c) Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems. This software is in the public domain and is freely
X * redisrtibutable PROVIDED that this copyright notice remains intact.
X */
END_OF_FILE
if test 6264 -ne `wc -c <'CRACK/README'`; then
echo shar: \"'CRACK/README'\" unpacked with wrong size!
fi
# end of 'CRACK/README'
fi
if test -f 'CRACK/bad_pws.dat' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CRACK/bad_pws.dat'\"
else
echo shar: Extracting \"'CRACK/bad_pws.dat'\" \(3105 characters\)
sed "s/^X//" >'CRACK/bad_pws.dat' <<'END_OF_FILE'
X123456
X12345678
XAnduin
XDoobrie
XLouise
XMortis
XSnarfel
Xacademia
Xaerobics
Xairplane
Xalbany
Xalbatross
XAlbert
XAlexander
Xalgebra
Xaliases
Xalphabet
Xamorphous
Xanalog
Xanchor
Xandromache
Xanimals
Xanswer
Xanthropogenic
Xanvils
Xanything
Xariadne
XArthur
Xasdfgh
Xathena
Xatmosphere
Xaztecs
Xbacchus
Xbailey
Xbanana
Xbananas
Xbandit
Xbarber
Xbaritone
Xbassoon
Xbatman
Xbeater
Xbeauty
Xbeethoven
Xbeetledrive
Xbeloved
Xbeowulf
Xberkeley
Xberliner
XBeverly
Xbicameral
XBrenda
XBridget
Xbroadway
Xbumbling
Xburgess
Xcampanile
Xcantor
Xcardinal
Xcarmen
Xcarolina
XCaroline
Xcascades
Xcastle
Xcayuga
Xceltics
Xcerulean
Xchange
XCharles
Xcharming
Xcharon
Xcheesecake
Xchester
Xcinelli
Xclassic
Xclusters
Xcoffee
Xcollins
Xcommrades
Xcomputer
Xcookie
Xcooper
XCornelius
Xcouscous
Xcreation
Xcreosote
Xcretin
Xdaemon
Xdancer
XDaniel
Xdecember
Xdeluge
Xdesperate
Xdevelop
Xdieter
Xdigital
Xdiscbox
Xdiscovery
Xdisney
Xdrought
XDuncan
Xeasier
Xedinburgh
XEdwina
Xegghead
Xeiderdown
XEileen
XEinstein
Xelephant
XElizabeth
Xemerald
Xengine
Xengineer
Xenterprise
Xenzyme
Xersatz
Xestablish
Xestate
Xeuclid
Xeugene
XEvelyn
Xextension
Xfairway
Xfelicia
Xfender
Xfermat
Xfidelity
Xfinite
Xfishers
Xflakes
Xflower
Xflowers
Xfoolproof
Xfootball
Xforesight
Xformat
Xforsythe
Xfourier
Xfriend
Xfrighten
Xfungible
XGabriel
Xgardner
Xgarfield
XGeorge
Xgertrude
XGilly
XGinger
Xglacier
Xgolfer
Xgorgeous
Xgorges
Xgosling
Xgraham
Xgrass
Xgryphon
Xguitar
Xgumption
Xguntis
Xgweledigaeth
Xhacker
Xhamlet
Xhandily
Xhappening
Xharmony
Xharold
Xharvey
Xhebrides
Xheinlein
Xherbert
Xhiawatha
Xhibernia
Xhobbit
Xhutchins
Xiluvben
Ximbroglio
Ximperial
Xinclude
Xingres
Xinnocuous
Xirishman
XJessica
Xjester
Xjixian
XJohnny
XJoseph
XJoshua
Xjudith
Xjuggle
Xkalajira
XKathleen
Xkermit
Xkernel
Xkipper
Xkirkland
Xknight
Xlager
Xlambda
Xlamination
Xlarkin
Xlazarus
Xlebesgue
Xleland
Xmacintosh
Xmaggot
XMalcolm
Xmarkus
Xmarvin
Xmaster
XMaurice
Xmellon
Xmerlin
XMichael
XMichelle
Xminimum
Xminsky
Xmoguls
Xmorley
Xmortis
Xmozart
Xmuser
Xnapoleon
Xnepenthe
Xnetwork
Xnewton
Xnoxious
Xnutrition
Xnyquist
Xoceanography
Xocelot
Xoerhrdle
Xolivetti
XOlivia
Xoracle
Xorchid
Xorwell
Xosiris
Xoutlaw
Xoxford
Xpacific
Xpainless
Xpakistan
Xpapers
Xpassword
XPatricia
Xpenguin
Xpeoria
Xpercolate
Xpersimmon
Xpersona
Xphilip
Xphoenix
XPierre
Xplover
Xplymouth
Xpolynomial
Xpondering
Xposter
Xpraise
Xprecious
Xprelude
Xprince
Xprinceton
Xprotect
Xprotozoa
Xpumpkin
Xpuneet
Xpuppet
Xqwerty
Xqwertyui
Xrabbit
Xrachmaninoff
Xrainbow
Xraindrop
Xraleigh
Xrandom
Xrascal
Xreally
XRebecca
Xremote
Xripple
Xrobotics
Xrochester
Xromano
XRonald
XRonnie
Xrosebud
XRosemary
Xsaturn
Xscamper
Xscheme
Xscotty
Xsecret
Xsensor
Xserenity
Xsharks
Xsharon
Xsheffield
Xsheldon
Xshitforbrains
Xshivers
Xshuttle
Xsignature
Xsilverlake
Xsimple
Xsinger
Xsingle
Xsmiles
Xsmooch
Xsmother
Xsnatch
Xsnoopy
Xsocrates
Xsossina
Xsparrows
Xsplatter
Xsplodge
Xspring
Xspringer
Xsquires
Xstrangle
Xstratford
Xstuttgart
Xsubway
Xsuccess
Xsucker
Xsummer
Xsuperstage
Xsupport
Xsupported
Xsurfer
XSuzanne
Xswearer
Xsymmetry
Xtangerine
Xtarget
Xtarragon
Xtaylor
Xteabag
Xtelephone
Xtemptation
Xthailand
Xthanatos
Xtoggle
Xtomato
Xtopography
Xtortoise
Xtoyota
Xtrails
Xtrivial
Xtrombone
Xtuttle
Xunhappy
Xunicorn
Xunknown
Xurchin
Xutility
Xvasant
Xvertigo
Xvillage
XVirginia
Xvortex
XWarren
Xweenie
Xwhatnot
Xwhiting
Xwhitney
XWilliam
Xwilliamsburg
XWillie
Xwinston
Xwisconsin
Xwizard
Xwombat
Xwoodwind
Xwormwood
Xxerox
Xyellowstone
Xyosemite
Xzerox
Xzimmerman
Xzxcvbn
END_OF_FILE
if test 3105 -ne `wc -c <'CRACK/bad_pws.dat'`; then
echo shar: \"'CRACK/bad_pws.dat'\" unpacked with wrong size!
fi
# end of 'CRACK/bad_pws.dat'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have the archive.
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

Alec David Muffett

未讀,
1991年7月17日 清晨7:41:341991/7/17
收件者:
This is a context diff to the file CRACK/PROGS/crack-pp.c: it fixes a
bug whereby words of length greater than 7 characters were pluralised,
and this is obviously a waste, since the password will be truncated at 8
characters anyway... If you don't have the 'patch' command, worry not,
because you can probably spot the difference and edit it yourself.
It's a 1-minute fix.

Other bugs and suggestions I have been swamped with:-

1) spotting whether to use index() or strchr()
2) spotting whether to use <strings.h> or <string.h>

- These I will fix with a lwall-style Configure script
which will also provide compile-time option control.

3) Creating a feedback file for information gathered from the password
file (GECOS, etc) in pass 1 to create a dictionary of names to use in
pass2.

- I am provisionally against this sort of idea because it
smacks of trying to get crack-pp to do everything, so that
it bloats and is hard to maintain and slow (bit like what's
happened to Unix, really... 8-) )

- A neater solution would be to get a preprocessor to hack
through the password file and wire the Gecos info into
the dictionaries, where the normal sort/trim/uniq process
would remove redundancy. This is what I shall implement.

If anyone mails me in the next few days, please be patient in waiting
for a response - I'm off to see my girlfriend win all the prizes in her
local village cookery contest... 8-)

alec
--
INET: a...@aber.ac.uk JANET: a...@uk.ac.aber BITNET: aem%aber@ukacrl
UUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac...@nsfnet-relay.ac.uk
SNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB

---- 8< cut here for patch 8< ----

*** crack-pp.c Wed Jul 17 12:08:26 1991
--- crack-pp.c.orig Wed Jul 17 12:05:25 1991
***************
*** 120,132 ****
{


fprintf (fps[ORDER_LCF], "%.8s\n", buffer);

fprintf (fps[ORDER_LCB], "%.8s\n", Reverse (buffer));

! if (strlen(buffer) < 8 && buffer[strlen(buffer) - 1] != 's')
{
- /*
- * Fix suggested by Jim Mattson (mat...@cs.ucsc.edu):-
- * we should not pluralise anything more than 7 chars
- * long, as it is a waste.
- */


fprintf (fps[ORDER_LCFP], "%.8ss\n", buffer);
}
}

--- 120,127 ----
{


fprintf (fps[ORDER_LCF], "%.8s\n", buffer);

fprintf (fps[ORDER_LCB], "%.8s\n", Reverse (buffer));

! if (buffer[strlen(buffer) - 1] != 's')
{

chris...@gmail.com

未讀,
2019年2月4日 下午5:23:132019/2/4
收件者:
probably Kevin Mitnick came here xD
0 則新訊息