home *** CD-ROM | disk | FTP | other *** search
- /*
- * pwc -- password cracker
- *
- * pwc is a brute force password cracking program. It reads a list of
- * /etc/passwd entries from the password file argument and compares
- * the password field against the contents of the remaining file arguments.
- * Good pattern files are the dictionary files in /usr/lib/dict, lists of
- * first names from the GECOS field, single letters and numbers,
- * license plates, etc.
- *
- * usage: pwc [-d] [-v] [-i] passwd_file file1 file2
- *
- * -d issue debugging information
- *
- * -v verbose. Print intermediate information as cracking proceeds
- *
- * -i identify and print usage message
- */
-
- char *Copyright_Legend[] = {
- " Written by Paul Pomes, University of Illinois, Computing Services Office",
- " Copyright (C) 1986 by Paul Pomes and the University of Illinois Board",
- " of Trustees",
- " ",
- " This program is distributed in the hope that it will be useful,",
- " but without any warranty. No author or distributor accepts",
- " responsibility to anyone for the consequences of using it or for",
- " whether it serves any particular purpose or works at all, unless",
- " s/he says so in writing.",
- " ",
- " Everyone is granted permission to copy, modify and redistribute",
- " this program under the following conditions:",
- " ",
- " Permission is granted to anyone to make or distribute copies",
- " of program source code, either as received or modified, in any",
- " medium, provided that all copyright notices, permission and",
- " nonwarranty notices are preserved, and that the distributor",
- " grants the recipient permission for further redistribution as",
- " permitted by this document, and gives him and points out to",
- " him an exact copy of this document to inform him of his rights.",
- " ",
- " Permission is granted to distribute this program in compiled",
- " or executable form under the same conditions applying for",
- " source code, provided that either",
- " A. it is accompanied by the corresponding machine-readable",
- " source code, or",
- " B. it is accompanied by a written offer, with no time limit,",
- " to give anyone a machine-readable copy of the corresponding",
- " source code in return for reimbursement of the cost of",
- " distribution. This written offer must permit verbatim",
- " duplication by anyone.",
- " C. it is distributed by someone who received only the",
- " executable form, and is accompanied by a copy of the",
- " written offer of source code which he received along with it.",
- " ",
- " In other words, you are welcome to use, share and improve this",
- " program. You are forbidden to forbid anyone else to use, share",
- " and improve what you give them. Help stamp out software-hoarding!",
- " ",
- " UUCP: {ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!paul",
- " ARPANET: paul%uxc@a.cs.uiuc.edu CSNET: paul%uxc@uiuc.csnet",
- " ICBMS: 88 13 N / 40 07 W",
- " US Mail: Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL 61801",
- 0
- };
-
- /*
- * $Log: pwc.c,v $
- * Revision 1.1 86/08/26 15:55:23 paul
- * Initial revision
- *
- */
-
- #ifndef lint
- static char RcsId[] = "$Header: pwc.c,v 1.1 86/08/26 15:55:23 paul Exp $";
- #endif
-
- #include <stdio.h>
- #include <strings.h>
- #include <ctype.h>
- #include <pwd.h>
-
- #define equal(s1, s2) (strcmp (s1, s2) == 0)
- #define skipline(f) while (getc (f) != '\n')
-
- #define PROC /* null; easy to find procs */
- #define FALSE 0
- #define TRUE 1
- #define CHNULL ('\0')
- #define CPNULL ((char *) NULL)
- #define FILENULL ((FILE *) NULL)
- #define REG register
- #define BMASK 0377
-
- #define MAXFILE 15
-
- /*
- * Miscellaneous global values:
- */
-
- char *usage[] = {
- "usage: %s [-d] [-v] [-i] passwd_file [file1] [file2 ...]",
- CPNULL
- };
-
- /* how program was invoked (argv[0]) for error messages */
- char *myname;
-
- /* debug messages printed if set (-d) */
- int dflag = FALSE;
-
- /* print informational messages every so often (-v) */
- int vflag = FALSE;
-
- /* external functions */
- extern char *fcrypt ();
-
- /* internal functions */
- char *getstr ();
-
- PROC main (argc, argv)
- int argc;
- char **argv;
- {
- extern int optind; /* from getopt () */
- extern char *optarg; /* from getopt () */
- int option; /* option "letter" */
- int i; /* counters */
- int done = 0; /* found a login match */
- REG FILE *filep; /* open input file */
- char *pw_file = CPNULL; /* name to use */
- char pattern[200]; /* word patterns from file */
- char *ciphered; /* result from fcrypt () */
- char *cp, *cp2;
- REG struct passwd *pwp; /* fast pointer to passwd struct */
- FILE *pat_fp[MAXFILE]; /* pattern file pointers */
- char *indexm();
-
- /*
- * BASENAME: Full string, or past '/' if any:
- */
-
- myname = ((myname = rindex (*argv, '/')) == CPNULL) ? *argv : (myname + 1);
-
- /*
- * PARSE ARGUMENTS:
- */
-
- while ((option = getopt (argc, argv, "dvi")) != EOF) {
- switch (option) {
- case 'd':
- dflag++;
- fprintf (stderr, "%s: dflag = %d\n", myname, dflag);
- break;
-
- case 'v':
- vflag++;
- break;
-
- case 'i':
- Usage (1);
- break;
-
- default:
- Usage (0);
- }
- }
- argc -= optind; /* skip options */
- argv += optind;
-
- if (argc < 1) /* no file names */
- Error ("No password file specified");
- pw_file = *argv;
- argc--; argv++;
- if (dflag)
- fprintf (stderr, "password file is %s\n", pw_file);
- setlinebuf (stdout);
-
- /*
- * open the pattern files and assign stream pointers in pat_fp.
- * when stepping through the files, the register variable filep
- * will be what's referenced. care must be taken to set fp_pat[n]
- * back to what filep is before rewind the file and going on to
- * fp_pat[n+1].
- */
-
- if (argc < 1) /* no file names */
- pat_fp[0] = FILENULL;
- else {
- for (i = 0; i < MAXFILE && argc > 0; i++, argc--, argv++) {
- if (dflag)
- fprintf (stderr, "%d opening %s\n", i, *argv);
- if ((pat_fp[i] = fopen (*argv, "r")) == FILENULL)
- Error ("can't open file \"%s\" to read it", *argv);
- }
- pat_fp[i] = FILENULL;
- if (i == MAXFILE)
- fprintf (stderr, "%s: too many pattern files. files after %s ignored\n",
- myname, *(--argv));
- }
-
- /* set the password file name for use by getpwent */
-
- setpwfile (pw_file);
- setpwent ();
-
- init_des();
-
- /*
- * two nested loops do the real work. outermost loop steps through
- * password entries. next loop works through pat_fp array of FILE
- * descriptors. innermost loop works through each file issuing
- * calls to fcrypt ().
- */
-
- while ((pwp = getpwent()) != NULL) {
- done = 0;
- printf ("%.8s", pwp->pw_name);
- (void) fflush (stdout);
- if (*pwp->pw_name == 'U') {
- printf("\t- UUCP account, skipping\n");
- fflush(stdout);
- continue;
- }
- if (*pwp->pw_passwd == '\0') {
- printf("\t- Null password (shell is %s)\n",
- pwp->pw_shell);
- continue;
- }
- if (equal (pwp->pw_passwd, "*")) {
- printf("\n");
- continue;
- }
- /*
- * Try the user's login name
- */
- *pattern = '\0';
- do {
- (void)strcat(pattern, pwp->pw_name);
- if (uandltry(pwp, pattern)) {
- done++;
- break;
- }
- } while (strlen(pattern) < 8);
- if (done)
- continue;
-
- /*
- * Try names from the gecos field
- */
- strcpy(pattern, pwp->pw_gecos);
- cp = pattern;
- for (;;) {
- if ((cp2 = indexm(cp, " ,;")) == NULL)
- cp2 = pattern + strlen(pwp->pw_gecos) - 1;
- else
- *cp2 = '\0';
- if (uandltry(pwp,cp)) {
- done++;
- break;
- }
- cp = ++cp2;
- }
- if (done)
- continue;
-
- /*
- * Try all single letters
- * (try digits too . --Seth)
- */
- pattern[1] = '\0';
- for (pattern[0]='a'; pattern[0] <= 'z'; pattern[0]++)
- if (try(pwp,pattern)) {
- done++;
- break;
- }
- for (pattern[0]='A'; pattern[0] <= 'Z'; pattern[0]++)
- if (try(pwp,pattern)) {
- done++;
- break;
- }
- for (pattern[0]='0'; pattern[0] <= '9'; pattern[0]++)
- if (try(pwp,pattern)) {
- done++;
- break;
- }
- if (done)
- continue;
- for (i = 0, filep = pat_fp[i];
- filep != FILENULL; i++, filep = pat_fp[i]) {
- while (getstr (pattern, 8, filep) != CPNULL) {
- ciphered = fcrypt (pattern, pwp->pw_passwd);
- if (dflag > 1)
- fprintf(stderr, " Testing =%s=, got =%s=\n", pattern, ciphered);
- if (equal (ciphered, pwp->pw_passwd)) {
- try (pwp, pattern);
- done++;
- break;
- }
- }
- rewind (filep);
- if (done)
- break;
- }
- if (! done)
- putchar ('\n');
- }
- exit (0);
- } /* main */
-
- /*
- * Usage -- print how to use message
- *
- * Print usage messages (char *usage[]) to stderr and exit nonzero.
- * Each message is followed by a newline.
- *
- * parameters:
- * full_text (IN) prints the copyright statement if set
- * returns:
- * none, exit (1)
- * side effects:
- * program terminates
- * deficiencies:
- */
-
- PROC Usage (full_text)
- int full_text;
- {
- REG int which = 0; /* current line */
-
- while (usage[which] != CPNULL) {
- fprintf (stderr, usage[which++], myname);
- putc ('\n', stderr);
- }
- fflush(stdout);
- which = 0;
- if (full_text) {
- while (Copyright_Legend[which] != CPNULL)
- printf ("%s\n", Copyright_Legend[which++]);
- }
- exit (1);
- } /* Usage */
-
- /*
- * Error -- print error message with program name
- *
- * Print an error message to stderr and exit nonzero. Message is preceded
- * by "<myname>: " using global char *myname, and followed by a newline.
- *
- * parameters:
- * message (IN) printf format string
- * arg1-4 (IN) printf arguments
- * returns:
- * none, exit (1)
- * side effects:
- * program terminates
- * deficiencies:
- */
-
- /* VARARGS */
- PROC Error (message, arg1, arg2, arg3, arg4)
- char *message;
- long arg1, arg2, arg3, arg4;
- {
- fprintf (stderr, "%s: ", myname);
- fprintf (stderr, message, arg1, arg2, arg3, arg4);
- putc ('\n', stderr);
- exit (1);
- } /* Error */
-
- /*
- * Malloc -- a malloc with error checking
- *
- * parameters:
- * size (IN) number of bytes to get
- * returns:
- * (char *) of first char of block, or
- * calls Error () upon error
- * side effects:
- * none
- * deficiencies:
- */
-
- char *malloc ();
- char *Malloc ();
-
- PROC char * Malloc (size)
- unsigned size; /* bytes to get */
- {
- char *cp; /* pointer to memory */
-
- if ((cp = malloc (size)) == CPNULL)
- Error ("malloc %d bytes failed", size);
- return (cp);
- } /* Malloc */
-
- /*
- * getstr -- get a string of length n or up to a new-line from a file
- *
- * parameters:
- * s (IN/OUT) char array to place string into
- * n (IN) maximum number of characters to get
- * iop (IN/OUT) FILE descriptor
- * returns:
- * (char *) of first char of block, or
- * calls Error () upon error
- * side effects:
- * none
- * deficiencies:
- */
-
- PROC char * getstr (s, n, iop)
- char *s;
- int n;
- register FILE *iop;
- {
- register c;
- register char *cs;
-
- cs = s;
- n++;
- while (--n > 0 && (c = getc (iop)) >= NULL) {
- *cs = c;
- if (c == '\n') {
- *cs = CHNULL;
- break;
- }
- cs++;
- }
- if (c < 0 && cs == s)
- return (CPNULL);
- if (c != '\n')
- while ((c = getc (iop)) != '\n' && c >= 0)
- *cs++ = CHNULL;
- return (s);
- } /* getstr */
- /*
- * Added by Jacob Gore, March 12, 1987.
- *
- * Finds the pointer of the leftmost occurance within the character string
- * 'string' of any character found within the character string 'chars'.
- *
- * If none of the characters in 'chars' appear in 'string', NULL is retutned.
- *
- */
- char *
- indexm (string, chars)
- char *string, *chars;
- {
- while (*string) {
- if (index(chars, *string) != NULL) {
- return string;
- }
- string++;
- }
- return NULL;
- }
- /*
- * Stands for "upper and lower" try. Calls the "real" try, below,
- * with the supplied version of the password, and with
- * an upper and lowercase version of the password. If the user doesn't
- * want to try upper and lower case then we just return after the one
- * check.
- * Written by Craig Leres, modified by Paul Pomes
- */
-
- uandltry (pwd,guess)
- char *guess;
- struct passwd *pwd;
- {
- register char *cp, *cpx;
- char buf[100];
- int alllower, allupper;
- char *reverse();
-
- alllower = allupper = 1;
-
- if (try(pwd,guess)) return (1);
- if (try(pwd,(cpx = reverse(guess)))) {
- free (cpx);
- return (1);
- }
- free (cpx);
-
- strcpy (buf, guess);
- cp = buf-1;
- while (*++cp) {
- if (isupper(*cp))
- alllower = 0;
- if (islower(*cp))
- allupper = 0;
- }
-
- if (!allupper) {
- for ( cp=buf; *cp != '\0'; cp++)
- if (islower (*cp))
- *cp += 'A' - 'a';
-
- if (try(pwd,buf)) return (1);
- if (try(pwd,(cpx = reverse(buf)))) {
- free (cpx);
- return (1);
- }
- free (cpx);
- }
-
- if (!alllower) {
- for ( cp = buf; *cp != '\0'; cp++)
- if (isupper (*cp))
- *cp += 'a' - 'A';
-
- if (try(pwd,buf)) return (1);
- if (try(pwd,(cpx = reverse(buf)))) {
- free (cpx);
- return (1);
- }
- free (cpx);
- }
- return (0);
- }
-
- try(pwd,guess)
- char *guess;
- register struct passwd *pwd;
- {
- register char *cp;
- char *fcrypt ();
-
- if (! guess || ! *guess) return(0);
- cp = fcrypt (guess, pwd -> pw_passwd);
- if (strcmp (cp, pwd -> pw_passwd))
- return (0);
- printf("\t- Guessed password is %s (shell is %s)\n",
- guess, pwd->pw_shell);
- fflush (stdout);
- return (1);
- }
- /*
- * reverse a string
- */
- char *reverse(str)
- char *str;
-
- {
- register char *ptr;
- register int len;
- char *malloc();
-
- if ((ptr = malloc((len = strlen(str))+1)) == NULL)
- return(NULL);
- ptr += len;
- *ptr = '\0';
- while (*str && (*--ptr = *str++))
- ;
- return(ptr);
- }
-
-
-
- Another file downloaded from: NIRVANAnet(tm)
-
- & the Temple of the Screaming Electron 510-935-5845
-
- Rat Head 510-524-3649
- Burn This Flag 408-363-9766
- realitycheck 415-474-2602
- Lies Unlimited 415-583-4102
-
- Specializing in conversations, obscure information, high explosives,
- arcane knowledge, political extremism, diversive sexuality,
- insane speculation, and wild rumours. ALL-TEXT BBS SYSTEMS.
-
- Full access for first-time callers. We don't want to know who you are,
- where you live, or what your phone number is. We are not Big Brother.
-
- "Raw Data for Raw Nerves"
-
-
-