Logo Search packages:      
Sourcecode: weplab version File versions  Download package

dictionary.c

/*

      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 <pcap.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#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<global_v.processes; i++) kill(arrayProcesses[i],SIGUSR1);
      signal(SIGUSR1, catch_dint);
      actualTime=time(NULL);
      printf("Process number: %u ===>",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<global_v.key_len; i++) keys[i]=0;

      dcurrentProcessNumber=0;            
      
        if ((global_v.key_len == WEPWEAKKEYSIZE) && ( !defaultAttacks[STABILITY_LEVELS][1] )) {
        /* Let's find the index of the WEP Key of this packet because we are going to use the 40bits hash generator */
                        for (i=1;i<10;i++) {
                          WEPKeyID=0;
                                memcpy(&WEPKeyID, packets[i]+LEN_IV, LEN_ID);
                                printf("The id for the packet number %d is %d\n", i, WEPKeyID);
                        }
        memcpy(&WEPKeyID, packets[0]+LEN_IV, LEN_ID);
        WEPKeyID=WEPKeyID&0x3;
        printf("The id for the first packet is %d\n", WEPKeyID);
      }
      
// TEST
      initialTime=time(NULL);
      lastTime=time(NULL);
      if (!dcurrentProcessNumber) mpid=fork();
      else mpid=0;
      if (!(mpid)){     
            signal(SIGUSR1, catch_dint);
            while (1){
                  
                  if (!++dtotalTests){
                        lastTime=time(NULL);
                        ndTotalTests++;   
            }
            //ViewKey(keys, global_v.key_len);  printf("\n");
        if ( (global_v.key_len == WEPWEAKKEYSIZE) && ( !defaultAttacks[STABILITY_LEVELS][1]) ) {
                        if (VerifyPacketWithKey(packets[0], &keys[WEPKeyID*5] )){
                                    printf("It seems that the first control data packet verifies the key! Let's test it with others....\n");
                              trues=0;
                                    for (i=1;i<10;i++) {
                                          WEPKeyID=0;
                                    memcpy(&WEPKeyID, packets[i]+LEN_IV, LEN_ID);
                                          printf("The id for the packet number %d is %d\n", i, WEPKeyID);
                              if (VerifyPacketWithKey(packets[i], &keys[WEPKeyID*5] )) trues++;
                                    }
                                    if (trues) {
                                          printf("Right KEY found!! (verify score : %d)\n", trues);
                                          printf("Passphrase was --> %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);   
}


Generated by  Doxygen 1.6.0   Back to index