Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Created December 21, 2025 20:40
Show Gist options
  • Select an option

  • Save santaklouse/93e4214837408f64c4fb96df06f7fcf8 to your computer and use it in GitHub Desktop.

Select an option

Save santaklouse/93e4214837408f64c4fb96df06f7fcf8 to your computer and use it in GitHub Desktop.
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