/* weplab - Wep Key Cracker Copyright (C) 2004 Jose Ignacio Sanchez Martin - Topo[LB] 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------- dictionary.c: dictionary based wep crack. */ #include #include #include #include #include #include #include #include #include #include #include "md5.h" #include "wep.h" #include "globals.h" #include "debug.h" #include "dictionary.h" #include "attack.h" /* This section of the code was riped from the wep_tools archive from Tim Newsham * http://lava.net/~newsham/wlan/ */ #define WEPWEAKKEYSIZE 5 #define WEPSTRONGKEYSIZE 13 #define WEPKEYS 4 #define WEPKEYSTORE (WEPWEAKKEYSIZE * WEPKEYS) /* * generate four subkeys from a seed using the defacto standard */ void wep_seedkeygen40(int val, u_char *keys){ int i; for(i = 0; i < WEPKEYSTORE; i++) { val *= 0x343fd; val += 0x269ec3; keys[i] = val >> 16; } return; } /* * generate one key from a string using the de facto standard * * resultant key is stored in * one 128 bit key: keys[0-12] */ void wep_keygen128(char *str, unsigned char *keys){ struct MD5Context ctx; unsigned char buf[64]; int i, j; /* repeat str until buf is full */ j = 0; for(i = 0; i < 64; i++) { if(str[j] == 0) j = 0; buf[i] = str[j++]; } MD5Init(&ctx); MD5Update(&ctx, buf, sizeof buf); MD5Final(buf, &ctx); memcpy(keys, buf, WEPKEYSTORE); for(i = 0; i < WEPSTRONGKEYSIZE; i++) { keys[i] = buf[i]; } for(; i < WEPKEYSTORE; i++) { keys[i] = 0; } return; } /* * generate four subkeys from a string using the defacto standard * * resultant keys are stored in keys[0-4], keys[5-9], keys[10-14] * and keys[15-20] */ void wep_keygen40(char *str, u_char *keys){ int val, i, shift; /* * seed is generated by xor'ing in the keystring bytes * into the four bytes of the seed, starting at the little end */ val = 0; for(i = 0; str[i]; i++) { shift = i & 0x3; val ^= (str[i] << (shift * 8)); } wep_seedkeygen40(val, keys); return; } /* End of ripped code section. We are back to my horrible coding style ;) */ unsigned long int dtotalTests=0; short ndTotalTests=0; unsigned char keys[WEPKEYSTORE]; unsigned char last_keys[WEPKEYSTORE]; time_t initialTime; time_t lastTime; time_t actualTime; int WEPKeyID=0; pid_t arrayProcesses[64]; int dcurrentProcessNumber=0; FILE* wordfile; int GetNextWord(unsigned char *word, int sz){ int i; char* rv=NULL; bzero(word, sz); while (((rv=fgets(word, sz-1, wordfile))!=NULL)&&((word[0]=='\r')||(word[0]=='\n'))) { /* We didn't get valuable data :( */ ; } for (i=1; i<=sz-1; i++) /* We turn CR and LF to '\0' because fgets likes to put them in our buffer */ if((word[i]=='\n')||(word[i]=='\r')) { word[i]=0; break; } return (rv == NULL)?-1:0; } void catch_dint(int sig_num){ int i; if (!dcurrentProcessNumber) for (i=1; i",dcurrentProcessNumber); if (!ndTotalTests) printf(" %lu keys tested [",dtotalTests); else printf(" %d * %lu keys tested [",ndTotalTests, dtotalTests); if (actualTime-lastTime) printf("%lu c/s] >>> ",(unsigned long int)dtotalTests/(actualTime-lastTime)); if (defaultAttacks[STABILITY_LEVELS][1]) printf(" s:\"%s\" ", last_keys); else if (global_v.key_len == WEPWEAKKEYSIZE) { printf("Key index: %d, ", WEPKeyID); ViewKey (&last_keys[WEPKeyID*5], global_v.key_len); } else ViewKey (last_keys, global_v.key_len); printf("\n"); } void dictionary (void){ t_storedPacket *packets[10]; unsigned char word[100]; pcap_t *file; pid_t mpid; int i; int c; int totalPackets; //unsigned char key2[13]="\x3e\x9a\xa0\xa4\xc6\x2e\xad\x59\x5a\x07\xa1\x80\x1f"; int trues; int totalByte=0xFF; int totalTemp=0; #ifdef _DEBUG debug("Starting Dictionary based cracking."); #endif file=OpenPcapFile(global_v.packetsFilename); signal(SIGUSR1,SIG_IGN); /* We could be able to use other file than STDIN by fopen'ing */ if (!strcmp(global_v.wordfile,"")) wordfile=stdin; else{ wordfile=fopen(global_v.wordfile,"r"); if (wordfile==NULL){ printf("\n ERROR opening the wordfile %s for reading\n\n",global_v.wordfile); exit(1); } } for (i=0; i<10; i++) { packets[i]=malloc(sizeof(t_storedPacket)); packets[i]->packet=NULL; } totalPackets=GetLessSizedPackets(file, packets); DebugView10Packets(packets, totalPackets); ClosePcapFile(file); for (i=0; i %s\n",word); ViewKey(keys, global_v.key_len); exit(1); } } } else if (VerifyPacketWithKey(packets[0], keys )){ printf("It seems that the first control data packet verifies the key! Let's test it with others....\n"); if (Verify10PacketsWithKey(packets, keys )>2){ printf("Right KEY found!!\n"); printf("Passphrase was --> %s\n",word); ViewKey(keys, global_v.key_len); exit(1); } } if((GetNextWord(word, sizeof(word)))==-1) { /* We have reached the end of the file, let's print stats and quit */ kill(getpid(), SIGUSR1); exit(1); } /* Find which kind of attack we are asked to perform */ if (defaultAttacks[STABILITY_LEVELS][1]) { /* We are asked to perform basic ascii test * We just have to backup the last key for the SIGUSR1 catching function that will print the last word */ bzero(keys, global_v.key_len+1); strncpy(keys, word, global_v.key_len); bzero(last_keys, global_v.key_len+1); strcpy(last_keys, keys); if (global_v.debug >1) { printf("We generate this "); ViewKey (keys, global_v.key_len); } } else { /* We work with real world key generation algorithm */ if (global_v.key_len == WEPSTRONGKEYSIZE) { wep_keygen128(word, keys); if (global_v.debug >1) { printf("We generate this "); ViewKey (keys, global_v.key_len); } } else { wep_keygen40(word, keys); if (global_v.debug >1) { printf("We generate these four keys : \n"); printf("Index 1 - "); ViewKey (keys, global_v.key_len); printf("Index 2 - "); ViewKey (&keys[5], global_v.key_len); printf("Index 3 - "); ViewKey (&keys[10], global_v.key_len); printf("Index 4 - "); ViewKey (&keys[15], global_v.key_len); printf("..... end\n"); } } memcpy(last_keys, keys, WEPKEYSTORE); } } }else{ //fclose(wordfile); arrayProcesses[0]=mpid; printf("\n\nStatistical cracking started! Please hit enter to get statistics from John.\nWeplab statistics will be printed each 5 seconds\n\n"); while (!waitpid(0,NULL,WNOHANG)) { if (wordfile != stdin){ c=getchar(); } else { /* We can't wait for keyboard input as we are reading the dictionnary file from stdin ! * So we just sleep 10 seconds and print stats */ sleep(5); c='\n'; } if (c=='\n') kill(mpid,SIGUSR1); } printf("This was the end of the dictionnary attack.\n"); } trues=Verify10PacketsWithKey(packets, keys /* XXX */ ); if (trues) printf("HURRA! %d packets verified the key!",trues); }