From 8e00ef9a88b5d16d294679a54ecf96e28ff68c99 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 26 Feb 2022 19:14:20 +0100 Subject: [PATCH 1/5] Added support to use 'John the Ripper' hash format with hash-type 13100 --- docs/changes.txt | 1 + src/modules/module_13100.c | 170 +++++++++++++++++++++++++++---------- 2 files changed, 124 insertions(+), 47 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 4f7ef789b..d799a42c1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -18,6 +18,7 @@ - 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_13100.c b/src/modules/module_13100.c index 23bec5483..8806d37ec 100644 --- a/src/modules/module_13100.c +++ b/src/modules/module_13100.c @@ -48,9 +48,11 @@ typedef struct krb5tgs u32 edata2[5120]; u32 edata2_len; + u32 format; + } krb5tgs_t; -static const char *SIGNATURE_KRB5TGS = "$krb5tgs$23$"; +static const char *SIGNATURE_KRB5TGS = "$krb5tgs$"; 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) { @@ -117,33 +119,90 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.signatures_cnt = 1; token.signatures_buf[0] = SIGNATURE_KRB5TGS; - token.len[0] = 12; + token.len[0] = 9; token.attr[0] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_SIGNATURE; /** - * $krb5tgs$23$checksum$edata2 - * $krb5tgs$23$*user*realm*spn*$checksum$edata2 + * hc + * format 1: $krb5tgs$23$*user*realm*spn*$checksum$edata2 + * format 2: $krb5tgs$23$checksum$edata2 + * + * jtr + * format 3: $krb5tgs$spn$checksum$edata2 */ - if (line_len < 16) return (PARSER_SALT_LENGTH); + if (line_len < 9) return (PARSER_SALT_LENGTH); - if (line_buf[12] == '*') + if (line_buf[9] == '2' && line_buf[10] == '3' && line_buf[11] == '$') { - char *account_info_start = (char *) line_buf + 12; // we want the * char included - char *account_info_stop = strchr ((const char *) account_info_start + 1, '*'); + if (line_buf[12] == '*') + { + char *account_info_start = (char *) line_buf + 12; // we want the * char included + + char *account_info_stop = strchr ((const char *) account_info_start + 1, '*'); + + if (account_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED); + + account_info_stop++; // we want the * char included + account_info_stop++; // we want the $ char included + + const int account_info_len = account_info_stop - account_info_start; - if (account_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED); + token.token_cnt = 5; - account_info_stop++; // we want the * char included - account_info_stop++; // we want the $ char included + token.sep[1] = '$'; + token.len_min[1] = 2; + token.len_max[1] = 2; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; - const int account_info_len = account_info_stop - account_info_start; + token.len[2] = account_info_len; + token.attr[2] = TOKEN_ATTR_FIXED_LENGTH; + token.sep[3] = '$'; + token.len_min[3] = 32; + token.len_max[3] = 32; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + 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 + { + token.token_cnt = 4; + + token.sep[1] = '$'; + token.len_min[1] = 2; + token.len_max[1] = 2; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[2] = '$'; + token.len_min[2] = 32; + token.len_max[2] = 32; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.sep[3] = '$'; + token.len_min[3] = 64; + token.len_max[3] = 40960; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + } + else + { token.token_cnt = 4; - token.len[1] = account_info_len; - token.attr[1] = TOKEN_ATTR_FIXED_LENGTH; + token.sep[1] = ':'; + token.len_min[1] = 0; + token.len_max[1] = 2048; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; token.sep[2] = '$'; token.len_min[2] = 32; @@ -157,22 +216,6 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; } - else - { - token.token_cnt = 3; - - token.sep[1] = '$'; - token.len_min[1] = 32; - token.len_max[1] = 32; - token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH - | TOKEN_ATTR_VERIFY_HEX; - - token.sep[2] = '$'; - token.len_min[2] = 64; - token.len_max[2] = 40960; - token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH - | TOKEN_ATTR_VERIFY_HEX; - } const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); @@ -183,23 +226,38 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE int data_len; - if (line_buf[12] == '*') + if (line_buf[9] == '2' && line_buf[10] == '3' && line_buf[11] == '$') { - checksum_pos = token.buf[2]; + if (line_buf[12] == '*') + { + checksum_pos = token.buf[3]; - data_pos = token.buf[3]; - data_len = token.len[3]; + data_pos = token.buf[4]; + data_len = token.len[4]; - memcpy (krb5tgs->account_info, token.buf[1], token.len[1]); + memcpy (krb5tgs->account_info, token.buf[2], token.len[2]); + krb5tgs->format = 1; + } + else + { + checksum_pos = token.buf[2]; + + data_pos = token.buf[3]; + data_len = token.len[3]; + + krb5tgs->account_info[0] = 0; + krb5tgs->format = 2; + } } else { - checksum_pos = token.buf[1]; + checksum_pos = token.buf[2]; - data_pos = token.buf[2]; - data_len = token.len[2]; + data_pos = token.buf[3]; + data_len = token.len[3]; - krb5tgs->account_info[0] = 0; + memcpy (krb5tgs->account_info, token.buf[1], token.len[1]); + krb5tgs->format = 3; } krb5tgs->checksum[0] = hex_to_u32 (checksum_pos + 0); @@ -251,14 +309,32 @@ 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_KRB5TGS, - (char *) krb5tgs->account_info, - byte_swap_32 (krb5tgs->checksum[0]), - byte_swap_32 (krb5tgs->checksum[1]), - byte_swap_32 (krb5tgs->checksum[2]), - byte_swap_32 (krb5tgs->checksum[3]), - data); + int line_len; + + // preserve the input hash format + + if (krb5tgs->format != 3) // hc + { + line_len = snprintf (line_buf, line_size, "%s23$%s%08x%08x%08x%08x$%s", + SIGNATURE_KRB5TGS, + (char *) krb5tgs->account_info, + byte_swap_32 (krb5tgs->checksum[0]), + byte_swap_32 (krb5tgs->checksum[1]), + byte_swap_32 (krb5tgs->checksum[2]), + byte_swap_32 (krb5tgs->checksum[3]), + data); + } + else // jtr + { + line_len = snprintf (line_buf, line_size, "%s%s:%08x%08x%08x%08x$%s", + SIGNATURE_KRB5TGS, + (char *) krb5tgs->account_info, + byte_swap_32 (krb5tgs->checksum[0]), + byte_swap_32 (krb5tgs->checksum[1]), + byte_swap_32 (krb5tgs->checksum[2]), + byte_swap_32 (krb5tgs->checksum[3]), + data); + } return line_len; } From ca9656e9836f7a60bd68d9a0b126600ca7a1c1b7 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 26 Feb 2022 19:39:23 +0100 Subject: [PATCH 2/5] Updated krb5tgs struct on 13100 kernels --- OpenCL/m13100_a0-optimized.cl | 1 + OpenCL/m13100_a0-pure.cl | 1 + OpenCL/m13100_a1-optimized.cl | 1 + OpenCL/m13100_a1-pure.cl | 1 + OpenCL/m13100_a3-optimized.cl | 1 + OpenCL/m13100_a3-pure.cl | 1 + src/modules/module_13100.c | 1 - 7 files changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenCL/m13100_a0-optimized.cl b/OpenCL/m13100_a0-optimized.cl index 0d67fb3c9..a2b653f47 100644 --- a/OpenCL/m13100_a0-optimized.cl +++ b/OpenCL/m13100_a0-optimized.cl @@ -25,6 +25,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/OpenCL/m13100_a0-pure.cl b/OpenCL/m13100_a0-pure.cl index d56a3004b..8aaff8389 100644 --- a/OpenCL/m13100_a0-pure.cl +++ b/OpenCL/m13100_a0-pure.cl @@ -24,6 +24,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/OpenCL/m13100_a1-optimized.cl b/OpenCL/m13100_a1-optimized.cl index 749f12952..26c8e8111 100644 --- a/OpenCL/m13100_a1-optimized.cl +++ b/OpenCL/m13100_a1-optimized.cl @@ -23,6 +23,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/OpenCL/m13100_a1-pure.cl b/OpenCL/m13100_a1-pure.cl index ebdb14864..1799a64ee 100644 --- a/OpenCL/m13100_a1-pure.cl +++ b/OpenCL/m13100_a1-pure.cl @@ -22,6 +22,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/OpenCL/m13100_a3-optimized.cl b/OpenCL/m13100_a3-optimized.cl index c692199b6..2d2a47efc 100644 --- a/OpenCL/m13100_a3-optimized.cl +++ b/OpenCL/m13100_a3-optimized.cl @@ -23,6 +23,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/OpenCL/m13100_a3-pure.cl b/OpenCL/m13100_a3-pure.cl index 7db244812..166997b52 100644 --- a/OpenCL/m13100_a3-pure.cl +++ b/OpenCL/m13100_a3-pure.cl @@ -22,6 +22,7 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; + u32 format; } krb5tgs_t; diff --git a/src/modules/module_13100.c b/src/modules/module_13100.c index 8806d37ec..84edb28e9 100644 --- a/src/modules/module_13100.c +++ b/src/modules/module_13100.c @@ -47,7 +47,6 @@ typedef struct krb5tgs u32 checksum[4]; u32 edata2[5120]; u32 edata2_len; - u32 format; } krb5tgs_t; From 395d19513db2f4c2add067df892780a7b1121690 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 26 Feb 2022 21:19:52 +0100 Subject: [PATCH 3/5] fix sample formats --- src/modules/module_13100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/module_13100.c b/src/modules/module_13100.c index 84edb28e9..2a220ebaf 100644 --- a/src/modules/module_13100.c +++ b/src/modules/module_13100.c @@ -124,11 +124,11 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE /** * hc - * format 1: $krb5tgs$23$*user*realm*spn*$checksum$edata2 + * format 1: $krb5tgs$23$*user$realm$spn*$checksum$edata2 * format 2: $krb5tgs$23$checksum$edata2 * * jtr - * format 3: $krb5tgs$spn$checksum$edata2 + * format 3: $krb5tgs$spn:checksum$edata2 */ if (line_len < 9) return (PARSER_SALT_LENGTH); From 39912575b2894b58b80192baf1e123914abda579 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sun, 27 Feb 2022 12:12:22 +0100 Subject: [PATCH 4/5] fix style --- src/modules/module_13100.c | 81 +++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/src/modules/module_13100.c b/src/modules/module_13100.c index 2a220ebaf..15adfbe4e 100644 --- a/src/modules/module_13100.c +++ b/src/modules/module_13100.c @@ -131,14 +131,17 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE * format 3: $krb5tgs$spn:checksum$edata2 */ - if (line_len < 9) return (PARSER_SALT_LENGTH); + if (line_len < (int) strlen (SIGNATURE_KRB5TGS)) return (PARSER_SALT_LENGTH); - if (line_buf[9] == '2' && line_buf[10] == '3' && line_buf[11] == '$') + memset (krb5tgs, 0, sizeof (krb5tgs_t)); + + token.token_cnt = 4; + + if (line_buf[token.len[0]] == '2' && line_buf[token.len[0] + 1] == '3' && line_buf[token.len[0] + 2] == '$') { - if (line_buf[12] == '*') + if (line_buf[token.len[0] + 3] == '*') { char *account_info_start = (char *) line_buf + 12; // we want the * char included - char *account_info_stop = strchr ((const char *) account_info_start + 1, '*'); if (account_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED); @@ -148,7 +151,9 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE const int account_info_len = account_info_stop - account_info_start; - token.token_cnt = 5; + token.token_cnt++; + + // etype token.sep[1] = '$'; token.len_min[1] = 2; @@ -156,24 +161,32 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; + // user$realm$spn + 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; + + krb5tgs->format = 1; } else { - token.token_cnt = 4; + // etype token.sep[1] = '$'; token.len_min[1] = 2; @@ -181,82 +194,88 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; + // 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; + + krb5tgs->format = 2; } } else { - token.token_cnt = 4; + // spn token.sep[1] = ':'; token.len_min[1] = 0; token.len_max[1] = 2048; token.attr[1] = TOKEN_ATTR_VERIFY_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; + + krb5tgs->format = 3; } 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; - const u8 *data_pos; + u8 *checksum_pos = NULL; + u8 *data_pos = NULL; - int data_len; + int data_len = 0; - if (line_buf[9] == '2' && line_buf[10] == '3' && line_buf[11] == '$') + if (krb5tgs->format == 1) { - if (line_buf[12] == '*') - { - checksum_pos = token.buf[3]; + checksum_pos = (u8 *) token.buf[3]; - data_pos = token.buf[4]; - data_len = token.len[4]; + data_pos = (u8 *) token.buf[4]; + data_len = token.len[4]; - memcpy (krb5tgs->account_info, token.buf[2], token.len[2]); - krb5tgs->format = 1; - } - else - { - checksum_pos = token.buf[2]; + memcpy (krb5tgs->account_info, token.buf[2], token.len[2]); + } + else if (krb5tgs->format == 2) + { + checksum_pos = (u8 *) token.buf[2]; - data_pos = token.buf[3]; - data_len = token.len[3]; + data_pos = (u8 *) token.buf[3]; + data_len = token.len[3]; - krb5tgs->account_info[0] = 0; - krb5tgs->format = 2; - } + krb5tgs->account_info[0] = 0; } - else + else if (krb5tgs->format == 3) { - checksum_pos = token.buf[2]; + checksum_pos = (u8 *) token.buf[2]; - data_pos = token.buf[3]; + data_pos = (u8 *) token.buf[3]; data_len = token.len[3]; memcpy (krb5tgs->account_info, token.buf[1], token.len[1]); - krb5tgs->format = 3; } krb5tgs->checksum[0] = hex_to_u32 (checksum_pos + 0); From eb30a1c820108fd306cb7e5edb8ba659a7a46b64 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sun, 27 Feb 2022 14:26:34 +0100 Subject: [PATCH 5/5] fix Cygwin build warnings --- src/modules/module_13100.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/modules/module_13100.c b/src/modules/module_13100.c index 15adfbe4e..9bb177dfb 100644 --- a/src/modules/module_13100.c +++ b/src/modules/module_13100.c @@ -245,39 +245,41 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); - u8 *checksum_pos = NULL; - u8 *data_pos = NULL; + const u8 *checksum_pos = NULL; + const u8 *data_pos = NULL; int data_len = 0; if (krb5tgs->format == 1) { - checksum_pos = (u8 *) token.buf[3]; + checksum_pos = token.buf[3]; - data_pos = (u8 *) token.buf[4]; + data_pos = token.buf[4]; data_len = token.len[4]; memcpy (krb5tgs->account_info, token.buf[2], token.len[2]); } else if (krb5tgs->format == 2) { - checksum_pos = (u8 *) token.buf[2]; + checksum_pos = token.buf[2]; - data_pos = (u8 *) token.buf[3]; + data_pos = token.buf[3]; data_len = token.len[3]; krb5tgs->account_info[0] = 0; } else if (krb5tgs->format == 3) { - checksum_pos = (u8 *) token.buf[2]; + checksum_pos = token.buf[2]; - data_pos = (u8 *) token.buf[3]; + data_pos = token.buf[3]; data_len = token.len[3]; memcpy (krb5tgs->account_info, token.buf[1], token.len[1]); } + if (checksum_pos == NULL || data_pos == NULL) return (PARSER_SALT_VALUE); + krb5tgs->checksum[0] = hex_to_u32 (checksum_pos + 0); krb5tgs->checksum[1] = hex_to_u32 (checksum_pos + 8); krb5tgs->checksum[2] = hex_to_u32 (checksum_pos + 16);