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
/*
 * author: kay ~ irc.nullnetwork.net
 * date: 28/11/2005
 * id like to be contacted if this code is every used anywhere else. just so i know.
 * 
 * very simple DES brute force password hash cracker. if you have trouble
 * figuring out how to use it contact me. basic usage: ./force hashhere.
 */
 
#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++;
		//sleep(1); //very small pause
		
		brute(t, o + 1, &opt, 0, hash);
	}
	/*
	if (o==0) {
		printf("exiting at %s (%d)\n", t, cnt);
	}
	*/
	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': //charset
				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': //word length
				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': //output file
				i++;
				if (i < argc) {
					opts.fp = fopen(argv[i], "w");
				} else {
					printf("Expected: filename\n");
					return 1;
				}
				break;
			case 'v': //verbose
				verbose++;
				break;
			case 'h': //help
				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 {
			//assume this is the hash
			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); //set it to the first result
	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;

}