diff --git a/include/types.h b/include/types.h index e6ea946f9..85301d862 100644 --- a/include/types.h +++ b/include/types.h @@ -655,6 +655,7 @@ typedef enum user_options_defaults HOOK_THREADS = 0, IDENTIFY = false, INCREMENT = false, + INCREMENT_INVERSE = false, INCREMENT_MAX = PW_MAX, INCREMENT_MIN = 1, KEEP_GUESSING = false, @@ -774,6 +775,7 @@ typedef enum user_options_map IDX_HOOK_THREADS = 0xff1f, IDX_IDENTIFY = 0xff20, IDX_INCREMENT = 'i', + IDX_INCREMENT_INVERSE = 0xff56, IDX_INCREMENT_MAX = 0xff21, IDX_INCREMENT_MIN = 0xff22, IDX_INDUCTION_DIR = 0xff23, @@ -2349,6 +2351,7 @@ typedef struct user_options bool hex_salt; bool hex_wordlist; bool increment; + bool increment_inverse; bool keep_guessing; bool keyspace; bool left; diff --git a/src/mpsp.c b/src/mpsp.c index 3efe345d7..c316a6db7 100644 --- a/src/mpsp.c +++ b/src/mpsp.c @@ -1072,6 +1072,26 @@ static int mask_append_final (hashcat_ctx_t *hashcat_ctx, const char *mask) return 0; } +// ?l?u?d -> ?d?u?l +static char* reverseMask(const char *mask) { + int length = strlen(mask); + char *tmp_buf = (char *) hcmalloc (256); + + for (int i = length - 1, j = 0; i >= 0; i--) { + if (mask[i] == '\0') + continue; + if (i != 0 && mask[i - 1] == '?') { + tmp_buf[j++] = '?'; + tmp_buf[j++] = mask[i]; + i--; + } else { + tmp_buf[j++] = mask[i]; + } + } + + return tmp_buf; +} + static int mask_append (hashcat_ctx_t *hashcat_ctx, const char *mask, const char *prepend) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; @@ -1108,11 +1128,25 @@ static int mask_append (hashcat_ctx_t *hashcat_ctx, const char *mask, const char mask_truncated_next += snprintf (mask_truncated, 256, "%s,", prepend); } - if (mp_get_truncated_mask (hashcat_ctx, mask, strlen (mask), increment_len, mask_truncated_next) == -1) + if (user_options->increment_inverse == true) { - hcfree (mask_truncated); + if (mp_get_truncated_mask (hashcat_ctx, reverseMask(mask), strlen (mask), increment_len, mask_truncated_next) == -1) + { + hcfree (mask_truncated); - break; + break; + } + + mask_truncated = reverseMask(mask_truncated); + } + else + { + if (mp_get_truncated_mask (hashcat_ctx, mask, strlen (mask), increment_len, mask_truncated_next) == -1) + { + hcfree (mask_truncated); + + break; + } } const int rc = mask_append_final (hashcat_ctx, mask_truncated); diff --git a/src/user_options.c b/src/user_options.c index b1ed588f4..ec7430540 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -78,6 +78,7 @@ static const struct option long_options[] = {"increment-max", required_argument, NULL, IDX_INCREMENT_MAX}, {"increment-min", required_argument, NULL, IDX_INCREMENT_MIN}, {"increment", no_argument, NULL, IDX_INCREMENT}, + {"increment-inverse", no_argument, NULL, IDX_INCREMENT_INVERSE}, {"induction-dir", required_argument, NULL, IDX_INDUCTION_DIR}, {"keep-guessing", no_argument, NULL, IDX_KEEP_GUESSING}, {"kernel-accel", required_argument, NULL, IDX_KERNEL_ACCEL}, @@ -221,6 +222,7 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->hook_threads = HOOK_THREADS; user_options->identify = IDENTIFY; user_options->increment = INCREMENT; + user_options->increment = INCREMENT_INVERSE; user_options->increment_max = INCREMENT_MAX; user_options->increment_min = INCREMENT_MIN; user_options->induction_dir = NULL; @@ -524,6 +526,7 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) case IDX_BITMAP_MAX: user_options->bitmap_max = hc_strtoul (optarg, NULL, 10); break; case IDX_HOOK_THREADS: user_options->hook_threads = hc_strtoul (optarg, NULL, 10); break; case IDX_INCREMENT: user_options->increment = true; break; + case IDX_INCREMENT_INVERSE: user_options->increment_inverse = true; break; case IDX_INCREMENT_MIN: user_options->increment_min = hc_strtoul (optarg, NULL, 10); user_options->increment_min_chgd = true; break; case IDX_INCREMENT_MAX: user_options->increment_max = hc_strtoul (optarg, NULL, 10); @@ -865,6 +868,13 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } + if ((user_options->increment == false) && (user_options->increment_inverse == true)) + { + event_log_error (hashcat_ctx, "Increment-inverse is only supported combined with -i/--increment."); + + return -1; + } + if (user_options->increment_min > user_options->increment_max) { event_log_error (hashcat_ctx, "Invalid --increment-min value specified - must be >= --increment-max."); @@ -1305,6 +1315,13 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } + if (user_options->increment_inverse == true) + { + event_log_error (hashcat_ctx, "Can't change --increment-inverse in benchmark mode."); + + return -1; + } + if (user_options->restore == true) { event_log_error (hashcat_ctx, "Can't change --restore in benchmark mode."); @@ -1883,6 +1900,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->attack_mode = ATTACK_MODE_BF; user_options->hwmon_temp_abort = 0; user_options->increment = false; + user_options->increment_inverse = false; user_options->left = false; user_options->logfile = false; user_options->spin_damp = 0; @@ -3243,6 +3261,7 @@ void user_options_logger (hashcat_ctx_t *hashcat_ctx) logfile_top_uint (user_options->hook_threads); logfile_top_uint (user_options->identify); logfile_top_uint (user_options->increment); + logfile_top_uint (user_options->increment_inverse); logfile_top_uint (user_options->increment_max); logfile_top_uint (user_options->increment_min); logfile_top_uint (user_options->keep_guessing);