void dump_all_fields(struct crack_data cdata, struct user_opt *opt) { printf("AA is:"); lamont_hdump(cdata.aa, 6); printf("\n"); printf("SPA is:"); lamont_hdump(cdata.spa, 6); printf("\n"); printf("snonce is:"); lamont_hdump(cdata.snonce, 32); printf("\n"); printf("anonce is:"); lamont_hdump(cdata.anonce, 32); printf("\n"); printf("keymic is:"); lamont_hdump(cdata.keymic, 16); printf("\n"); printf("eapolframe is:"); if (opt->nonstrict == 0) { lamont_hdump(cdata.eapolframe, 99); } else { lamont_hdump(cdata.eapolframe, 125); } printf("\n"); }
void dump_all_fields(struct crack_data cdata) { printf("AA is:"); lamont_hdump(cdata.aa, 6); printf("\n"); printf("SPA is:"); lamont_hdump(cdata.spa, 6); printf("\n"); printf("snonce is:"); lamont_hdump(cdata.snonce, 32); printf("\n"); printf("anonce is:"); lamont_hdump(cdata.anonce, 32); printf("\n"); printf("keymic is:"); lamont_hdump(cdata.keymic, 16); printf("\n"); printf("eapolframe is:"); lamont_hdump(cdata.eapolframe, 99); /* Bug in lamont_hdump makes this look wrong, only shows 98 bytes */ printf("\n"); }
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 hashfile_attack(struct user_opt *opt, char *passphrase, struct crack_data *cdata) { FILE *fp; int reclen, wordlen; u8 pmk[32]; u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; struct hashdb_rec rec; struct hashdb_head hf_head; char headerssid[33]; /* Open the hash file */ if (*opt->hashfile == '-') { printf("Using STDIN for hashfile contents.\n"); fp = stdin; } else { fp = fopen(opt->hashfile, "rb"); if (fp == NULL) { perror("fopen"); return(-1); } } /* Read the record header contents */ if (fread(&hf_head, sizeof(hf_head), 1, fp) != 1) { perror("fread"); return(-1); } /* Ensure selected SSID matches what's stored in the header record */ if (memcmp(hf_head.ssid, opt->ssid, hf_head.ssidlen) != 0) { memcpy(&headerssid, hf_head.ssid, hf_head.ssidlen); headerssid[hf_head.ssidlen] = 0; /* NULL terminate string */ fprintf(stderr, "\nSSID in hashfile (\"%s\") does not match " "SSID specified on the \n" "command line (\"%s\"). You cannot " "mix and match SSID's for this\nattack.\n\n", headerssid, opt->ssid); return(-1); } while (feof(fp) == 0 && sig == 0) { /* Populate the hashdb_rec with the next record */ reclen = nexthashrec(fp, &rec); /* nexthashrec returns the length of the record, test to ensure passphrase is greater than 8 characters */ wordlen = rec.rec_size - (sizeof(rec.pmk) + sizeof(rec.rec_size)); if (wordlen < 8) { printf("Found a record that was too short, this " "shouldn't happen in practice!\n"); return(-1); } /* Populate passphrase with the record contents */ memcpy(passphrase, rec.word, wordlen); /* NULL terminate passphrase string */ passphrase[wordlen] = 0; if (opt->verbose > 1) { printf("Testing passphrase: %s\n", passphrase); } /* Increment the words tested counter */ wordstested++; /* Status display */ #ifdef FPGA if ((wordstested % 1000) == 0) { #else if ((wordstested % 10000) == 0) { #endif printf("key no. %ld: %s\n", wordstested, passphrase); fflush(stdout); } if (opt->verbose > 1) { printf("Calculating PTK for \"%s\".\n", passphrase); } 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"); } wpa_pmk_to_ptk(rec.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; } } return 1; } #ifdef FPGA struct crack_data *cdata_g; struct user_opt *opt_g; struct timeval start_g; int dictfile_found(unsigned char *pmk, char *passphrase) { u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; struct timeval end; if (opt_g->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt_g->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } wpa_pmk_to_ptk(pmk, cdata_g->aa, cdata_g->spa, cdata_g->anonce, cdata_g->snonce, ptk, sizeof(ptk)); if (opt_g->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt_g->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } hmac_md5(ptkset->mic_key, 16, cdata_g->eapolframe, sizeof(cdata_g->eapolframe), keymic); if (opt_g->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata_g->keymic, &keymic, sizeof(keymic)) == 0) { printf("\nThe PSK is \"%s\".\n", passphrase); } else { return 1; } gettimeofday(&end, NULL); printstats(start_g, end, wordstested); exit(0); return 0; }
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; }
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; /* 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 (%u).\n", passphrase, strlen(passphrase)); } continue; } else { /* This word is good, increment the words tested counter */ wordstested++; } /* Status display */ if ((wordstested % 1000) == 0) { 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); 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"); } 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"); } if (opt->nonstrict == 0) { hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe, sizeof(cdata->eapolframe), keymic); } else { hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe, cdata->eapolframe_size, 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; } } return 1; }