diff -uNr cowpatty-4.6/cowpatty.c cowpatty-4.6-fixup16/cowpatty.c --- cowpatty-4.6/cowpatty.c 2009-07-03 08:15:50.000000000 -0700 +++ cowpatty-4.6-fixup16/cowpatty.c 2009-08-01 13:26:14.820815924 -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; @@ -271,6 +267,7 @@ case DLT_IEEE802_11: case DLT_PRISM_HEADER: case DLT_IEEE802_11_RADIO: + case DLT_PPI: break; default: /* Unknown/unsupported pcap type */ @@ -293,7 +290,9 @@ /* Assume it's a libpcap file for now */ int ret; struct ieee80211_radiotap_header *rtaphdr; + struct ieee80211_radiotap_header *ppihdr; int rtaphdrlen=0; + int ppihdrlen=0; struct dot11hdr *dot11 = NULL; /* Loop on pcap_next_ex until we get a packet we want, return from @@ -399,6 +398,37 @@ return(ret); break; + case DLT_PPI: + + ppihdr = (struct ieee80211_radiotap_header *)packet; + ppihdrlen = le16_to_cpu(ppihdr->it_len); + + if (ppihdrlen > (h->len - 10)) { + return -2; + } + + if (ppihdrlen == 24) + ppihdrlen = 32; + + capdata->dstmac_offset = 4 + ppihdrlen; + capdata->srcmac_offset = 10 + ppihdrlen; + + dot11 = ((struct dot11hdr *)(packet+ppihdrlen)); + /* differentiate QoS data and non-QoS data frames */ + if (dot11->u1.fc.subtype == DOT11_FC_SUBTYPE_QOSDATA) { + capdata->dot1x_offset = 34 + ppihdrlen; + capdata->l2type_offset = 32 + ppihdrlen; + } else if (dot11->u1.fc.subtype == + DOT11_FC_SUBTYPE_DATA) { + capdata->dot1x_offset = 32 + ppihdrlen; + capdata->l2type_offset = 30 + ppihdrlen; + } else { + /* Not a data frame we support */ + continue; + } + return(ret); + break; + default: /* Unknown/unsupported pcap type */ return (1); @@ -435,21 +465,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 +477,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 +492,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 +520,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 +538,77 @@ sizeof(cdata->eapolframe)); cdata->keymicset = 1; cdata->eapolframeset = 1; - } - } else { + cdata->counters = 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; - - /* 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 +1027,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-fixup16/cowpatty.h --- cowpatty-4.6/cowpatty.h 2009-06-04 06:24:16.000000000 -0700 +++ cowpatty-4.6-fixup16/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;