diff --git a/OpenCL/m18200_a0-optimized.cl b/OpenCL/m18200_a0-optimized.cl index d78a4b310..4eee77861 100644 --- a/OpenCL/m18200_a0-optimized.cl +++ b/OpenCL/m18200_a0-optimized.cl @@ -25,6 +25,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m18200_a0-pure.cl b/OpenCL/m18200_a0-pure.cl index a71ca148c..f86a48fef 100644 --- a/OpenCL/m18200_a0-pure.cl +++ b/OpenCL/m18200_a0-pure.cl @@ -24,6 +24,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m18200_a1-optimized.cl b/OpenCL/m18200_a1-optimized.cl index fe7cbe57f..c710bcbe8 100644 --- a/OpenCL/m18200_a1-optimized.cl +++ b/OpenCL/m18200_a1-optimized.cl @@ -23,6 +23,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m18200_a1-pure.cl b/OpenCL/m18200_a1-pure.cl index 2dd9272f6..987afb360 100644 --- a/OpenCL/m18200_a1-pure.cl +++ b/OpenCL/m18200_a1-pure.cl @@ -22,6 +22,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m18200_a3-optimized.cl b/OpenCL/m18200_a3-optimized.cl index 0e7f02d04..c2c2eee7b 100644 --- a/OpenCL/m18200_a3-optimized.cl +++ b/OpenCL/m18200_a3-optimized.cl @@ -23,6 +23,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m18200_a3-pure.cl b/OpenCL/m18200_a3-pure.cl index 7a71941c5..b5015406b 100644 --- a/OpenCL/m18200_a3-pure.cl +++ b/OpenCL/m18200_a3-pure.cl @@ -22,6 +22,7 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; diff --git a/OpenCL/m20710_a0-optimized.cl b/OpenCL/m20710_a0-optimized.cl index b1ce011ea..f5385d316 100644 --- a/OpenCL/m20710_a0-optimized.cl +++ b/OpenCL/m20710_a0-optimized.cl @@ -1198,14 +1198,14 @@ KERNEL_FQ void m20710_s04 (KERN_ATTR_RULES ()) w7_t = SHA256_EXPAND (w5_t, w0_t, w8_t, w7_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, b, c, d, e, f, g, h, a, w7_t, SHA256C37); w8_t = SHA256_EXPAND (w6_t, w1_t, w9_t, w8_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, a, b, c, d, e, f, g, h, w8_t, SHA256C38); - // if (MATCHES_NONE_VS (h+digest[7]-SHA256M_H, d_rev)) continue; + // if (MATCHES_NONE_VS ((h + digest[7] - make_u32x (SHA256M_H)), d_rev)) continue; w9_t = SHA256_EXPAND (w7_t, w2_t, wa_t, w9_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, h, a, b, c, d, e, f, g, w9_t, SHA256C39); wa_t = SHA256_EXPAND (w8_t, w3_t, wb_t, wa_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, g, h, a, b, c, d, e, f, wa_t, SHA256C3a); wb_t = SHA256_EXPAND (w9_t, w4_t, wc_t, wb_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, f, g, h, a, b, c, d, e, wb_t, SHA256C3b); wc_t = SHA256_EXPAND (wa_t, w5_t, wd_t, wc_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, e, f, g, h, a, b, c, d, wc_t, SHA256C3c); - if (MATCHES_NONE_VS (h+digest[7]-SHA256M_H, search[1])) continue; + if (MATCHES_NONE_VS ((h + digest[7] - make_u32x (SHA256M_H)), search[1])) continue; wd_t = SHA256_EXPAND (wb_t, w6_t, we_t, wd_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, d, e, f, g, h, a, b, c, wd_t, SHA256C3d); we_t = SHA256_EXPAND (wc_t, w7_t, wf_t, we_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, c, d, e, f, g, h, a, b, we_t, SHA256C3e); diff --git a/OpenCL/m20710_a1-optimized.cl b/OpenCL/m20710_a1-optimized.cl index e84e13d35..044720593 100644 --- a/OpenCL/m20710_a1-optimized.cl +++ b/OpenCL/m20710_a1-optimized.cl @@ -1312,14 +1312,14 @@ KERNEL_FQ void m20710_s04 (KERN_ATTR_BASIC ()) w7_t = SHA256_EXPAND (w5_t, w0_t, w8_t, w7_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, b, c, d, e, f, g, h, a, w7_t, SHA256C37); w8_t = SHA256_EXPAND (w6_t, w1_t, w9_t, w8_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, a, b, c, d, e, f, g, h, w8_t, SHA256C38); - // if (MATCHES_NONE_VS (h+digest[7]-SHA256M_H, d_rev)) continue; + // if (MATCHES_NONE_VS ((h + digest[7] - make_u32x (SHA256M_H)), d_rev)) continue; w9_t = SHA256_EXPAND (w7_t, w2_t, wa_t, w9_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, h, a, b, c, d, e, f, g, w9_t, SHA256C39); wa_t = SHA256_EXPAND (w8_t, w3_t, wb_t, wa_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, g, h, a, b, c, d, e, f, wa_t, SHA256C3a); wb_t = SHA256_EXPAND (w9_t, w4_t, wc_t, wb_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, f, g, h, a, b, c, d, e, wb_t, SHA256C3b); wc_t = SHA256_EXPAND (wa_t, w5_t, wd_t, wc_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, e, f, g, h, a, b, c, d, wc_t, SHA256C3c); - if (MATCHES_NONE_VS (h+digest[7]-SHA256M_H, search[1])) continue; + if (MATCHES_NONE_VS ((h + digest[7] - make_u32x (SHA256M_H)), search[1])) continue; wd_t = SHA256_EXPAND (wb_t, w6_t, we_t, wd_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, d, e, f, g, h, a, b, c, wd_t, SHA256C3d); we_t = SHA256_EXPAND (wc_t, w7_t, wf_t, we_t); SHA256_STEP (SHA256_F0o, SHA256_F1o, c, d, e, f, g, h, a, b, we_t, SHA256C3e); diff --git a/OpenCL/m20900_a0-optimized.cl b/OpenCL/m20900_a0-optimized.cl index d55cbb761..3ab829071 100644 --- a/OpenCL/m20900_a0-optimized.cl +++ b/OpenCL/m20900_a0-optimized.cl @@ -1441,7 +1441,7 @@ KERNEL_FQ void m20900_s04 (KERN_ATTR_RULES ()) MD5_STEP (MD5_I , b, c, d, a, wd_t, MD5C3b, MD5S33); MD5_STEP (MD5_I , a, b, c, d, w4_t, MD5C3c, MD5S30); - if (MATCHES_NONE_VS ((a+digest[0]-MD5M_A), search[0])) continue; + if (MATCHES_NONE_VS ((a + digest[0] - make_u32x (MD5M_A)), search[0])) continue; MD5_STEP (MD5_I , d, a, b, c, wb_t, MD5C3d, MD5S31); MD5_STEP (MD5_I , c, d, a, b, w2_t, MD5C3e, MD5S32); diff --git a/OpenCL/m20900_a1-optimized.cl b/OpenCL/m20900_a1-optimized.cl index 07c3f210f..c50b619f8 100644 --- a/OpenCL/m20900_a1-optimized.cl +++ b/OpenCL/m20900_a1-optimized.cl @@ -1555,7 +1555,7 @@ KERNEL_FQ void m20900_s04 (KERN_ATTR_BASIC ()) MD5_STEP (MD5_I , b, c, d, a, wd_t, MD5C3b, MD5S33); MD5_STEP (MD5_I , a, b, c, d, w4_t, MD5C3c, MD5S30); - if (MATCHES_NONE_VS ((a+digest[0]-MD5M_A), search[0])) continue; + if (MATCHES_NONE_VS ((a + digest[0] - make_u32x (MD5M_A)), search[0])) continue; MD5_STEP (MD5_I , d, a, b, c, wb_t, MD5C3d, MD5S31); MD5_STEP (MD5_I , c, d, a, b, w2_t, MD5C3e, MD5S32); diff --git a/OpenCL/m21200_a0-optimized.cl b/OpenCL/m21200_a0-optimized.cl index bb1c0ea8e..c3764aa87 100644 --- a/OpenCL/m21200_a0-optimized.cl +++ b/OpenCL/m21200_a0-optimized.cl @@ -864,7 +864,7 @@ KERNEL_FQ void m21200_s04 (KERN_ATTR_RULES ()) MD5_STEP (MD5_I , b, c, d, a, wd_t, MD5C3b, MD5S33); MD5_STEP (MD5_I , a, b, c, d, w4_t, MD5C3c, MD5S30); - if (MATCHES_NONE_VS ((a+digest[0]-MD5M_A), search[0])) continue; + if (MATCHES_NONE_VS ((a + digest[0] - make_u32x (MD5M_A)), search[0])) continue; MD5_STEP (MD5_I , d, a, b, c, wb_t, MD5C3d, MD5S31); MD5_STEP (MD5_I , c, d, a, b, w2_t, MD5C3e, MD5S32); diff --git a/OpenCL/m21200_a1-optimized.cl b/OpenCL/m21200_a1-optimized.cl index 28262d244..00289dc1f 100644 --- a/OpenCL/m21200_a1-optimized.cl +++ b/OpenCL/m21200_a1-optimized.cl @@ -978,7 +978,7 @@ KERNEL_FQ void m21200_s04 (KERN_ATTR_BASIC ()) MD5_STEP (MD5_I , b, c, d, a, wd_t, MD5C3b, MD5S33); MD5_STEP (MD5_I , a, b, c, d, w4_t, MD5C3c, MD5S30); - if (MATCHES_NONE_VS ((a+digest[0]-MD5M_A), search[0])) continue; + if (MATCHES_NONE_VS ((a + digest[0] - make_u32x (MD5M_A)), search[0])) continue; MD5_STEP (MD5_I , d, a, b, c, wb_t, MD5C3d, MD5S31); MD5_STEP (MD5_I , c, d, a, b, w2_t, MD5C3e, MD5S32); diff --git a/docs/changes.txt b/docs/changes.txt index d799a42c1..2822aa30b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -14,11 +14,12 @@ ## - Added new backend support for Metal, the OpenCL replacement API on Apple +- Added support to use 'John the Ripper' hash format with hash-type 13100 +- Added support to use 'John the Ripper' hash format with hash-type 18200 - Added support to use --debug-mode in attack-mode 9 (Association Attack) - Added support to building universal macOS binary on Apple Silicon - Added hex encoding format for --separator option - Added password candidates range to --status-json output -- Added support to use 'John the Ripper' hash format with hash-type 13100 ## ## Bugs diff --git a/src/modules/module_18200.c b/src/modules/module_18200.c index 85d85b946..83cf949f2 100644 --- a/src/modules/module_18200.c +++ b/src/modules/module_18200.c @@ -47,10 +47,11 @@ typedef struct krb5asrep u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5asrep_t; -static const char *SIGNATURE_KRB5ASREP = "$krb5asrep$23$"; +static const char *SIGNATURE_KRB5ASREP = "$krb5asrep$"; char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED const hc_device_param_t *device_param) { @@ -122,47 +123,132 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE | TOKEN_ATTR_VERIFY_SIGNATURE; /** - * $krb5asrep$23$user_principal_name:checksum$edata2 + * hc + * format 1: $krb5asrep$23$user_principal_name:checksum$edata2 + * + * jtr + * format 2: $krb5asrep$user_principal_name:checksum$edata2 */ - if (line_len < 16) return (PARSER_SALT_LENGTH); + if (line_len < (int) strlen (SIGNATURE_KRB5ASREP)) return (PARSER_SALT_LENGTH); - char *upn_info_start = (char *) line_buf + strlen (SIGNATURE_KRB5ASREP); - char *upn_info_stop = strchr ((const char *) upn_info_start, ':'); + memset (krb5asrep, 0, sizeof (krb5asrep_t)); - if (upn_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED); + size_t parse_off = 0; - upn_info_stop++; // we want the : char included + if (line_buf[token.len[0]] == '2' && line_buf[token.len[0] + 1] == '3' && line_buf[token.len[0] + 2] == '$') + { + // hashcat format - const int upn_info_len = upn_info_stop - upn_info_start; + krb5asrep->format = 1; + + parse_off += 2; + } + else + { + // jtr format + + krb5asrep->format = 2; + } + + char *account_info_start = (char *) line_buf + strlen (SIGNATURE_KRB5ASREP) + parse_off; + char *account_info_stop = strchr ((const char *) account_info_start, ':'); + + if (account_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED); + + account_info_stop++; // we want the : char included + + const int account_info_len = account_info_stop - account_info_start; token.token_cnt = 4; - token.len[1] = upn_info_len; - token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + if (krb5asrep->format == 1) + { + token.token_cnt++; - token.sep[2] = '$'; - token.len_min[2] = 32; - token.len_max[2] = 32; - token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH - | TOKEN_ATTR_VERIFY_HEX; + // etype - token.sep[3] = '$'; - token.len_min[3] = 64; - token.len_max[3] = 40960; - token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH - | TOKEN_ATTR_VERIFY_HEX; + token.sep[1] = '$'; + token.len[1] = 2; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // user_principal_name + + token.sep[2] = ':'; + token.len[2] = account_info_len; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH; + + // checksum + + token.sep[3] = '$'; + token.len_min[3] = 32; + token.len_max[3] = 32; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // edata2 + + token.sep[4] = '$'; + token.len_min[4] = 64; + token.len_max[4] = 40960; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + else + { + // user_principal_name + + token.sep[1] = ':'; + token.len[1] = account_info_len; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + + // checksum + + token.sep[2] = '$'; + token.len_min[2] = 32; + token.len_max[2] = 32; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // edata2 + + token.sep[3] = '$'; + token.len_min[3] = 64; + token.len_max[3] = 40960; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); - const u8 *checksum_pos = token.buf[2]; + const u8 *checksum_pos = NULL; + const u8 *data_pos = NULL; - const u8 *data_pos = token.buf[3]; - const int data_len = token.len[3]; + int data_len = 0; - memcpy (krb5asrep->account_info, token.buf[1], token.len[1]); + if (krb5asrep->format == 1) + { + checksum_pos = token.buf[3]; + + data_pos = token.buf[4]; + data_len = token.len[4]; + + memcpy (krb5asrep->account_info, token.buf[2], token.len[2]); + } + else + { + checksum_pos = token.buf[2]; + + data_pos = token.buf[3]; + data_len = token.len[3]; + + memcpy (krb5asrep->account_info, token.buf[1], token.len[1]); + } + + if (checksum_pos == NULL || data_pos == NULL) return (PARSER_SALT_VALUE); krb5asrep->checksum[0] = hex_to_u32 (checksum_pos + 0); krb5asrep->checksum[1] = hex_to_u32 (checksum_pos + 8); @@ -213,14 +299,30 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE sprintf (data + j, "%02x", ptr_edata2[i]); } - const int line_len = snprintf (line_buf, line_size, "%s%s%08x%08x%08x%08x$%s", - SIGNATURE_KRB5ASREP, - (char *) krb5asrep->account_info, - byte_swap_32 (krb5asrep->checksum[0]), - byte_swap_32 (krb5asrep->checksum[1]), - byte_swap_32 (krb5asrep->checksum[2]), - byte_swap_32 (krb5asrep->checksum[3]), - data); + int line_len = 0; + + if (krb5asrep->format == 1) + { + line_len = snprintf (line_buf, line_size, "%s23%s%08x%08x%08x%08x$%s", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->account_info, + byte_swap_32 (krb5asrep->checksum[0]), + byte_swap_32 (krb5asrep->checksum[1]), + byte_swap_32 (krb5asrep->checksum[2]), + byte_swap_32 (krb5asrep->checksum[3]), + data); + } + else + { + line_len = snprintf (line_buf, line_size, "%s%s%08x%08x%08x%08x$%s", + SIGNATURE_KRB5ASREP, + (char *) krb5asrep->account_info, + byte_swap_32 (krb5asrep->checksum[0]), + byte_swap_32 (krb5asrep->checksum[1]), + byte_swap_32 (krb5asrep->checksum[2]), + byte_swap_32 (krb5asrep->checksum[3]), + data); + } return line_len; }