Created
December 21, 2025 20:40
-
-
Save santaklouse/93e4214837408f64c4fb96df06f7fcf8 to your computer and use it in GitHub Desktop.
cowpatty patch from http://proton.cygnusx-1.org/~edgan/cowpatty/cowpatty-4.6-fixup16.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment