diff --git a/docs/changes.txt b/docs/changes.txt index 8b314d757..8e35d547f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -51,6 +51,8 @@ - OpenCL Device: Do a check on available constant memory size and abort if it's less than 64kB - Sessions: Move out handling of multiple instance from restore file into separate pidfile - Wordlists: Disable dictstat handling for hash-mode 3000 as it virtually creates words in the wordlist which is not the case for other modes +- WPA: Changed format for outfile and potfile from essid:mac1:mac2 to hash:essid +- WPA: Changed format for outfile_check from essid:mac1:mac2 to hash * changes v3.20 -> v3.30: diff --git a/include/potfile.h b/include/potfile.h index 257294ef8..1e4a76269 100644 --- a/include/potfile.h +++ b/include/potfile.h @@ -12,9 +12,6 @@ #define INCR_POT 1000 -int sort_by_hash_t_salt (const void *v1, const void *v2); -int sort_by_hash_t_salt_hccap (const void *v1, const void *v2); - int potfile_init (hashcat_ctx_t *hashcat_ctx); int potfile_read_open (hashcat_ctx_t *hashcat_ctx); void potfile_read_close (hashcat_ctx_t *hashcat_ctx); diff --git a/src/interface.c b/src/interface.c index d2ad24b8a..76b4c4abb 100644 --- a/src/interface.c +++ b/src/interface.c @@ -2779,16 +2779,63 @@ int wpa_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED } } - u32 *p0 = (u32 *) in.essid; + // Create a hash of the nonce as ESSID is not unique enough + // Not a regular MD5 but good enough + // We can also ignore cases where we should bzero the work buffer - u32 c0 = 0; - u32 c1 = 0; + u32 hash[4]; - for (int i = 0; i < 8; i++) c0 ^= *p0++; - for (int i = 0; i < 25; i++) c1 ^= wpa->pke[i]; + hash[0] = 0; + hash[1] = 1; + hash[2] = 2; + hash[3] = 3; - salt->salt_buf[10] = c0; - salt->salt_buf[11] = c1; + u32 block[16]; + + u8 *block_ptr = (u8 *) block; + + for (int i = 0; i < 16; i++) block[i] = salt->salt_buf[i]; + + md5_64 (block, hash); + + for (int i = 0; i < 16; i++) block[i] = wpa->pke[i + 0]; + + md5_64 (block, hash); + + for (int i = 0; i < 9; i++) block[i] = wpa->pke[i + 16]; + + md5_64 (block, hash); + + for (int i = 0; i < 16; i++) block[i] = wpa->eapol[i + 0]; + + md5_64 (block, hash); + + for (int i = 0; i < 16; i++) block[i] = wpa->eapol[i + 16]; + + md5_64 (block, hash); + + for (int i = 0; i < 16; i++) block[i] = wpa->eapol[i + 32]; + + md5_64 (block, hash); + + for (int i = 0; i < 16; i++) block[i] = wpa->eapol[i + 48]; + + md5_64 (block, hash); + + for (int i = 0; i < 6; i++) block_ptr[i + 0] = wpa->orig_mac1[i]; + for (int i = 0; i < 6; i++) block_ptr[i + 6] = wpa->orig_mac2[i]; + + md5_64 (block, hash); + + for (int i = 0; i < 32; i++) block_ptr[i + 0] = wpa->orig_nonce1[i]; + for (int i = 0; i < 32; i++) block_ptr[i + 32] = wpa->orig_nonce2[i]; + + md5_64 (block, hash); + + salt->salt_buf[12] = hash[0]; + salt->salt_buf[13] = hash[1]; + salt->salt_buf[14] = hash[2]; + salt->salt_buf[15] = hash[3]; return (PARSER_OK); } @@ -15444,24 +15491,12 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const size_t out_le } else if (hash_mode == 2500) { - wpa_t *wpas = (wpa_t *) esalts_buf; - - wpa_t *wpa = &wpas[salt_pos]; - - snprintf (out_buf, out_len - 1, "%s:%02x%02x%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x", - (char *) salt.salt_buf, - wpa->orig_mac1[0], - wpa->orig_mac1[1], - wpa->orig_mac1[2], - wpa->orig_mac1[3], - wpa->orig_mac1[4], - wpa->orig_mac1[5], - wpa->orig_mac2[0], - wpa->orig_mac2[1], - wpa->orig_mac2[2], - wpa->orig_mac2[3], - wpa->orig_mac2[4], - wpa->orig_mac2[5]); + snprintf (out_buf, out_len - 1, "%08x%08x%08x%08x:%s", + salt.salt_buf[12], + salt.salt_buf[13], + salt.salt_buf[14], + salt.salt_buf[15], + (char *) salt.salt_buf); } else if (hash_mode == 4400) { diff --git a/src/outfile_check.c b/src/outfile_check.c index 27957442c..ec904a0e1 100644 --- a/src/outfile_check.c +++ b/src/outfile_check.c @@ -203,44 +203,13 @@ static int outfile_remove (hashcat_ctx_t *hashcat_ctx) } else if (hash_mode == 2500) { - // BSSID : MAC1 : MAC2 (:plain) - if (i == (salt_buf->salt_len + 1 + 12 + 1 + 12)) + // this comparison is a bit inaccurate as we compare only ESSID + // call it a bug, but it's good enough for a special case used in a special case + // in this case all essid will be marked as cracked that match the essid + + if (i == salt_buf->salt_len) { cracked = (memcmp (line_buf, salt_buf->salt_buf, salt_buf->salt_len) == 0); - - if (!cracked) continue; - - // now compare MAC1 and MAC2 too, since we have this additional info - char *mac1_pos = line_buf + salt_buf->salt_len + 1; - char *mac2_pos = mac1_pos + 12 + 1; - - wpa_t *wpas = (wpa_t *) hashes->esalts_buf; - wpa_t *wpa = &wpas[salt_pos]; - - // compare hex string(s) vs binary MAC address(es) - - for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx++, orig_mac_idx += 2) - { - if (wpa->orig_mac1[mac_idx] != hex_to_u8 ((const u8 *) &mac1_pos[orig_mac_idx])) - { - cracked = 0; - - break; - } - } - - // early skip ;) - if (!cracked) continue; - - for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx++, orig_mac_idx += 2) - { - if (wpa->orig_mac2[mac_idx] != hex_to_u8 ((const u8 *) &mac2_pos[orig_mac_idx])) - { - cracked = 0; - - break; - } - } } } else diff --git a/src/potfile.c b/src/potfile.c index 06bf49bb4..282e35924 100644 --- a/src/potfile.c +++ b/src/potfile.c @@ -5,6 +5,7 @@ #include "common.h" #include "types.h" +#include "bitops.h" #include "convert.h" #include "memory.h" #include "event.h" @@ -21,7 +22,9 @@ int sort_by_hash (const void *v1, const void *v2, void *v3); int sort_by_hash_no_salt (const void *v1, const void *v2, void *v3); // get rid of this later -int sort_by_hash_t_salt (const void *v1, const void *v2) +// this function is for potfile comparison where the potfile does not contain all the +// information requires to do a true sort_by_hash() bsearch +static int sort_by_hash_t_salt (const void *v1, const void *v2) { const hash_t *h1 = (const hash_t *) v1; const hash_t *h2 = (const hash_t *) v2; @@ -29,30 +32,24 @@ int sort_by_hash_t_salt (const void *v1, const void *v2) const salt_t *s1 = h1->salt; const salt_t *s2 = h2->salt; + const int res1 = (int) s1->salt_len - (int) s2->salt_len; + + if (res1 != 0) return (res1); + + //const int res2 = (int) s1->salt_iter - (int) s2->salt_iter; + // + //if (res2 != 0) return (res2); + for (int n = 0; n < 16; n++) { if (s1->salt_buf[n] > s2->salt_buf[n]) return 1; if (s1->salt_buf[n] < s2->salt_buf[n]) return -1; } - return 0; -} - -int sort_by_hash_t_salt_hccap (const void *v1, const void *v2) -{ - const hash_t *h1 = (const hash_t *) v1; - const hash_t *h2 = (const hash_t *) v2; - - const salt_t *s1 = h1->salt; - const salt_t *s2 = h2->salt; - - // last 2: salt_buf[10] and salt_buf[11] contain the digest (skip them) - // 9 * 4 = 36 bytes (max length of ESSID) - - for (int n = 0; n < 9; n++) + for (int n = 0; n < 8; n++) { - if (s1->salt_buf[n] > s2->salt_buf[n]) return 1; - if (s1->salt_buf[n] < s2->salt_buf[n]) return -1; + if (s1->salt_buf_pc[n] > s2->salt_buf_pc[n]) return 1; + if (s1->salt_buf_pc[n] < s2->salt_buf_pc[n]) return -1; } return 0; @@ -441,65 +438,48 @@ int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx) } else if (hashconfig->hash_mode == 2500) { - if (line_hash_len < 64) // 64 = 16 * u32 in salt_buf[] - { - // here we have in line_hash_buf: ESSID:MAC1:MAC2 (without the plain) - - char *mac2_pos = strrchr (line_hash_buf, ':'); - - if (mac2_pos == NULL) continue; + // here we have in line_hash_buf: hash:essid (without the plain) - mac2_pos[0] = 0; - mac2_pos++; + char *sep_pos = strrchr (line_hash_buf, ':'); - if (strlen (mac2_pos) != 12) continue; + if (sep_pos == NULL) continue; - char *mac1_pos = strrchr (line_hash_buf, ':'); + sep_pos[0] = 0; - if (mac1_pos == NULL) continue; + char *hash_pos = line_hash_buf; - mac1_pos[0] = 0; - mac1_pos++; + const size_t hash_len = strlen (hash_pos); - if (strlen (mac1_pos) != 12) continue; + if (hash_len != 32) continue; - u32 essid_length = mac1_pos - line_hash_buf - 1; + char *essid_pos = sep_pos + 1; - if (hashconfig->is_salted) - { - // this should be always true, but we need it to make scan-build happy + const size_t essid_len = strlen (essid_pos); - memcpy (hash_buf.salt->salt_buf, line_hash_buf, essid_length); - - hash_buf.salt->salt_len = essid_length; - } + if (essid_len > 36) continue; - found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt_hccap); - - if (found) - { - wpa_t *wpa = (wpa_t *) found->esalt; + if (hashconfig->is_salted) + { + // this should be always true, but we need it to make scan-build happy - // compare hex string(s) vs binary MAC address(es) + memcpy (hash_buf.salt->salt_buf, essid_pos, essid_len); - for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx += 1, orig_mac_idx += 2) - { - if (wpa->orig_mac1[mac_idx] != hex_to_u8 ((const u8 *) &mac1_pos[orig_mac_idx])) - { - found = NULL; + hash_buf.salt->salt_len = essid_len; - break; - } + u32 hash[4]; - if (wpa->orig_mac2[mac_idx] != hex_to_u8 ((const u8 *) &mac2_pos[orig_mac_idx])) - { - found = NULL; + hash[0] = hex_to_u32 ((const u8 *) &hash_pos[ 0]); + hash[1] = hex_to_u32 ((const u8 *) &hash_pos[ 8]); + hash[2] = hex_to_u32 ((const u8 *) &hash_pos[16]); + hash[3] = hex_to_u32 ((const u8 *) &hash_pos[24]); - break; - } - } - } + hash_buf.salt->salt_buf[12] = byte_swap_32 (hash[0]); + hash_buf.salt->salt_buf[13] = byte_swap_32 (hash[1]); + hash_buf.salt->salt_buf[14] = byte_swap_32 (hash[2]); + hash_buf.salt->salt_buf[15] = byte_swap_32 (hash[3]); } + + found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt); } else {