#include "includes.h" void str_to_key(unsigned char *str,unsigned char *key); void usage(char *progname); void fill_user_struct(int, char *dastring, struct user_struct *da_struct); void LMword(char *passwd, char *word); char *atob(char *hexstring,int size); int htoi(char c); int PutUniCode(char *dst,char *src); int isvalid_userline(int, char *str); /* * Convert a 7 byte array into an 8 byte des key with odd parity. */ void str_to_key(unsigned char *str,unsigned char *key) { void des_set_odd_parity(des_cblock *); int i; key[0] = str[0]>>1; key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); key[7] = str[6]&0x7F; for (i=0;i<8;i++) { key[i] = (key[i]<<1); } des_set_odd_parity((des_cblock *)key); } void usage(char *progname){ char *p; p = strrchr(progname, '\\'); if (p == NULL) p = progname; else p++; fprintf(stderr, "Usage: %s -p -w -o -b" " [-l || n]\n", p); fprintf(stderr, " -p The password file to read from in pwdump format\n"); fprintf(stderr, " -P The password file to read from in sniffer format\n"); fprintf(stderr, " -w The dictionary of words to try\n"); fprintf(stderr, " -o File to write results to - if not\n"); fprintf(stderr, " specified defaults to stdout\n"); fprintf(stderr, " -b Brute force through the entire keyspace\n"); fprintf(stderr, " \n"); fprintf(stderr, " -l Only go after the LANMAN password\n"); fprintf(stderr, " -n Only go after the NT Dialect password [dumb!]\n"); fprintf(stderr, " without the -l or -n it goes after both\n"); fprintf(stderr, " which is still much faster than going after\n"); fprintf(stderr, " the NT Dialect password only!\n"); fprintf(stderr, "\n"); fprintf(stderr, " Note: Both -p and -w are required, unless -b is" " specified\n"); fprintf(stderr, " in which case -w must be ommited\n"); fprintf(stderr, " mudge@l0pht.com\n"); exit(1); } void fill_user_struct(int pwdump, char *dastring, struct user_struct *da_struct){ char *tmp, *atobstr; /* clear out the sucker */ memset(da_struct, '\0', sizeof(struct user_struct)); da_struct->pwdumpval = pwdump; if (pwdump){ strncpy(da_struct->username, strtok(dastring, ":"), 128); strtok(NULL, ":"); /* skip over UID */ tmp = strtok(NULL, ":"); if (strncmp(tmp, "NO PASSWORD", 11) == 0){ strcpy(da_struct->lmhash, "DISABLED?"); strcpy(da_struct->nthash, "DISABLED?"); } else if (strncmp(tmp, "********", 8) == 0){ strcpy(da_struct->lmhash, "NULL PASSWD?"); strcpy(da_struct->nthash, "NULL PASSWD?"); } else { strncpy(da_struct->lmhash, tmp, 32); strncpy(da_struct->nthash, strtok(NULL, ":"), 32); } if ((strncmp(da_struct->lmhash, "DISABLED?", 9) != 0) \ && (strncmp(da_struct->lmhash, "NULL PASSWD?", 12) != 0 )){ atobstr = atob(da_struct->lmhash, 32); memcpy(da_struct->lmhashb, atobstr, 16); free(atobstr); atobstr = atob(da_struct->nthash, 32); memcpy(da_struct->nthashb, atobstr, 16); free(atobstr); } /* if the second part of the lanman key is 0xAAD3B435B51404EE then the password is 7 chars or less and we don't need to spin the extra CPU cycles */ if (memcmp(&(da_struct->lmhash[16]), "AAD3B435B51404EE", 16) == 0) da_struct->under7 = 1; else da_struct->under7 = 0; } else { /* we are reading from a sniffer file */ strncpy(da_struct->username, strtok(dastring, ":"), 128); tmp = strtok(NULL, ":"); /* get the password length */ if (atoi(tmp) >= 7) da_struct->under7 = 0; else da_struct->under7 = 1; tmp = strtok(NULL, ":"); /* get the 8byte challenge - note that we have it stored in ascii so it is 16 bytes to begin with */ atobstr = atob(tmp, 16); memcpy(da_struct->server_chall, atobstr, 8); free(atobstr); tmp = strtok(NULL, ":"); atobstr = atob(tmp, 48); memcpy(da_struct->lmresp_b, atobstr, 24); free(atobstr); tmp = strtok(NULL, ":"); atobstr = atob(tmp, 48); memcpy(da_struct->ntresp_b, atobstr, 24); free(atobstr); } da_struct->lmdone = 0; da_struct->ntdone = 0; da_struct->already_printed = 0; da_struct->next = NULL; da_struct->previous = NULL; } void LMword(char *passwd, char *word){ size_t i; int word_len; word_len = strlen(word); for (i=0; i < word_len; i++) word[i] = toupper(word[i]); if (word_len < 14){ memcpy(passwd, word, strlen(word)); for (i=0; i<= (strlen(passwd)); i++){ if ((passwd[i] == '\r') || (passwd[i] == '\n')) passwd[i] = '\0'; } } else memcpy(passwd, word, 14); } /* the routines atob() and htoi() were lifted from code by Josh Daymont - with only minor modifications */ char *atob(char *hexstring,int size) { int i, value; unsigned char c; char *str1, *str2; value = (size/2)+1; str1 = (char *)(malloc((unsigned)value)); str2 = str1; /* save pointer to beginning */ for (i=0; i