From ced9b0c6f82df3a75334d4df5bf800d5cc46a8b0 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 5 Jun 2021 22:11:18 +0200 Subject: [PATCH 1/4] Added new feature: autodetect hash-mode --- docs/changes.txt | 1 + include/types.h | 4 + src/Makefile | 1 + src/hashcat.c | 324 +++++++++++++++++++++++++++++++++++++ src/interface.c | 6 +- src/modules/module_02000.c | 3 +- src/modules/module_09000.c | 3 +- src/modules/module_99999.c | 3 +- src/status.c | 2 + src/terminal.c | 5 + src/user_options.c | 6 + 11 files changed, 352 insertions(+), 6 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 5c2c5e26a..acfe0ebe5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -41,6 +41,7 @@ - RC4 Kernels: Improved performance by 20%+ for hash-modes Kerberos 5 (etype 23), MS Office (<= 2003) and PDF (<= 1.6) by using new RC4 code - Status Screen: Show currently running kernel type (pure, optimized) and generator type (host, device) - UTF8-to-UTF16: Replaced naive UTF8 to UTF16 conversion with true conversion for RAR3, AES Crypt, MultiBit HD (scrypt) and Umbraco HMAC-SHA1 +- Autodetect hash-type: performs an automatic analysis of the hashlist, associating compatible algorithms, or executing the attack if only one compatible format is found. ## ## Technical diff --git a/include/types.h b/include/types.h index 354702779..fbbf235fc 100644 --- a/include/types.h +++ b/include/types.h @@ -210,6 +210,7 @@ typedef enum status_rc STATUS_ABORTED_RUNTIME = 11, STATUS_ERROR = 13, STATUS_ABORTED_FINISH = 14, + STATUS_AUTODETECT = 16, } status_rc_t; @@ -443,6 +444,7 @@ typedef enum opts_type OPTS_TYPE_MP_MULTI_DISABLE = (1ULL << 52), // do not multiply the kernel-accel with the multiprocessor count per device to allow more fine-tuned workload settings OPTS_TYPE_NATIVE_THREADS = (1ULL << 53), // forces "native" thread count: CPU=1, GPU-Intel=8, GPU-AMD=64 (wavefront), GPU-NV=32 (warps) OPTS_TYPE_POST_AMP_UTF16LE = (1ULL << 54), // run the utf8 to utf16le conversion kernel after they have been processed from amplifiers + OPTS_TYPE_AUTODETECT_DISABLE = (1ULL << 55), // skip autodetect engine } opts_type_t; @@ -594,6 +596,7 @@ typedef enum user_options_defaults { ADVICE_DISABLE = false, ATTACK_MODE = ATTACK_MODE_STRAIGHT, + AUTODETECT = false, BENCHMARK_ALL = false, BENCHMARK = false, BITMAP_MAX = 18, @@ -1939,6 +1942,7 @@ typedef struct user_options char **hc_argv; bool attack_mode_chgd; + bool autodetect; #ifdef WITH_BRAIN bool brain_host_chgd; bool brain_port_chgd; diff --git a/src/Makefile b/src/Makefile index 2f9f07432..77029e3f9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -189,6 +189,7 @@ endif ## because LZMA SDK ifeq ($(CC),clang) CFLAGS += -Wno-enum-conversion +CFLAGS += -Wno-typedef-redefinition endif ## because ZLIB diff --git a/src/hashcat.c b/src/hashcat.c index 7fa047ca7..459892bab 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -28,6 +28,7 @@ #include "event.h" #include "hashes.h" #include "hwmon.h" +#include "hlfmt.h" #include "induct.h" #include "interface.h" #include "logfile.h" @@ -1138,6 +1139,271 @@ int hashcat_session_init (hashcat_ctx_t *hashcat_ctx, const char *install_folder return 0; } +bool autodetect_hashmode_test (hashcat_ctx_t *hashcat_ctx) +{ + hashconfig_t *hashconfig = hashcat_ctx->hashconfig; + hashes_t *hashes = hashcat_ctx->hashes; + module_ctx_t *module_ctx = hashcat_ctx->module_ctx; + user_options_t *user_options = hashcat_ctx->user_options; + user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; + + // check for file or hash on command line + // if file, find out if binary file + + if (hashconfig->opts_type & OPTS_TYPE_AUTODETECT_DISABLE) return false; + + if (hashconfig->opts_type & OPTS_TYPE_BINARY_HASHFILE) + { + if (hashconfig->opts_type & OPTS_TYPE_BINARY_HASHFILE_OPTIONAL) + { + hashes->hashlist_mode = (hc_path_exist (user_options_extra->hc_hash) == true) ? HL_MODE_FILE_PLAIN : HL_MODE_ARG; + + if (hashes->hashlist_mode == HL_MODE_FILE_PLAIN) + { + hashes->hashfile = user_options_extra->hc_hash; + } + } + else + { + hashes->hashlist_mode = HL_MODE_FILE_BINARY; + + if (hc_path_read (user_options_extra->hc_hash) == false) return false; + + hashes->hashfile = user_options_extra->hc_hash; + } + } + else + { + hashes->hashlist_mode = (hc_path_exist (user_options_extra->hc_hash) == true) ? HL_MODE_FILE_PLAIN : HL_MODE_ARG; + + if (hashes->hashlist_mode == HL_MODE_FILE_PLAIN) + { + hashes->hashfile = user_options_extra->hc_hash; + } + } + + /** + * load hashes, part I: find input mode + */ + + const char *hashfile = hashes->hashfile; + const u32 hashlist_mode = hashes->hashlist_mode; + + u32 hashlist_format = HLFMT_HASHCAT; + + if (hashlist_mode == HL_MODE_FILE_PLAIN) + { + HCFILE fp; + + if (hc_fopen (&fp, hashfile, "rb") == false) return false; + + hashlist_format = hlfmt_detect (hashcat_ctx, &fp, 100); + + hc_fclose (&fp); + } + + hashes->hashlist_format = hashlist_format; + + /** + * load hashes, part II: allocate required memory, set pointers + */ + + void *digest = hccalloc (1, hashconfig->dgst_size); + salt_t *salt = (salt_t *) hccalloc (1, sizeof (salt_t)); + void *esalt = NULL; + void *hook_salt = NULL; + + if (hashconfig->esalt_size > 0) + { + esalt = hccalloc (1, hashconfig->esalt_size); + } + + if (hashconfig->hook_salt_size > 0) + { + hook_salt = hccalloc (1, hashconfig->hook_salt_size); + } + + hashinfo_t *hash_info = (hashinfo_t *) hcmalloc (sizeof (hashinfo_t)); + + hash_info->user = (user_t *) hcmalloc (sizeof (user_t)); + hash_info->orighash = (char *) hcmalloc (256); + hash_info->split = (split_t *) hcmalloc (sizeof (split_t)); + + hash_t *hashes_buf = (hash_t *) hcmalloc (sizeof (hash_t)); + + hashes_buf->digest = digest; + hashes_buf->salt = salt; + hashes_buf->esalt = esalt; + hashes_buf->hook_salt = hook_salt; + + hashes->hashes_buf = hashes_buf; + hashes->digests_buf = digest; + hashes->salts_buf = salt; + hashes->esalts_buf = esalt; + hashes->hook_salts_buf = hook_salt; + + bool success = false; + + if (hashlist_mode == HL_MODE_ARG) + { + char *input_buf = user_options_extra->hc_hash; + + size_t input_len = strlen (input_buf); + + char *hash_buf = NULL; + int hash_len = 0; + + hlfmt_hash (hashcat_ctx, hashlist_format, input_buf, input_len, &hash_buf, &hash_len); + + bool hash_fmt_error = false; + + if (hash_len < 1) hash_fmt_error = true; + if (hash_buf == NULL) hash_fmt_error = true; + + if (hash_fmt_error) return false; + + const int parser_status = module_ctx->module_hash_decode (hashconfig, digest, salt, esalt, hook_salt, hash_info, hash_buf, hash_len); + + if (parser_status == PARSER_OK) success = true; + } + else if (hashlist_mode == HL_MODE_FILE_PLAIN) + { + HCFILE fp; + + if (hc_fopen (&fp, hashfile, "rb") == false) return false; + + char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); + + while (!hc_feof (&fp)) + { + const size_t line_len = fgetl (&fp, line_buf, HCBUFSIZ_LARGE); + + if (line_len == 0) continue; + + char *hash_buf = NULL; + int hash_len = 0; + + hlfmt_hash (hashcat_ctx, hashlist_format, line_buf, line_len, &hash_buf, &hash_len); + + bool hash_fmt_error = false; + + if (hash_len < 1) hash_fmt_error = true; + if (hash_buf == NULL) hash_fmt_error = true; + + if (hash_fmt_error) continue; + + int parser_status = module_ctx->module_hash_decode (hashconfig, digest, salt, esalt, hook_salt, hash_info, hash_buf, hash_len); + + if (parser_status == PARSER_OK) + { + success = true; + + break; + } + } + + hcfree (line_buf); + + hc_fclose (&fp); + } + else if (hashlist_mode == HL_MODE_FILE_BINARY) + { + char *input_buf = user_options_extra->hc_hash; + + size_t input_len = strlen (input_buf); + + if (module_ctx->module_hash_binary_parse != MODULE_DEFAULT) + { + const int hashes_parsed = module_ctx->module_hash_binary_parse (hashconfig, user_options, user_options_extra, hashes); + + if (hashes_parsed > 0) success = true; + } + else + { + const int parser_status = module_ctx->module_hash_decode (hashconfig, digest, salt, esalt, hook_salt, hash_info, input_buf, input_len); + + if (parser_status == PARSER_OK) success = true; + } + } + + hcfree (digest); + hcfree (salt); + hcfree (hash_info); + hcfree (hashes_buf); + + if (hashconfig->esalt_size > 0) + { + hcfree (esalt); + } + + if (hashconfig->hook_salt_size > 0) + { + hcfree (hook_salt); + } + + hashes->digests_buf = NULL; + hashes->salts_buf = NULL; + hashes->esalts_buf = NULL; + hashes->hook_salts_buf = NULL; + + return success; +} + +int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, int *modes_buf) +{ + folder_config_t *folder_config = hashcat_ctx->folder_config; + user_options_t *user_options = hashcat_ctx->user_options; + + int modes_cnt = 0; + + // save quiet state so we can restore later + + const bool quiet_sav = user_options->quiet; + + user_options->quiet = true; + + char *modulefile = (char *) hcmalloc (HCBUFSIZ_TINY); + + // brute force all the modes + + for (int i = 0; i < MODULE_HASH_MODES_MAXIMUM; i++) + { + user_options->hash_mode = i; + + // this is just to find out of that hash-mode exists or not + + module_filename (folder_config, i, modulefile, HCBUFSIZ_TINY); + + if (hc_path_exist (modulefile) == false) continue; + + // we know it exists, so load the plugin + + const int hashconfig_init_rc = hashconfig_init (hashcat_ctx); + + if (hashconfig_init_rc == 0) + { + const bool test_rc = autodetect_hashmode_test (hashcat_ctx); + + if (test_rc == true) + { + modes_buf[modes_cnt] = i; + + modes_cnt++; + } + } + + // clean up + + hashconfig_destroy (hashcat_ctx); + } + + hcfree (modulefile); + + user_options->quiet = quiet_sav; + + return modes_cnt; +} + int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; @@ -1170,6 +1436,64 @@ int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) dictstat_read (hashcat_ctx); + // autodetect + + if (user_options->autodetect == true) + { + status_ctx->devices_status = STATUS_AUTODETECT; + + int *modes_buf = (int *) hccalloc (MODULE_HASH_MODES_MAXIMUM, sizeof (int)); + + if (!modes_buf) return -1; + + const int modes_cnt = autodetect_hashmodes (hashcat_ctx, modes_buf); + + if (modes_cnt > 0) + { + event_log_info (hashcat_ctx, "The following %d hash-mode match the structure of your input hash:", modes_cnt); + event_log_info (hashcat_ctx, NULL); + event_log_info (hashcat_ctx, " # | Name | Category"); + event_log_info (hashcat_ctx, " ======+=====================================================+======================================"); + + for (int i = 0; i < modes_cnt; i++) + { + user_options->hash_mode = modes_buf[i]; + + if (hashconfig_init (hashcat_ctx) == 0) + { + event_log_info (hashcat_ctx, "%7u | %-51s | %s", hashcat_ctx->hashconfig->hash_mode, hashcat_ctx->hashconfig->hash_name, strhashcategory (hashcat_ctx->hashconfig->hash_category)); + + if (modes_cnt != 1) hashconfig_destroy (hashcat_ctx); // keep for later + } + } + + event_log_info (hashcat_ctx, NULL); + + if (modes_cnt > 1) + { + event_log_error (hashcat_ctx, "Please specify the hash-mode by argument (-m)."); + + return -1; + } + else // 1 + { + event_log_warning (hashcat_ctx, "You have not specified -m to select the correct hash-mode."); + event_log_warning (hashcat_ctx, "It was automatically selected by hashcat because it was the only hash-mode matching your input hash."); + event_log_warning (hashcat_ctx, "Under no circumstances it is not to be understood as a guarantee this is the right hash-mode."); + event_log_warning (hashcat_ctx, "Do not report hashcat issues if you do not know exactly how the hash was extracted."); + event_log_warning (hashcat_ctx, NULL); + + user_options->autodetect = false; + } + } + else + { + if (user_options->show == false) event_log_error (hashcat_ctx, "No hash-mode matches the structure of the input hash."); + + return -1; + } + } + /** * outer loop */ diff --git a/src/interface.c b/src/interface.c index c49f30610..8b0d4c8a3 100644 --- a/src/interface.c +++ b/src/interface.c @@ -259,7 +259,7 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx) { if ((hashconfig->opts_type & OPTS_TYPE_KEYBOARD_MAPPING) == 0) { - event_log_error (hashcat_ctx, "Parameter --keyboard-layout-mapping not valid for hash-type %u", hashconfig->hash_mode); + if (user_options->autodetect == false) event_log_error (hashcat_ctx, "Parameter --keyboard-layout-mapping not valid for hash-type %u", hashconfig->hash_mode); return -1; } @@ -288,7 +288,7 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx) } else { - event_log_error (hashcat_ctx, "Parameter --hex-salt not valid for hash-type %u", hashconfig->hash_mode); + if (user_options->autodetect == false) event_log_error (hashcat_ctx, "Parameter --hex-salt not valid for hash-type %u", hashconfig->hash_mode); return -1; } @@ -302,7 +302,7 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx) { if (hashconfig->opts_type & OPTS_TYPE_SUGGEST_KG) { - if (user_options->quiet == false) + if (user_options->quiet == false && user_options->autodetect == false) { event_log_warning (hashcat_ctx, "This hash-mode is known to emit multiple valid password candidates for the same hash."); event_log_warning (hashcat_ctx, "Use --keep-guessing to prevent hashcat from shutdown after the hash has been cracked."); diff --git a/src/modules/module_02000.c b/src/modules/module_02000.c index 0c21c8862..19fb60394 100644 --- a/src/modules/module_02000.c +++ b/src/modules/module_02000.c @@ -20,7 +20,8 @@ static const u32 HASH_CATEGORY = HASH_CATEGORY_PLAIN; static const char *HASH_NAME = "STDOUT"; static const u64 KERN_TYPE = 2000; static const u32 OPTI_TYPE = 0; -static const u64 OPTS_TYPE = OPTS_TYPE_SELF_TEST_DISABLE; +static const u64 OPTS_TYPE = OPTS_TYPE_SELF_TEST_DISABLE + | OPTS_TYPE_AUTODETECT_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_NONE; static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "hashcat"; diff --git a/src/modules/module_09000.c b/src/modules/module_09000.c index a6341d273..5b7c87c07 100644 --- a/src/modules/module_09000.c +++ b/src/modules/module_09000.c @@ -21,7 +21,8 @@ static const char *HASH_NAME = "Password Safe v2"; static const u64 KERN_TYPE = 9000; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE - | OPTS_TYPE_BINARY_HASHFILE; + | OPTS_TYPE_BINARY_HASHFILE + | OPTS_TYPE_AUTODETECT_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "0a3f352686e5eb5be173e668a4fff5cd5df420927e1da2d5d4052340160637e3e6a5a92841a188ed240e13b919f3d91694bd4c0acba79271e9c08a83ea5ad387cbb74d5884066a1cb5a8caa80d847079168f84823847c631dbe3a834f1bc496acfebac3bff1608bf1c857717f8f428e07b5e2cb12aaeddfa83d7dcb6d840234d08b84f8ca6c6e562af73eea13148f7902bcaf0220d3e36eeeff1d37283dc421483a2791182614ebb"; diff --git a/src/modules/module_99999.c b/src/modules/module_99999.c index 959786003..e079aa7ba 100644 --- a/src/modules/module_99999.c +++ b/src/modules/module_99999.c @@ -30,7 +30,8 @@ static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_RAW_HASH; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE | OPTS_TYPE_PT_ADD80 - | OPTS_TYPE_PT_ADDBITS14; + | OPTS_TYPE_PT_ADDBITS14 + | OPTS_TYPE_AUTODETECT_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_NONE; static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "hashcat"; diff --git a/src/status.c b/src/status.c index dc39cf71e..93d4404fe 100644 --- a/src/status.c +++ b/src/status.c @@ -34,6 +34,7 @@ static const char *ST_0012 = "Running (Checkpoint Quit requested)"; static const char *ST_0013 = "Error"; static const char *ST_0014 = "Aborted (Finish)"; static const char *ST_0015 = "Running (Quit after attack requested)"; +static const char *ST_0016 = "Autodetect"; static const char *ST_9999 = "Unknown! Bug!"; static const char UNITS[7] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E' }; @@ -292,6 +293,7 @@ const char *status_get_status_string (const hashcat_ctx_t *hashcat_ctx) case STATUS_ABORTED_RUNTIME: return ST_0011; case STATUS_ERROR: return ST_0013; case STATUS_ABORTED_FINISH: return ST_0014; + case STATUS_AUTODETECT: return ST_0016; } return ST_9999; diff --git a/src/terminal.c b/src/terminal.c index b8206bd32..9a9bc357a 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -68,6 +68,11 @@ void welcome_screen (hashcat_ctx_t *hashcat_ctx, const char *version_tag) event_log_info (hashcat_ctx, "%s (%s) starting in progress-only mode...", PROGNAME, version_tag); event_log_info (hashcat_ctx, NULL); } + else if (user_options->autodetect == true) + { + event_log_info (hashcat_ctx, "%s (%s) starting in autodetect mode...", PROGNAME, version_tag); + event_log_info (hashcat_ctx, NULL); + } else { event_log_info (hashcat_ctx, "%s (%s) starting...", PROGNAME, version_tag); diff --git a/src/user_options.c b/src/user_options.c index ce4d93a24..70c929d53 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -157,6 +157,7 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->advice_disable = ADVICE_DISABLE; user_options->attack_mode = ATTACK_MODE; + user_options->autodetect = AUTODETECT; user_options->backend_devices = NULL; user_options->backend_ignore_cuda = BACKEND_IGNORE_CUDA; user_options->backend_ignore_opencl = BACKEND_IGNORE_OPENCL; @@ -664,6 +665,11 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } + if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) + { + user_options->autodetect = true; + } + if (user_options->outfile_format == 0) { event_log_error (hashcat_ctx, "Invalid --outfile-format value specified."); From 75d135bf7dea87b20dbe2750a68722a98ded5c7c Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sun, 6 Jun 2021 12:29:07 +0200 Subject: [PATCH 2/4] fix for autodetect (1) --- src/Makefile | 1 - src/hashcat.c | 51 +++++++++++++++++++++++++--------------------- src/terminal.c | 2 +- src/user_options.c | 13 +++++++----- 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/Makefile b/src/Makefile index 77029e3f9..2f9f07432 100644 --- a/src/Makefile +++ b/src/Makefile @@ -189,7 +189,6 @@ endif ## because LZMA SDK ifeq ($(CC),clang) CFLAGS += -Wno-enum-conversion -CFLAGS += -Wno-typedef-redefinition endif ## because ZLIB diff --git a/src/hashcat.c b/src/hashcat.c index 459892bab..7883291ab 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -1444,11 +1444,18 @@ int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) int *modes_buf = (int *) hccalloc (MODULE_HASH_MODES_MAXIMUM, sizeof (int)); - if (!modes_buf) return -1; + if (modes_buf == NULL) return -1; const int modes_cnt = autodetect_hashmodes (hashcat_ctx, modes_buf); - if (modes_cnt > 0) + if (modes_cnt <= 0) + { + if (user_options->show == false) event_log_error (hashcat_ctx, "No hash-mode matches the structure of the input hash."); + + return -1; + } + + if (modes_cnt > 1) { event_log_info (hashcat_ctx, "The following %d hash-mode match the structure of your input hash:", modes_cnt); event_log_info (hashcat_ctx, NULL); @@ -1463,35 +1470,33 @@ int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) { event_log_info (hashcat_ctx, "%7u | %-51s | %s", hashcat_ctx->hashconfig->hash_mode, hashcat_ctx->hashconfig->hash_name, strhashcategory (hashcat_ctx->hashconfig->hash_category)); - if (modes_cnt != 1) hashconfig_destroy (hashcat_ctx); // keep for later + hashconfig_destroy (hashcat_ctx); } } event_log_info (hashcat_ctx, NULL); - if (modes_cnt > 1) - { - event_log_error (hashcat_ctx, "Please specify the hash-mode by argument (-m)."); - - return -1; - } - else // 1 - { - event_log_warning (hashcat_ctx, "You have not specified -m to select the correct hash-mode."); - event_log_warning (hashcat_ctx, "It was automatically selected by hashcat because it was the only hash-mode matching your input hash."); - event_log_warning (hashcat_ctx, "Under no circumstances it is not to be understood as a guarantee this is the right hash-mode."); - event_log_warning (hashcat_ctx, "Do not report hashcat issues if you do not know exactly how the hash was extracted."); - event_log_warning (hashcat_ctx, NULL); - - user_options->autodetect = false; - } - } - else - { - if (user_options->show == false) event_log_error (hashcat_ctx, "No hash-mode matches the structure of the input hash."); + event_log_error (hashcat_ctx, "Please specify the hash-mode by argument (-m)."); return -1; } + + // modes_cnt == 1 + + user_options->hash_mode = modes_buf[0]; + + if (hashconfig_init (hashcat_ctx) != 0) return -1; + + event_log_warning (hashcat_ctx, "You have not specified -m to select the correct hash-mode."); + event_log_warning (hashcat_ctx, "It was automatically selected by hashcat because it was the only hash-mode matching your input hash:"); + event_log_warning (hashcat_ctx, "\n%u | %s | %s\n", hashcat_ctx->hashconfig->hash_mode, hashcat_ctx->hashconfig->hash_name, strhashcategory (hashcat_ctx->hashconfig->hash_category)); + event_log_warning (hashcat_ctx, "Under no circumstances it is not to be understood as a guarantee this is the right hash-mode."); + event_log_warning (hashcat_ctx, "Do not report hashcat issues if you do not know exactly how the hash was extracted."); + event_log_warning (hashcat_ctx, NULL); + + hashconfig_destroy (hashcat_ctx); + + user_options->autodetect = false; } /** diff --git a/src/terminal.c b/src/terminal.c index 9a9bc357a..da80ebcf9 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -68,7 +68,7 @@ void welcome_screen (hashcat_ctx_t *hashcat_ctx, const char *version_tag) event_log_info (hashcat_ctx, "%s (%s) starting in progress-only mode...", PROGNAME, version_tag); event_log_info (hashcat_ctx, NULL); } - else if (user_options->autodetect == true) + else if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) { event_log_info (hashcat_ctx, "%s (%s) starting in autodetect mode...", PROGNAME, version_tag); event_log_info (hashcat_ctx, NULL); diff --git a/src/user_options.c b/src/user_options.c index 70c929d53..312f96790 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -665,11 +665,6 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } - if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) - { - user_options->autodetect = true; - } - if (user_options->outfile_format == 0) { event_log_error (hashcat_ctx, "Invalid --outfile-format value specified."); @@ -1898,6 +1893,14 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) { user_options->potfile_disable = true; } + + if (user_options->stdout_flag == false) + { + if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) + { + user_options->autodetect = true; + } + } } void user_options_postprocess (hashcat_ctx_t *hashcat_ctx) From b8ae1444decf023745a63e9c4eedab54a251c6d0 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sun, 6 Jun 2021 13:40:01 +0200 Subject: [PATCH 3/4] skip autodetect if benchmark is enabled, keep table sorting like usage --- include/usage.h | 9 +++++++++ src/hashcat.c | 47 ++++++++++++++++++++++++---------------------- src/usage.c | 10 +--------- src/user_options.c | 2 +- 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/include/usage.h b/include/usage.h index 4f3895973..35eaef562 100644 --- a/include/usage.h +++ b/include/usage.h @@ -9,7 +9,16 @@ #include #include +typedef struct usage_sort +{ + u32 hash_mode; + char *hash_name; + u32 hash_category; + +} usage_sort_t; + void usage_mini_print (const char *progname); void usage_big_print (hashcat_ctx_t *hashcat_ctx); +int sort_by_usage (const void *p1, const void *p2); #endif // _USAGE_H diff --git a/src/hashcat.c b/src/hashcat.c index 7883291ab..11a6b6c58 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -48,6 +48,7 @@ #include "user_options.h" #include "wordlist.h" #include "hashcat.h" +#include "usage.h" #ifdef WITH_BRAIN #include "brain.h" @@ -1349,12 +1350,12 @@ bool autodetect_hashmode_test (hashcat_ctx_t *hashcat_ctx) return success; } -int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, int *modes_buf) +int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, usage_sort_t *usage_sort_buf) { folder_config_t *folder_config = hashcat_ctx->folder_config; user_options_t *user_options = hashcat_ctx->user_options; - int modes_cnt = 0; + int usage_sort_cnt = 0; // save quiet state so we can restore later @@ -1364,6 +1365,8 @@ int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, int *modes_buf) char *modulefile = (char *) hcmalloc (HCBUFSIZ_TINY); + if (modulefile == NULL) return -1; + // brute force all the modes for (int i = 0; i < MODULE_HASH_MODES_MAXIMUM; i++) @@ -1386,9 +1389,11 @@ int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, int *modes_buf) if (test_rc == true) { - modes_buf[modes_cnt] = i; + usage_sort_buf[usage_sort_cnt].hash_mode = hashcat_ctx->hashconfig->hash_mode; + usage_sort_buf[usage_sort_cnt].hash_name = hcstrdup (hashcat_ctx->hashconfig->hash_name); + usage_sort_buf[usage_sort_cnt].hash_category = hashcat_ctx->hashconfig->hash_category; - modes_cnt++; + usage_sort_cnt++; } } @@ -1399,9 +1404,11 @@ int autodetect_hashmodes (hashcat_ctx_t *hashcat_ctx, int *modes_buf) hcfree (modulefile); + qsort (usage_sort_buf, usage_sort_cnt, sizeof (usage_sort_t), sort_by_usage); + user_options->quiet = quiet_sav; - return modes_cnt; + return usage_sort_cnt; } int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) @@ -1442,11 +1449,11 @@ int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) { status_ctx->devices_status = STATUS_AUTODETECT; - int *modes_buf = (int *) hccalloc (MODULE_HASH_MODES_MAXIMUM, sizeof (int)); + usage_sort_t *usage_sort_buf = (usage_sort_t *) hccalloc (MODULE_HASH_MODES_MAXIMUM, sizeof (usage_sort_t)); - if (modes_buf == NULL) return -1; + if (usage_sort_buf == NULL) return -1; - const int modes_cnt = autodetect_hashmodes (hashcat_ctx, modes_buf); + const int modes_cnt = autodetect_hashmodes (hashcat_ctx, usage_sort_buf); if (modes_cnt <= 0) { @@ -1464,39 +1471,35 @@ int hashcat_session_execute (hashcat_ctx_t *hashcat_ctx) for (int i = 0; i < modes_cnt; i++) { - user_options->hash_mode = modes_buf[i]; - - if (hashconfig_init (hashcat_ctx) == 0) - { - event_log_info (hashcat_ctx, "%7u | %-51s | %s", hashcat_ctx->hashconfig->hash_mode, hashcat_ctx->hashconfig->hash_name, strhashcategory (hashcat_ctx->hashconfig->hash_category)); + event_log_info (hashcat_ctx, "%7u | %-51s | %s", usage_sort_buf[i].hash_mode, usage_sort_buf[i].hash_name, strhashcategory (usage_sort_buf[i].hash_category)); - hashconfig_destroy (hashcat_ctx); - } + hcfree (usage_sort_buf[i].hash_name); } event_log_info (hashcat_ctx, NULL); event_log_error (hashcat_ctx, "Please specify the hash-mode by argument (-m)."); + hcfree (usage_sort_buf); + return -1; } // modes_cnt == 1 - user_options->hash_mode = modes_buf[0]; - - if (hashconfig_init (hashcat_ctx) != 0) return -1; - event_log_warning (hashcat_ctx, "You have not specified -m to select the correct hash-mode."); event_log_warning (hashcat_ctx, "It was automatically selected by hashcat because it was the only hash-mode matching your input hash:"); - event_log_warning (hashcat_ctx, "\n%u | %s | %s\n", hashcat_ctx->hashconfig->hash_mode, hashcat_ctx->hashconfig->hash_name, strhashcategory (hashcat_ctx->hashconfig->hash_category)); + event_log_warning (hashcat_ctx, "\n%u | %s | %s\n", usage_sort_buf[0].hash_mode, usage_sort_buf[0].hash_name, strhashcategory (usage_sort_buf[0].hash_category)); event_log_warning (hashcat_ctx, "Under no circumstances it is not to be understood as a guarantee this is the right hash-mode."); event_log_warning (hashcat_ctx, "Do not report hashcat issues if you do not know exactly how the hash was extracted."); event_log_warning (hashcat_ctx, NULL); - hashconfig_destroy (hashcat_ctx); - user_options->autodetect = false; + + user_options->hash_mode = usage_sort_buf[0].hash_mode; + + hcfree (usage_sort_buf[0].hash_name); + hcfree (usage_sort_buf); } /** diff --git a/src/usage.c b/src/usage.c index 8202121c8..d50a7bfa1 100644 --- a/src/usage.c +++ b/src/usage.c @@ -239,15 +239,7 @@ static const char *const USAGE_BIG_POST_HASHMODES[] = NULL }; -typedef struct usage_sort -{ - u32 hash_mode; - char *hash_name; - u32 hash_category; - -} usage_sort_t; - -static int sort_by_usage (const void *p1, const void *p2) +int sort_by_usage (const void *p1, const void *p2) { const usage_sort_t *u1 = (const usage_sort_t *) p1; const usage_sort_t *u2 = (const usage_sort_t *) p2; diff --git a/src/user_options.c b/src/user_options.c index 312f96790..748ffc376 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -1894,7 +1894,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->potfile_disable = true; } - if (user_options->stdout_flag == false) + if (user_options->stdout_flag == false && user_options->benchmark == false) { if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) { From 1106e163cae75181a6f5708965727a06ba672d74 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sun, 6 Jun 2021 15:48:04 +0200 Subject: [PATCH 4/4] fix example0*, skip autodetect if keyspace enabled, update help and changes.txt --- docs/changes.txt | 7 ++++++- example0.cmd | 2 +- example0.sh | 2 +- src/usage.c | 2 +- src/user_options.c | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index acfe0ebe5..b21c752eb 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -21,6 +21,12 @@ - Added hash-mode: sha384($salt.utf16le($pass)) - Added hash-mode: sha384(utf16le($pass).$salt) +## +## Features +## + +- Autodetect hash-type: performs an automatic analysis of the input hash(es), associating compatible algorithms, or executing the attack if only one compatible format is found. + ## ## Bugs ## @@ -41,7 +47,6 @@ - RC4 Kernels: Improved performance by 20%+ for hash-modes Kerberos 5 (etype 23), MS Office (<= 2003) and PDF (<= 1.6) by using new RC4 code - Status Screen: Show currently running kernel type (pure, optimized) and generator type (host, device) - UTF8-to-UTF16: Replaced naive UTF8 to UTF16 conversion with true conversion for RAR3, AES Crypt, MultiBit HD (scrypt) and Umbraco HMAC-SHA1 -- Autodetect hash-type: performs an automatic analysis of the hashlist, associating compatible algorithms, or executing the attack if only one compatible format is found. ## ## Technical diff --git a/example0.cmd b/example0.cmd index d348c9b88..38e05a590 100644 --- a/example0.cmd +++ b/example0.cmd @@ -1,2 +1,2 @@ -hashcat.exe -t 32 -a 7 example0.hash ?a?a?a?a example.dict +hashcat.exe -m 0 -t 32 -a 7 example0.hash ?a?a?a?a example.dict pause diff --git a/example0.sh b/example0.sh index 98ed7cf6f..1274e0b27 100755 --- a/example0.sh +++ b/example0.sh @@ -1 +1 @@ -./hashcat -t 32 -a 7 example0.hash ?a?a?a?a example.dict +./hashcat -m 0 -t 32 -a 7 example0.hash ?a?a?a?a example.dict diff --git a/src/usage.c b/src/usage.c index d50a7bfa1..b63e417c2 100644 --- a/src/usage.c +++ b/src/usage.c @@ -26,7 +26,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = "", " Options Short / Long | Type | Description | Example", "================================+======+======================================================+=======================", - " -m, --hash-type | Num | Hash-type, see references below | -m 1000", + " -m, --hash-type | Num | Hash-type, references below (otherwise autodetect) | -m 1000", " -a, --attack-mode | Num | Attack-mode, see references below | -a 3", " -V, --version | | Print version |", " -h, --help | | Print help |", diff --git a/src/user_options.c b/src/user_options.c index 748ffc376..4abddd4cc 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -1894,7 +1894,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->potfile_disable = true; } - if (user_options->stdout_flag == false && user_options->benchmark == false) + if (user_options->stdout_flag == false && user_options->benchmark == false && user_options->keyspace == false) { if (user_options->hash_mode == 0 && user_options->hash_mode_chgd == false) {