mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-19 04:58:16 +00:00

only the first hash in a multihash list was marked as cracked, regardless of which hash was actually cracked. For example, if the second hash was cracked, it incorrectly marked the first as cracked and left the second uncracked. This issue only affected beta versions and only in multihash cracking mode. Added deep-comp kernel support for Kerberos modes 28800 and 28900, enabling multihash cracking for the same user in the same domain, even if the password was changed or the recording was bad. Added a rule ensuring that device buffer sizes for password candidates, hooks, and transport (tmps) must be smaller than 1/4 of the maximum allocatable memory. If not, hashcat now automatically reduces kernel-accel down to 1, then halves the number of threads and restores kernel-accel up to its maximum, repeating until the size requirement is met. Fixed salt length limit verification for -m 20712. Fixed password length limit for -m 14400. Fixed unit test salt generator for -m 21100, which could produce duplicate hashes under certain conditions. Added the OPTS_TYPE_NATIVE_THREADS flag to the following hash modes (after benchmarking): 7700, 7701, 9000, 1375x, 1376x, 14800, 19500, 23900.
330 lines
14 KiB
C
330 lines
14 KiB
C
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "types.h"
|
|
#include "modules.h"
|
|
#include "bitops.h"
|
|
#include "convert.h"
|
|
#include "shared.h"
|
|
|
|
static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL;
|
|
static const u32 DGST_POS0 = 0;
|
|
static const u32 DGST_POS1 = 1;
|
|
static const u32 DGST_POS2 = 2;
|
|
static const u32 DGST_POS3 = 3;
|
|
static const u32 DGST_SIZE = DGST_SIZE_4_4;
|
|
static const u32 HASH_CATEGORY = HASH_CATEGORY_NETWORK_PROTOCOL;
|
|
static const char *HASH_NAME = "Kerberos 5, etype 17, DB";
|
|
static const u64 KERN_TYPE = 28800;
|
|
static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE
|
|
| OPTI_TYPE_NOT_ITERATED
|
|
| OPTI_TYPE_SLOW_HASH_SIMD_LOOP;
|
|
static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE
|
|
| OPTS_TYPE_DEEP_COMP_KERNEL
|
|
| OPTS_TYPE_PT_GENERATE_LE;
|
|
static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED;
|
|
static const char *ST_PASS = "hashcat";
|
|
static const char *ST_HASH = "$krb5db$17$test$TEST.LOCAL$1c41586d6c060071e08186ee214e725e";
|
|
|
|
u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; }
|
|
u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; }
|
|
u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; }
|
|
u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; }
|
|
u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; }
|
|
u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; }
|
|
u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; }
|
|
const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; }
|
|
u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; }
|
|
u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; }
|
|
u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; }
|
|
u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; }
|
|
const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; }
|
|
const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; }
|
|
|
|
typedef struct krb5db_17
|
|
{
|
|
u32 user[128];
|
|
u32 domain[128];
|
|
u32 account_info[512];
|
|
u32 account_info_len;
|
|
|
|
} krb5db_17_t;
|
|
|
|
typedef struct krb5db_17_tmp
|
|
{
|
|
u32 ipad[5];
|
|
u32 opad[5];
|
|
u32 dgst[10];
|
|
u32 out[10];
|
|
|
|
} krb5db_17_tmp_t;
|
|
|
|
static const char *SIGNATURE_KRB5DB = "$krb5db$17$";
|
|
|
|
u32 module_deep_comp_kernel (MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED const u32 salt_pos, MAYBE_UNUSED const u32 digest_pos)
|
|
{
|
|
return KERN_RUN_3;
|
|
}
|
|
|
|
u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
|
|
{
|
|
const u64 tmp_size = (const u64) sizeof (krb5db_17_tmp_t);
|
|
|
|
return tmp_size;
|
|
}
|
|
|
|
u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra)
|
|
{
|
|
const u64 esalt_size = (const u64) sizeof (krb5db_17_t);
|
|
|
|
return esalt_size;
|
|
}
|
|
|
|
int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len)
|
|
{
|
|
u32 *digest = (u32 *) digest_buf;
|
|
|
|
krb5db_17_t *krb5db = (krb5db_17_t *) esalt_buf;
|
|
|
|
hc_token_t token;
|
|
|
|
memset (&token, 0, sizeof (hc_token_t));
|
|
|
|
token.signatures_cnt = 1;
|
|
token.signatures_buf[0] = SIGNATURE_KRB5DB;
|
|
|
|
token.len[0] = 11;
|
|
token.attr[0] = TOKEN_ATTR_FIXED_LENGTH
|
|
| TOKEN_ATTR_VERIFY_SIGNATURE;
|
|
|
|
/**
|
|
* $krb5db$17$user$realm$hash
|
|
* $krb5db$17$user$realm$*spn*$hash
|
|
*/
|
|
|
|
// assume no signature found
|
|
if (line_len < 11) return (PARSER_SALT_LENGTH);
|
|
|
|
char *spn_info_start = strchr (line_buf + 11 + 1, '*');
|
|
|
|
int is_spn_provided = 0;
|
|
|
|
// assume $krb5db$17$user$realm$hash
|
|
if (spn_info_start == NULL)
|
|
{
|
|
token.token_cnt = 4;
|
|
|
|
token.sep[1] = '$';
|
|
token.len_min[1] = 1;
|
|
token.len_max[1] = 512;
|
|
token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH;
|
|
|
|
token.sep[2] = '$';
|
|
token.len_min[2] = 1;
|
|
token.len_max[2] = 512;
|
|
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH;
|
|
|
|
token.sep[3] = '$';
|
|
token.len[3] = 32;
|
|
token.attr[3] = TOKEN_ATTR_FIXED_LENGTH
|
|
| TOKEN_ATTR_VERIFY_HEX;
|
|
}
|
|
// assume $krb5db$17$user$realm$*spn*$hash
|
|
else
|
|
{
|
|
char *spn_info_stop = strchr ((const char *) spn_info_start + 1, '*');
|
|
|
|
if (spn_info_stop == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
spn_info_stop++; // we want the * $char included
|
|
spn_info_stop++; // we want the $ char included
|
|
|
|
const int spn_info_len = spn_info_stop - spn_info_start;
|
|
|
|
token.token_cnt = 5;
|
|
|
|
token.sep[1] = '$';
|
|
token.len_min[1] = 1;
|
|
token.len_max[1] = 512;
|
|
token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH;
|
|
|
|
token.sep[2] = '$';
|
|
token.len_min[2] = 1;
|
|
token.len_max[2] = 512;
|
|
token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH;
|
|
|
|
token.len[3] = spn_info_len;
|
|
token.attr[3] = TOKEN_ATTR_FIXED_LENGTH;
|
|
|
|
token.sep[4] = '$';
|
|
token.len[4] = 32;
|
|
token.attr[4] = TOKEN_ATTR_FIXED_LENGTH
|
|
| TOKEN_ATTR_VERIFY_HEX;
|
|
|
|
is_spn_provided = 1;
|
|
}
|
|
|
|
const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token);
|
|
|
|
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
|
|
|
|
const u8 *user_pos;
|
|
const u8 *domain_pos;
|
|
const u8 *checksum_pos;
|
|
|
|
int user_len;
|
|
int domain_len;
|
|
int account_info_len;
|
|
|
|
user_pos = token.buf[1];
|
|
user_len = token.len[1];
|
|
|
|
memcpy (krb5db->user, user_pos, user_len);
|
|
|
|
domain_pos = token.buf[2];
|
|
domain_len = token.len[2];
|
|
|
|
memcpy (krb5db->domain, domain_pos, domain_len);
|
|
|
|
checksum_pos = token.buf[3 + is_spn_provided];
|
|
|
|
account_info_len = token.len[2] + token.len[1];
|
|
|
|
u8 *account_info_ptr = (u8 *) krb5db->account_info;
|
|
|
|
// domain must be uppercase
|
|
|
|
u8 domain[128];
|
|
|
|
memcpy (domain, domain_pos, domain_len);
|
|
uppercase (domain, domain_len);
|
|
|
|
memcpy (account_info_ptr, domain, domain_len);
|
|
memcpy (account_info_ptr + domain_len, user_pos, user_len);
|
|
|
|
krb5db->account_info_len = account_info_len;
|
|
|
|
// salt
|
|
|
|
salt->salt_buf[0] = krb5db->account_info[0];
|
|
salt->salt_buf[1] = krb5db->account_info[1];
|
|
salt->salt_buf[2] = krb5db->account_info[2];
|
|
salt->salt_buf[3] = krb5db->account_info[3];
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_iter = 4096 - 1;
|
|
|
|
// digest
|
|
|
|
digest[0] = byte_swap_32 (hex_to_u32 (checksum_pos + 0));
|
|
digest[1] = byte_swap_32 (hex_to_u32 (checksum_pos + 8));
|
|
digest[2] = byte_swap_32 (hex_to_u32 (checksum_pos + 16));
|
|
digest[3] = byte_swap_32 (hex_to_u32 (checksum_pos + 24));
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size)
|
|
{
|
|
const u32 *digest = (const u32 *) digest_buf;
|
|
|
|
const krb5db_17_t *krb5db = (const krb5db_17_t *) esalt_buf;
|
|
|
|
const int line_len = snprintf (line_buf, line_size, "%s%s$%s$%08x%08x%08x%08x",
|
|
SIGNATURE_KRB5DB,
|
|
(const char *) krb5db->user,
|
|
(const char *) krb5db->domain,
|
|
digest[0],
|
|
digest[1],
|
|
digest[2],
|
|
digest[3]);
|
|
|
|
return line_len;
|
|
}
|
|
|
|
void module_init (module_ctx_t *module_ctx)
|
|
{
|
|
module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT;
|
|
module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT;
|
|
|
|
module_ctx->module_attack_exec = module_attack_exec;
|
|
module_ctx->module_benchmark_esalt = MODULE_DEFAULT;
|
|
module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT;
|
|
module_ctx->module_benchmark_mask = MODULE_DEFAULT;
|
|
module_ctx->module_benchmark_charset = MODULE_DEFAULT;
|
|
module_ctx->module_benchmark_salt = MODULE_DEFAULT;
|
|
module_ctx->module_bridge_name = MODULE_DEFAULT;
|
|
module_ctx->module_bridge_type = MODULE_DEFAULT;
|
|
module_ctx->module_build_plain_postprocess = MODULE_DEFAULT;
|
|
module_ctx->module_deep_comp_kernel = module_deep_comp_kernel;
|
|
module_ctx->module_deprecated_notice = MODULE_DEFAULT;
|
|
module_ctx->module_dgst_pos0 = module_dgst_pos0;
|
|
module_ctx->module_dgst_pos1 = module_dgst_pos1;
|
|
module_ctx->module_dgst_pos2 = module_dgst_pos2;
|
|
module_ctx->module_dgst_pos3 = module_dgst_pos3;
|
|
module_ctx->module_dgst_size = module_dgst_size;
|
|
module_ctx->module_dictstat_disable = MODULE_DEFAULT;
|
|
module_ctx->module_esalt_size = module_esalt_size;
|
|
module_ctx->module_extra_buffer_size = MODULE_DEFAULT;
|
|
module_ctx->module_extra_tmp_size = MODULE_DEFAULT;
|
|
module_ctx->module_extra_tuningdb_block = MODULE_DEFAULT;
|
|
module_ctx->module_forced_outfile_format = MODULE_DEFAULT;
|
|
module_ctx->module_hash_binary_count = MODULE_DEFAULT;
|
|
module_ctx->module_hash_binary_parse = MODULE_DEFAULT;
|
|
module_ctx->module_hash_binary_save = MODULE_DEFAULT;
|
|
module_ctx->module_hash_decode_postprocess = MODULE_DEFAULT;
|
|
module_ctx->module_hash_decode_potfile = MODULE_DEFAULT;
|
|
module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT;
|
|
module_ctx->module_hash_decode = module_hash_decode;
|
|
module_ctx->module_hash_encode_status = MODULE_DEFAULT;
|
|
module_ctx->module_hash_encode_potfile = MODULE_DEFAULT;
|
|
module_ctx->module_hash_encode = module_hash_encode;
|
|
module_ctx->module_hash_init_selftest = MODULE_DEFAULT;
|
|
module_ctx->module_hash_mode = MODULE_DEFAULT;
|
|
module_ctx->module_hash_category = module_hash_category;
|
|
module_ctx->module_hash_name = module_hash_name;
|
|
module_ctx->module_hashes_count_min = MODULE_DEFAULT;
|
|
module_ctx->module_hashes_count_max = MODULE_DEFAULT;
|
|
module_ctx->module_hlfmt_disable = MODULE_DEFAULT;
|
|
module_ctx->module_hook_extra_param_size = MODULE_DEFAULT;
|
|
module_ctx->module_hook_extra_param_init = MODULE_DEFAULT;
|
|
module_ctx->module_hook_extra_param_term = MODULE_DEFAULT;
|
|
module_ctx->module_hook12 = MODULE_DEFAULT;
|
|
module_ctx->module_hook23 = MODULE_DEFAULT;
|
|
module_ctx->module_hook_salt_size = MODULE_DEFAULT;
|
|
module_ctx->module_hook_size = MODULE_DEFAULT;
|
|
module_ctx->module_jit_build_options = MODULE_DEFAULT;
|
|
module_ctx->module_jit_cache_disable = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_accel_max = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_accel_min = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_loops_max = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_loops_min = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_threads_max = MODULE_DEFAULT;
|
|
module_ctx->module_kernel_threads_min = MODULE_DEFAULT;
|
|
module_ctx->module_kern_type = module_kern_type;
|
|
module_ctx->module_kern_type_dynamic = MODULE_DEFAULT;
|
|
module_ctx->module_opti_type = module_opti_type;
|
|
module_ctx->module_opts_type = module_opts_type;
|
|
module_ctx->module_outfile_check_disable = MODULE_DEFAULT;
|
|
module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT;
|
|
module_ctx->module_potfile_custom_check = MODULE_DEFAULT;
|
|
module_ctx->module_potfile_disable = MODULE_DEFAULT;
|
|
module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT;
|
|
module_ctx->module_pwdump_column = MODULE_DEFAULT;
|
|
module_ctx->module_pw_max = MODULE_DEFAULT;
|
|
module_ctx->module_pw_min = MODULE_DEFAULT;
|
|
module_ctx->module_salt_max = MODULE_DEFAULT;
|
|
module_ctx->module_salt_min = MODULE_DEFAULT;
|
|
module_ctx->module_salt_type = module_salt_type;
|
|
module_ctx->module_separator = MODULE_DEFAULT;
|
|
module_ctx->module_st_hash = module_st_hash;
|
|
module_ctx->module_st_pass = module_st_pass;
|
|
module_ctx->module_tmp_size = module_tmp_size;
|
|
module_ctx->module_unstable_warning = MODULE_DEFAULT;
|
|
module_ctx->module_warmup_disable = MODULE_DEFAULT;
|
|
}
|