Filename: force.c
Size: 4601 bytes
Lines: 189
Creation time: 1267738157 (2010-03-04)
Description: This is a DES brute force cracker. Note that code wasn't designed to be efficient, it was merely supposed to show how you may go about building a cracker. Generally the recursive method I employ would probably not be used in practical crackers due to resource usage.
Download
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct options {
FILE *fp;
char * charset;
int setlen;
int maxlen;
char salt[9];
};
int brute(char * s, int o, void * p, int initialcall, char * hash);
int die = 0;
int verbose = 0;
int brute(char * s, int o, void * p, int initialcall, char * hash) {
char * t;
int c = 0, d = 0;
static int cnt=0;
struct options * opt0 = (struct options *)p;
struct options opt = *opt0;
FILE *fp = opt.fp;
char buf[20];
char * set = opt.charset;
t = (char *)malloc(opt.maxlen + 1);
memset(t, 0, opt.maxlen + 1);
strcpy(t, s);
if (o == opt.maxlen) {
return cnt;
}
for(c = 0 ; c < opt.setlen ; c++) {
if (die) break;
*(t + o) = *(opt.charset + c);
if (fp!=NULL) {
fwrite (t,1,strlen(t),fp);
fwrite ("\n",1,1,fp);
} else {
memset(buf, 0, 20);
strncpy(buf, (char *)crypt(t, opt.salt), 20);
if (hash) {
if (verbose) printf("comparing '%s' against '%s' (%s)\n", hash, buf, t);
if (strncmp(hash, buf, strlen(hash)) == 0 && strlen(hash) == strlen(buf)) {
printf("Found it! %s\n", t);
die = 1;
break;
}
} else {
printf("%s (%s)\n", t, buf);
}
}
cnt++;
brute(t, o + 1, &opt, 0, hash);
}
free(t);
return cnt;
}
int isnumerical(char * s, int l) {
int i;
for(i = 0; i < l; i++) {
if (isdigit(*s)==0) {
return 0;
}
s++;
}
return 1;
}
void signal_handler(int sig) {
if (sig==SIGTERM || sig==SIGINT || sig==SIGABRT) {
printf("%s caught. Cleaning up...\n",( sig==SIGTERM || sig==SIGABRT ? ( sig==SIGABRT ? "SIGABRT" : "SIGTERM") : "SIGINT"));
exit(1);
}
}
int main (int argc, char **argv) {
char * s, * hash = NULL;
int i = 0;
struct options opts;
opts.charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
opts.setlen = strlen(opts.charset);
opts.maxlen = 3;
opts.fp = NULL;
opts.salt[0]='h';
opts.salt[1]='k';
opts.salt[2]='\0';
signal(SIGTERM,signal_handler);
signal(SIGINT,signal_handler);
signal(SIGABRT,signal_handler);
for (i = 1; i < argc; i++) {
if (strncmp(argv[i], "-", 1) == 0) {
switch (argv[i][1]) {
case 'c': i++;
if (i < argc) {
opts.setlen = strlen(argv[i]);
opts.charset = (char *)malloc(opts.setlen + 1);
memset(opts.charset, 0, opts.setlen + 1);
strncpy(opts.charset, argv[i], opts.setlen);
} else {
printf("Expected: character set string\n");
return 1;
}
break;
case 'n': i++;
if (i < argc) {
if (isnumerical(argv[i],strlen(argv[i]))) {
opts.maxlen = atoi(argv[i]);
} else {
printf("'%s' is not a valid number\n", argv[i]);
return 1;
}
} else {
printf("Expected: string length\n");
return 1;
}
break;
case 'f': i++;
if (i < argc) {
opts.fp = fopen(argv[i], "w");
} else {
printf("Expected: filename\n");
return 1;
}
break;
case 'v': verbose++;
break;
case 'h': printf("Usage: brute [-n number-of-letters] [-c character-set] [-f filename] [-v] hash\n\nnote: -f will not perform a crack, itll just out put all combinations configured\n");
return 0;
default:
printf("Unknown option. Try -h for help.\n");
}
} else {
switch (strlen(argv[i])) {
case 13:
opts.salt[0] = argv[i][0];
opts.salt[1] = argv[i][1];
opts.salt[2] = '\0';
printf("Attacking %s (%s) using salt '%s'...\n", argv[i], "DES", opts.salt);
hash = argv[i];
break;
default:
printf("the format of %s is of an unimplemented hash at this time\n", argv[i]);
}
}
}
s = (char *)malloc(opts.maxlen + 1);
memset(s, 0, opts.maxlen + 1);
if (verbose) printf("maxlen=%d charset='%s' hash='%s'\n", opts.maxlen, opts.charset, hash);
*s = *(opts.charset); printf("combinations tested: %d\n", brute(s, 0, &opts, 0, hash));
free(opts.charset);
free(s);
if (opts.fp!=NULL) {
close(opts.fp);
}
return 0;
}