diff --git a/docs/changes.txt b/docs/changes.txt index 283e3c0d4..d9bf7b630 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -441,6 +441,7 @@ - Added option --markov-inverse to inverse markov statistics, with the idea of reversing the order of the password candidates - Added temperature watchdog and fanspeed readings for CPU and GPU on macOS using iokit - Added temperature watchdog and utilization for CPU on linux using sysfs and procfs +- Added option --increment-inverse to increment masks from right-to-left instead of left-to-right ## ## Bugs 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/include/user_options.h b/include/user_options.h index a0e176944..d94b908b1 100644 --- a/include/user_options.h +++ b/include/user_options.h @@ -34,4 +34,6 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx); void user_options_info (hashcat_ctx_t *hashcat_ctx); +void increment_parse (hashcat_ctx_t *hashcat_ctx); + #endif // HC_USER_OPTIONS_H diff --git a/src/mpsp.c b/src/mpsp.c index 3efe345d7..dd1e67ea5 100644 --- a/src/mpsp.c +++ b/src/mpsp.c @@ -1072,6 +1072,43 @@ 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, const char *prepend) +{ + u32 maskLength = strlen (mask); + u32 prependLength = strlen (prepend); + + char *tmp_buf = (char *) hcmalloc (256); + + u32 i = 0; + + // Add prepend section to tmp_buf, avoiding reversal + if (prependLength != 0) + { + for (i = 0; i < prependLength ; i++) + { + tmp_buf[i] = prepend[i]; + } + tmp_buf[i++] = ','; + } + + for (u32 j = maskLength - 1; i <= maskLength - 1 ; i++) + { + if (mask[i] == '?' && mask[i + 1] != '\0') + { + tmp_buf[j--] = mask[i + 1]; + 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 +1145,32 @@ 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; + } + + if (prepend) + { + mask_truncated = reverseMask (mask_truncated, prepend); + } + else + { + 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/usage.c b/src/usage.c index 7cbf22348..5d00ace6d 100644 --- a/src/usage.c +++ b/src/usage.c @@ -132,6 +132,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = " -4, --custom-charset4 | CS | User-defined charset ?4 |", " --identify | | Shows all supported algorithms for input hashes | --identify my.hash", " -i, --increment | | Enable mask increment mode |", + " -ii,--increment-inverse | | Increment from right-to-left |", " --increment-min | Num | Start mask incrementing at X | --increment-min=4", " --increment-max | Num | Stop mask incrementing at X | --increment-max=8", " -S, --slow-candidates | | Enable slower (but advanced) candidate generators |", diff --git a/src/user_options.c b/src/user_options.c index b1ed588f4..c463e63ce 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; @@ -523,7 +525,8 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) case IDX_BITMAP_MIN: user_options->bitmap_min = hc_strtoul (optarg, NULL, 10); break; 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: increment_parse(hashcat_ctx); 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); @@ -1305,6 +1308,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 +1893,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; @@ -3186,6 +3197,21 @@ int user_options_check_files (hashcat_ctx_t *hashcat_ctx) return 0; } +void increment_parse (hashcat_ctx_t *hashcat_ctx) +{ + user_options_t *user_options = hashcat_ctx->user_options; + + // Set increment inverse when -ii + if (user_options->increment == true) + { + user_options->increment_inverse = true; + } + else + { + user_options->increment = true; + } +} + void user_options_logger (hashcat_ctx_t *hashcat_ctx) { user_options_t *user_options = hashcat_ctx->user_options; @@ -3243,6 +3269,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);