diff -uNr cowpatty-4.6/cowpatty.c cowpatty-4.6-fixup14/cowpatty.c --- cowpatty-4.6/cowpatty.c 2009-07-03 08:15:50.000000000 -0700 +++ cowpatty-4.6-fixup14/cowpatty.c 2009-07-17 19:16:21.792816008 -0700 @@ -94,8 +94,7 @@ "\t-d \tHash file (genpmk)\n" "\t-r \tPacket capture file\n" "\t-s \tNetwork SSID (enclose in quotes if SSID includes spaces)\n" - "\t-2 \tUse frames 1 and 2 or 2 and 3 for key attack (nonstrict mode)\n" - "\t-c \tCheck for valid 4-way frames, does not crack\n" + "\t-c \tCheck for valid 4-way frames, does not crack\n" "\t-h \tPrint this help information and exit\n" "\t-v \tPrint verbose information (more -v for more verbosity)\n" "\t-V \tPrint program version and exit\n" "\n"); @@ -151,7 +150,7 @@ int c; - while ((c = getopt(argc, argv, "f:r:s:d:c2nhvV")) != EOF) { + while ((c = getopt(argc, argv, "f:r:s:d:cnhvV")) != EOF) { switch (c) { case 'f': strncpy(opt->dictfile, optarg, sizeof(opt->dictfile)); @@ -166,9 +165,6 @@ strncpy(opt->hashfile, optarg, sizeof(opt->hashfile)); break; case 'n': - case '2': - opt->nonstrict++; - break; case 'c': opt->checkonly++; break; @@ -435,21 +431,11 @@ cdata->ver = key_info & WPA_KEY_INFO_TYPE_MASK; index = key_info & WPA_KEY_INFO_KEY_INDEX_MASK; - if (opt->nonstrict == 0) { - - /* Check for EAPOL version 1, type EAPOL-Key */ - if (dot1xhdr->version != 1 || dot1xhdr->type != 3) { - return; - } - - } else { - - /* Check for type EAPOL-Key */ - if (dot1xhdr->type != 3) { - return; - } - + /* Check for type EAPOL-Key */ + if (dot1xhdr->type != 3) { + return; } + if (cdata->ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && cdata->ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { return; @@ -457,12 +443,12 @@ if (cdata->ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) { /* Check for WPA key, and pairwise key type */ - if (eapolkeyhdr->type != 254 || + if ((eapolkeyhdr->type != 2 && eapolkeyhdr->type != 254) || (key_info & WPA_KEY_INFO_KEY_TYPE) == 0) { return; } } else if (cdata->ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { - if (eapolkeyhdr->type != 2 || + if ((eapolkeyhdr->type != 2 && eapolkeyhdr->type != 254) || (key_info & WPA_KEY_INFO_KEY_TYPE) == 0) { return; } @@ -472,19 +458,22 @@ /* Check for frame 2 of the 4-way handshake */ if ((key_info & WPA_KEY_INFO_MIC) - && (key_info & WPA_KEY_INFO_ACK) == 0 - && (key_info & WPA_KEY_INFO_INSTALL) == 0 - && eapolkeyhdr->key_data_length > 0) { + && (key_info & WPA_KEY_INFO_ACK) == 0 + && (key_info & WPA_KEY_INFO_INSTALL) == 0 + && eapolkeyhdr->key_data_length > 0) { /* All we need from this frame is the authenticator nonce */ memcpy(cdata->snonce, eapolkeyhdr->key_nonce, sizeof(cdata->snonce)); cdata->snonceset = 1; + memcpy(cdata->replay_counter1, + eapolkeyhdr->replay_counter, 8); + cdata->replay_counter1[7] = cdata->replay_counter1[7] + 1; /* Check for frame 3 of the 4-way handshake */ } else if ((key_info & WPA_KEY_INFO_MIC) - && (key_info & WPA_KEY_INFO_INSTALL) - && (key_info & WPA_KEY_INFO_ACK)) { + && (key_info & WPA_KEY_INFO_INSTALL) + && (key_info & WPA_KEY_INFO_ACK)) { memcpy(cdata->spa, &packet[capdata->dstmac_offset], sizeof(cdata->spa)); @@ -497,15 +486,17 @@ cdata->anonceset = 1; /* We save the replay counter value in the 3rd frame to match against the 4th frame of the four-way handshake */ - memcpy(cdata->replay_counter, + memcpy(cdata->replay_counter2, eapolkeyhdr->replay_counter, 8); /* Check for frame 4 of the four-way handshake */ } else if ((key_info & WPA_KEY_INFO_MIC) - && (key_info & WPA_KEY_INFO_ACK) == 0 - && (key_info & WPA_KEY_INFO_INSTALL) == 0 - && (memcmp (cdata->replay_counter, - eapolkeyhdr->replay_counter, 8) == 0)) { + && (key_info & WPA_KEY_INFO_ACK) == 0 + && (key_info & WPA_KEY_INFO_INSTALL) == 0 + && (memcmp (cdata->replay_counter1, + cdata->replay_counter2, 8) == 0) + && (memcmp (cdata->replay_counter2, + eapolkeyhdr->replay_counter, 8) == 0)) { memcpy(cdata->keymic, eapolkeyhdr->key_mic, sizeof(cdata->keymic)); @@ -513,57 +504,76 @@ sizeof(cdata->eapolframe)); cdata->keymicset = 1; cdata->eapolframeset = 1; + cdata->counters = 1; } - } else { - - /* Check for frame 1 of the 4-way handshake */ - if ((key_info & WPA_KEY_INFO_MIC) == 0 - && (key_info & WPA_KEY_INFO_ACK) - && (key_info & WPA_KEY_INFO_INSTALL) == 0 ) { - /* All we need from this frame is the authenticator nonce */ - memcpy(cdata->anonce, eapolkeyhdr->key_nonce, - sizeof(cdata->anonce)); - cdata->anonceset = 1; - - /* Check for frame 2 of the 4-way handshake */ - } else if ((key_info & WPA_KEY_INFO_MIC) - && (key_info & WPA_KEY_INFO_INSTALL) == 0 - && (key_info & WPA_KEY_INFO_ACK) == 0 - && eapolkeyhdr->key_data_length > 0) { - cdata->eapolframe_size = ( packet[capdata->dot1x_offset + 2] << 8 ) - + packet[capdata->dot1x_offset + 3] + 4; - - memcpy(cdata->spa, &packet[capdata->dstmac_offset], - sizeof(cdata->spa)); - cdata->spaset = 1; - - memcpy(cdata->aa, &packet[capdata->srcmac_offset], - sizeof(cdata->aa)); - cdata->aaset = 1; - - memcpy(cdata->snonce, eapolkeyhdr->key_nonce, - sizeof(cdata->snonce)); - cdata->snonceset = 1; + } else { - memcpy(cdata->keymic, eapolkeyhdr->key_mic, - sizeof(cdata->keymic)); - cdata->keymicset = 1; + /* Check for frame 1 of the 4-way handshake */ + if ((key_info & WPA_KEY_INFO_MIC) == 0 + && (key_info & WPA_KEY_INFO_ACK) + && (key_info & WPA_KEY_INFO_INSTALL) == 0 ) { + + /* All we need from this frame is the authenticator nonce */ + memcpy(cdata->anonce, eapolkeyhdr->key_nonce, + sizeof(cdata->anonce)); + cdata->anonceset = 1; + + memcpy(cdata->replay_counter1, + eapolkeyhdr->replay_counter, 8); + cdata->replay_counter1[7] = cdata->replay_counter1[7] + 1; + + /* Check for frame 2 or 4 of the 4-way handshake */ + } else if ((key_info & WPA_KEY_INFO_MIC) + && (key_info & WPA_KEY_INFO_INSTALL) == 0 + && (key_info & WPA_KEY_INFO_ACK) == 0) { + + cdata->eapolframe_size = ( packet[capdata->dot1x_offset + 2] << 8 ) + + packet[capdata->dot1x_offset + 3] + 4; + + memcpy(cdata->spa, &packet[capdata->dstmac_offset], + sizeof(cdata->spa)); + cdata->spaset = 1; + + memcpy(cdata->aa, &packet[capdata->srcmac_offset], + sizeof(cdata->aa)); + cdata->aaset = 1; + + memcpy(cdata->snonce, eapolkeyhdr->key_nonce, + sizeof(cdata->snonce)); + cdata->snonceset = 1; + + memcpy(cdata->keymic, eapolkeyhdr->key_mic, + sizeof(cdata->keymic)); + cdata->keymicset = 1; + + memcpy(cdata->eapolframe, &packet[capdata->dot1x_offset], + cdata->eapolframe_size); + cdata->eapolframeset = 1; - memcpy(cdata->eapolframe, &packet[capdata->dot1x_offset], - cdata->eapolframe_size); - cdata->eapolframeset = 1; + memcpy(cdata->replay_counter2, + eapolkeyhdr->replay_counter, 8); + cdata->replay_counter2[7] = cdata->replay_counter2[7] + 1; + memcpy(cdata->replay_counter3, + eapolkeyhdr->replay_counter, 8); + cdata->replay_counter3[7] = cdata->replay_counter3[7] + 2; + + /* Check for frame 3 of the 4-way handshake */ + } else if ((key_info & WPA_KEY_INFO_MIC) + && (key_info & WPA_KEY_INFO_ACK) + && (key_info & WPA_KEY_INFO_INSTALL)) { + + /* All we need from this frame is the authenticator nonce */ + memcpy(cdata->anonce, eapolkeyhdr->key_nonce, + sizeof(cdata->anonce)); + cdata->anonceset = 1; + + memcpy(cdata->replay_counter4, + eapolkeyhdr->replay_counter, 8); + cdata->replay_counter4[7] = cdata->replay_counter4[7] + 1; + } - /* Check for frame 3 of the 4-way handshake */ - } else if ((key_info & WPA_KEY_INFO_MIC) - && (key_info & WPA_KEY_INFO_ACK) - && (key_info & WPA_KEY_INFO_INSTALL)) { - /* All we need from this frame is the authenticator nonce */ - memcpy(cdata->anonce, eapolkeyhdr->key_nonce, - sizeof(cdata->anonce)); - cdata->anonceset = 1; - } } } @@ -982,10 +992,82 @@ } } + 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.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); diff -uNr cowpatty-4.6/cowpatty.h cowpatty-4.6-fixup14/cowpatty.h --- cowpatty-4.6/cowpatty.h 2009-06-04 06:24:16.000000000 -0700 +++ cowpatty-4.6-fixup14/cowpatty.h 2009-07-17 16:16:58.043152023 -0700 @@ -178,7 +178,11 @@ u8 anonceset; u8 keymicset; u8 eapolframeset; - u8 replay_counter[8]; + u8 replay_counter1[8]; + u8 replay_counter2[8]; + u8 replay_counter3[8]; + u8 replay_counter4[8]; + u8 counters; int ver; /* Hashing algo, MD5 or AES-CBC-MAC */ int eapolframe_size;