www.pudn.com > AntiCrack.zip > anticrack.c
/* * anticrack - a password checker against password Crackers * * Copyright (C) 1996 Kazuto Tominaga * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * How to make: * * 1. Compile "anticrack.c" and "rejrule.c" within the Source directory * of Crack v4.1f (crack.h, conf.h and crack-glob.h in Crack's distribution * are required). * * 2. Compile "crack-lib.c" in Crack's distribution. * * 3. Link all the resulting objects (anticrack.o, rejrule.o and crack-lib.o) * to make the executable `anticrack'. * * * Usage: * * Anticrack requires two arguments: the first is a rule file, and the * second is a dictionary file. You can use Crack's "Scripts/dicts.rules" * and "Dicts/bigdict" files respectively. The command line would look like: * * anticrack dicts.rules bigdict * * You will be prompted for your password candidate (twice). Echo * automatically turns off. * * Then, you'll get the result quite a little time after, * but it heavily depends on the number of the rules, the size of * the dictionary, and furthermore, the given candidate. * * * Note: * * In default, neither comment lines nor empty lines are allowed in * the dictionary file. If it has some, the switch '-c' must be specified. * * * Bugs: * * The 8th bit is used internally to mean special characters. * * The string functions (e.g., strcpy) are supposed to handle an 8-bit * character in the same way as they handle a 7-bit character. * */ #include#include #ifdef hpux #include /* for getpass(3) */ #endif #include "anticrack.h" /* version info */ char anticrack_version[] = VERSION; /* version of this file */ static char version_id[] = "@(#) $Id: anticrack.c,v 1.15 1993/11/18 08:24:21 tominaga Exp tominaga $"; /* to embed in binary code */ static char anticrack_h_version_id[] = ANTICRACK_H_VERSION; /* default values */ int debug = 0; /* debug flag */ int comment = 0; /* turn on if dictionary has comment or empty lines */ int showcracked = 0; /* turn on if cracked candidates should be shown */ int acceptedrules = 0; /* turn on to show the accepted rules */ int showacceptrate = 0; /* turn on to show the rate of accepted rules */ /* stub for crack-lib.c */ Log(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) char *f; long x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; { fprintf(stderr, f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); } /* optional messages are shown by this function */ message(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) char *f; long x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; { fprintf(stderr, f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); } char *Malloc(s) /* indispensable malloc; exits on failure */ unsigned s; { char *p, *malloc(); if ((p = malloc(s)) == NULL) { perror("malloc"); exit(-2); } return p; } char *newstr(s) char *s; { char *p; p = Malloc(strlen(s)+1); strcpy(p, s); return p; } main(ac, av) int ac; char **av; { char *rfile, *dfile, *flags; FILE *rules, *dic; char pwline[MAXPWLINE], pwline2[MAXPWLINE], rawpw[MAXPWLINE]; char *getpass(); struct RULE *rtop, *prepit(); int cracked; switch (ac) { case 3: rfile = av[1]; dfile = av[2]; break; case 4: if (*av[1] == '-') { for (flags = av[1] + 1; *flags != '\0'; flags++) { switch (*flags) { case 'c': comment = 1; break; case 's': showcracked = 1; break; case 'd': debug = 1; break; case 'a': acceptedrules = 1; break; case 'p': showacceptrate = 1; break; default: fprintf(stderr, "unknown option -%c\n", *flags); exit(-3); } } rfile = av[2]; dfile = av[3]; break; } /* don't break */ default: fprintf(stderr, "%s\n", VERSION); fprintf(stderr, "usage:\n\t%s [-csdap] \n", *av); fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "user options:", "\tc: the dictionary has comment or empty lines", "\ts: show matching rule and result if cracked", "debug options:", "\td: show debug info of processing", "\ta: show all accepted rules", "\tp: show rate of acception"); exit(-1); } /*** notice to the user ***/ if (debug) { fprintf(stderr, "WARNING: THE CANDIDATE WILL BE SHOWN\n"); fflush(stdout); } if (showcracked) { fprintf(stderr, "WARNING: THE CANDIDATE WILL BE SHOWN IF CRACKED\n"); fflush(stdout); } if (acceptedrules) { fprintf(stderr, "CAUTION: Hints for the candidate will be shown\n"); fflush(stdout); } /* prompt user to input */ fprintf(stderr, "Welcome to AntiCrack.\n"); strcpy(pwline, getpass("Your password candidate: ")); strcpy(pwline2, getpass("Type it again: ")); if (strcmp(pwline, pwline2)) { fprintf(stderr, "You typed different strings; try again.\n"); exit(6); } if ((rules = fopen(rfile, "r")) == NULL) { perror("fopen"); exit(11); } if ((dic = fopen(dfile, "r")) == NULL) { perror("fopen"); exit(2); } /* truncate the password up to PWLEN characters */ /* (it must have been done by getpass, but to be sure) */ strncpy(rawpw, pwline, PWLEN); rawpw[PWLEN] = '\0'; if (debug) message("debug: candidate is \"%s\"\n", rawpw); rtop = prepit(rules, rawpw); if (acceptedrules) showrules(rtop); if (docrack(rawpw, rtop, dic)) { /* hit */ fprintf(stderr, "Cracked. Try another candidate.\n"); cracked = 1; } else { /* ok */ fprintf(stderr, "Not Cracked.\n"); cracked = 0; } fclose(rules); fclose(dic); exit(cracked); } /* load rules from file rejecting unsuitable ones */ struct RULE *prepit(rf, pw) FILE *rf; char *pw; { char rbuf[RBUFSIZE]; void Trim(); struct RULE top, *p; int all=0, accepted=0; p = ⊤ while (fgets(rbuf, DBUFSIZE, rf) != NULL) { Trim(rbuf); if (rbuf[0] == '\0' || rbuf[0] == '#') continue; all++; if (rejrule(rbuf, pw) < 0) { /* reject not suitable rules */ if (debug) message("debug: Rejecting \"%s\"\n", rbuf); continue; } else { if (debug) message("debug: Accepting \"%s\"\n", rbuf); } accepted++; p->next = (struct RULE *)Malloc(sizeof(struct RULE)); p->next->rule = newstr(rbuf); p = p->next; } p->next = NULL; if (showacceptrate) message("%d/%d rules are accepted\n", accepted, all); return top.next; } docrack(pw, rules, df) char *pw; struct RULE *rules; FILE *df; { register char *mangled; register struct RULE *rp; struct RULE rtop; char dword[DBUFSIZE]; rtop.next = rules; while (fgets(dword, DBUFSIZE, df) != NULL) { if (comment) { Trim(dword); /* remove space characters at end of line */ if (dword[0] == '\0' || dword[0] == '#') continue; /* skip comments and empty lines */ } else { dword[strlen(dword)-1] = '\0'; /* remove the newline */ } rp = &rtop; while (rp->next != NULL) { mangled = Mangle(dword, rp->next->rule); if (mangled == (char *)0) goto contpoint; /* the rule is rejected */ if (!strncmp(pw, mangled, PWLEN)) { if (showcracked) message("\"%s\" (%s) -> \"%s\"\n", dword, rp->next->rule, pw); return 1; } contpoint: rp = rp->next; } } return 0; } showrules(rules) struct RULE *rules; { struct RULE top, *rp; top.next = rules; rp = ⊤ message("*** accepted rules ***\n"); while (rp->next != NULL) { message("\"%s\"\n", rp->next->rule); rp = rp->next; } return; }