From 33579ae3db34a84bc26e01589925707b370d4f33 Mon Sep 17 00:00:00 2001 From: Jens Steube Date: Fri, 8 May 2020 10:18:17 +0200 Subject: [PATCH] Add new option for modules OPTS_TYPE_SELF_TEST_DISABLE to disable self-test functionality from hash-mode directly --- docs/hashcat-plugin-development-guide.md | 1 + include/types.h | 1 + src/hashcat.c | 2 +- src/interface.c | 5 +++++ src/modules/module_01500.c | 5 +++-- src/modules/module_02000.c | 6 +++--- src/modules/module_08900.c | 5 +++-- src/modules/module_14600.c | 3 ++- src/modules/module_15700.c | 3 ++- src/modules/module_16500.c | 5 +++-- src/terminal.c | 9 ++++++++- 11 files changed, 32 insertions(+), 13 deletions(-) diff --git a/docs/hashcat-plugin-development-guide.md b/docs/hashcat-plugin-development-guide.md index 0aa85db22..e87f56016 100644 --- a/docs/hashcat-plugin-development-guide.md +++ b/docs/hashcat-plugin-development-guide.md @@ -482,6 +482,7 @@ This configuration item is a bitmask field and is very similar to the module_opt * OPTS_TYPE_COPY_TMPS: This option tells the hashcat host binary to copy the `tmps` data structure from the compute device to the host in case a hash was cracked. In order to access this data, you need to implement and register the module function module_build_plain_postprocess(). There are several scenarios in which this can be useful. For instance, if you have a weak algorithm that could be exploited to leak portions of the password and you use this leaked data to speed up your attacks, you still need to know the leaked data on the host to copy it to the password buffer before printing it to the user. A good example for this is PKZIP `src/modules/module_20510.c` which leaks the first 6 bytes of the password. Another scenario is the PIM brute force in VeraCrypt. The PIM in this case can be seen as an additional numeric password. In case we crack it, the user needs to know both the password and the PIM in order to mount the volume. * OPTS_TYPE_POTFILE_NOPASS: This option simply prevents the hashcat host binary from adding a cracked hash to the potfile. For instance, if a specific hashing algorithm is implemented with several hash formats and therefore your plugins hash format shares the same format with a different plugin hash format (think of it like a format clash where the potfile parser could not really decide if it is the correct hash format to accept). A good example is the WPA PMK, which cannot be used to login to a specific WPA network directly. There could be other reasons for not printing the cracked hashes to the potfile. * OPTS_TYPE_DYNAMIC_SHARED: This is a very special option which tells the hashcat host binary to query the real available shared memory on a device for a particular kernel. In addition it will also register the queried amount of shared memory from the host. On NVIDIA, this allows us to use the full available shared memory (regions in the post 48k range), though we still need to prepare the kernel in order to make use of the dynamic allocated shared memory. A good example is the bcrypt kernel `OpenCL/m03200-pure.cl`. +* OPTS_TYPE_SELF_TEST_DISABLE: This option can be used if you want to disable the self-test functionality for your hash-mode. Valid reasons to disable this feature are: Your OpenCL kernel is using compile time optimizations such as fixed salts (like in DESCrypt), the hash primitive to be used has to be derived first from the target hash (like in JWT) or the hash-mode is so slow that it hurts startup time of hashcat (like in Ethereum Wallet SCRYPT). For the first two cases the problem is that hashcat would create a cached optimized OpenCL kernel with a configuration which is valid only for the self-test hash, but very likely the wrong ones for the real target hash. The real target hash would never crack. ### module_salt_type() ### diff --git a/include/types.h b/include/types.h index 47eff8f28..7972d4821 100644 --- a/include/types.h +++ b/include/types.h @@ -428,6 +428,7 @@ typedef enum opts_type OPTS_TYPE_COPY_TMPS = (1ULL << 46), // if we want to use data from tmps buffer (for example get the PMK in WPA) OPTS_TYPE_POTFILE_NOPASS = (1ULL << 47), // sometimes the password should not be printed to potfile OPTS_TYPE_DYNAMIC_SHARED = (1ULL << 48), // use dynamic shared memory (note: needs special kernel changes) + OPTS_TYPE_SELF_TEST_DISABLE = (1ULL << 49), // some algos use JiT in combinations with a salt or create too much startup time } opts_type_t; diff --git a/src/hashcat.c b/src/hashcat.c index fb7006d91..4c916c988 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -707,7 +707,7 @@ static int outer_loop (hashcat_ctx_t *hashcat_ctx) * create self-test threads */ - if ((user_options->self_test_disable == false) && (hashconfig->st_hash != NULL) && (hashconfig->st_pass != NULL)) + if ((hashconfig->opts_type & OPTS_TYPE_SELF_TEST_DISABLE) == 0) { EVENT (EVENT_SELFTEST_STARTING); diff --git a/src/interface.c b/src/interface.c index e514a1ca8..3ac86aedd 100644 --- a/src/interface.c +++ b/src/interface.c @@ -280,6 +280,11 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx) } } + if (user_options->self_test_disable == true) + { + hashconfig->opts_type |= OPTS_TYPE_SELF_TEST_DISABLE; + } + if (user_options->hex_charset) { hashconfig->opts_type |= OPTS_TYPE_PT_HEX; diff --git a/src/modules/module_01500.c b/src/modules/module_01500.c index 77ab912d2..f742c4b5a 100644 --- a/src/modules/module_01500.c +++ b/src/modules/module_01500.c @@ -22,9 +22,10 @@ static const char *HASH_NAME = "descrypt, DES (Unix), Traditional DES"; static const u64 KERN_TYPE = 1500; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE - | OPTS_TYPE_TM_KERNEL; + | OPTS_TYPE_TM_KERNEL + | OPTS_TYPE_SELF_TEST_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; -static const char *ST_PASS = NULL; // the self-test can't work because the salt is not part of the code at compile-time +static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "24leDr0hHfb3A"; 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; } diff --git a/src/modules/module_02000.c b/src/modules/module_02000.c index be40fcb4f..243c312ba 100644 --- a/src/modules/module_02000.c +++ b/src/modules/module_02000.c @@ -20,10 +20,10 @@ 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 = 0; +static const u64 OPTS_TYPE = OPTS_TYPE_SELF_TEST_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_NONE; -static const char *ST_PASS = NULL; -static const char *ST_HASH = NULL; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "hashcat"; 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; } diff --git a/src/modules/module_08900.c b/src/modules/module_08900.c index 06be00b6e..bf1cc9bc1 100644 --- a/src/modules/module_08900.c +++ b/src/modules/module_08900.c @@ -21,9 +21,10 @@ static const u32 HASH_CATEGORY = HASH_CATEGORY_GENERIC_KDF; static const char *HASH_NAME = "scrypt"; static const u64 KERN_TYPE = 8900; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; -static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE; +static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_SELF_TEST_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; -static const char *ST_PASS = NULL; // the self-test can't work because the scrypt settings is part of the code at compile-time +static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "SCRYPT:1024:1:1:Mzg3MjYzNzYwMzE0NDE=:uM7P3Kg2X9En9KZPv3378YablKcuUoQ1mwunXdg3o1M="; 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; } diff --git a/src/modules/module_14600.c b/src/modules/module_14600.c index 46d30eb20..8999d6091 100644 --- a/src/modules/module_14600.c +++ b/src/modules/module_14600.c @@ -23,10 +23,11 @@ static const u64 KERN_TYPE = 14611; // this gets overwritten later instea static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_SLOW_HASH_SIMD_LOOP; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_SELF_TEST_DISABLE | OPTS_TYPE_BINARY_HASHFILE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; -static const char *ST_HASH = NULL; // ST_HASH_14600 multi-hash-mode algorithm, unlikely to match self-test hash settings +static const char *ST_HASH = "tbd"; 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; } diff --git a/src/modules/module_15700.c b/src/modules/module_15700.c index ac04271df..db11d596e 100644 --- a/src/modules/module_15700.c +++ b/src/modules/module_15700.c @@ -22,9 +22,10 @@ static const char *HASH_NAME = "Ethereum Wallet, SCRYPT"; static const u64 KERN_TYPE = 15700; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_SELF_TEST_DISABLE | OPTS_TYPE_ST_HEX; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; -static const char *ST_PASS = NULL; // the self-test is disabled, because the original scrypt settings would create a too long startup time +static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "$ethereum$s*262144*8*1*3134313837333434333838303231333633373433323633373534333136363537*73da7f80ec3bd4f2a128c3a815cfb4d576ecb1a9b47024c902e62ea926f7795b*910e0f8dc1f7ba41959e1089bb769f3e919109591913cc33ba03953d7a905efd"; 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; } diff --git a/src/modules/module_16500.c b/src/modules/module_16500.c index 5762b0031..948c484ff 100644 --- a/src/modules/module_16500.c +++ b/src/modules/module_16500.c @@ -23,10 +23,11 @@ static const char *HASH_NAME = "JWT (JSON Web Token)"; static const u64 KERN_TYPE = 16511; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE | OPTI_TYPE_NOT_ITERATED; -static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_BE; +static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_BE + | OPTS_TYPE_SELF_TEST_DISABLE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; -static const char *ST_HASH = NULL; // multi-hash-mode algorithm, unlikely to match self-test hash settings +static const char *ST_HASH = "eyJhbGciOiJIUzI1NiJ9.eyIzNDM2MzQyMCI6NTc2ODc1NDd9.f1nXZ3V_Hrr6ee-AFCTLaHRnrkiKmio2t3JqwL32guY"; 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; } diff --git a/src/terminal.c b/src/terminal.c index d1e8834e8..3a39e3b93 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -553,7 +553,14 @@ void example_hashes (hashcat_ctx_t *hashcat_ctx) if ((hashconfig->st_hash != NULL) && (hashconfig->st_pass != NULL)) { - event_log_info (hashcat_ctx, "HASH: %s", hashconfig->st_hash); + if (hashconfig->opts_type & OPTS_TYPE_BINARY_HASHFILE) + { + event_log_info (hashcat_ctx, "HASH (hex-encoded): %s", hashconfig->st_hash); + } + else + { + event_log_info (hashcat_ctx, "HASH: %s", hashconfig->st_hash); + } if (need_hexify ((const u8 *) hashconfig->st_pass, strlen (hashconfig->st_pass), user_options->separator, false)) {