diff --git a/docs/changes.txt b/docs/changes.txt index 7e5c262c6..931114a32 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -505,6 +505,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 6dd2de71f..c61c79bf5 100644 --- a/include/types.h +++ b/include/types.h @@ -672,6 +672,12 @@ typedef enum progress_mode } progress_mode_t; +typedef enum increment { + INCREMENT_NONE = 0, + INCREMENT_NORMAL = 1, + INCREMENT_INVERSED = 2, +} increment_t; + typedef enum user_options_defaults { ADVICE = true, @@ -712,7 +718,8 @@ typedef enum user_options_defaults HEX_WORDLIST = false, HOOK_THREADS = 0, IDENTIFY = false, - INCREMENT = false, + INCREMENT = INCREMENT_NONE, + INCREMENT_INVERSE = false, INCREMENT_MAX = PW_MAX, INCREMENT_MIN = 1, KEEP_GUESSING = false, @@ -846,6 +853,7 @@ typedef enum user_options_map IDX_HOOK_THREADS = 0xff1f, IDX_IDENTIFY = 0xff20, IDX_INCREMENT = 'i', + IDX_INCREMENT_INVERSE = 0xff61, IDX_INCREMENT_MAX = 0xff21, IDX_INCREMENT_MIN = 0xff22, IDX_INDUCTION_DIR = 0xff23, @@ -2443,7 +2451,7 @@ typedef struct user_options bool hex_charset; bool hex_salt; bool hex_wordlist; - bool increment; + increment_t increment; bool keep_guessing; bool keyspace; bool total_candidates; 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 0a133b7c7..26fdd384b 100644 --- a/src/mpsp.c +++ b/src/mpsp.c @@ -1096,12 +1096,49 @@ 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; user_options_t *user_options = hashcat_ctx->user_options; - if (user_options->increment == true) + if (user_options->increment != INCREMENT_NONE) { const u32 mask_length = mp_get_length (mask, hashconfig->opts_type); @@ -1132,11 +1169,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 == INCREMENT_INVERSED) { - 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 43665a007..77cfb5a81 100644 --- a/src/usage.c +++ b/src/usage.c @@ -145,6 +145,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = " -8, --custom-charset8 | CS | User-defined charset ?8 |", " --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 31056110b..c6c877729 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -90,6 +90,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}, @@ -247,7 +248,7 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->hex_wordlist = HEX_WORDLIST; user_options->hook_threads = HOOK_THREADS; user_options->identify = IDENTIFY; - user_options->increment = INCREMENT; + user_options->increment = (increment_t) INCREMENT; user_options->increment_max = INCREMENT_MAX; user_options->increment_min = INCREMENT_MIN; user_options->induction_dir = NULL; @@ -570,7 +571,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: user_options->increment++; break; + case IDX_INCREMENT_INVERSE: user_options->increment = INCREMENT_INVERSED; 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); @@ -938,28 +940,28 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } - if ((user_options->increment == true) && (user_options->progress_only == true)) + if ((user_options->increment != INCREMENT_NONE) && (user_options->progress_only == true)) { event_log_error (hashcat_ctx, "Increment is not allowed in combination with --progress-only."); return -1; } - if ((user_options->increment == true) && (user_options->speed_only == true)) + if ((user_options->increment != INCREMENT_NONE) && (user_options->speed_only == true)) { event_log_error (hashcat_ctx, "Increment is not allowed in combination with --speed-only."); return -1; } - if ((user_options->increment == true) && (user_options->attack_mode == ATTACK_MODE_STRAIGHT)) + if ((user_options->increment != INCREMENT_NONE) && (user_options->attack_mode == ATTACK_MODE_STRAIGHT)) { event_log_error (hashcat_ctx, "Increment is not allowed in attack mode 0 (straight)."); return -1; } - if ((user_options->increment == true) && (user_options->attack_mode == ATTACK_MODE_ASSOCIATION)) + if ((user_options->increment != INCREMENT_NONE) && (user_options->attack_mode == ATTACK_MODE_ASSOCIATION)) { event_log_error (hashcat_ctx, "Increment is not allowed in attack mode 9 (association)."); @@ -973,20 +975,28 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } - if ((user_options->increment == false) && (user_options->increment_min_chgd == true)) + if ((user_options->increment == INCREMENT_NONE) && (user_options->increment_min_chgd == true)) { event_log_error (hashcat_ctx, "Increment-min is only supported when combined with -i/--increment."); return -1; } - if ((user_options->increment == false) && (user_options->increment_max_chgd == true)) + if ((user_options->increment == INCREMENT_NONE) && (user_options->increment_max_chgd == true)) { event_log_error (hashcat_ctx, "Increment-max is only supported combined with -i/--increment."); return -1; } + // In case the user uses -iii, escaping enum bounds + if (user_options->increment > INCREMENT_INVERSED) + { + event_log_error (hashcat_ctx, "Invalid -i/--increment value."); + + return -1; + } + if ((user_options->rp_files_cnt > 0) && (user_options->rp_gen > 0)) { event_log_error (hashcat_ctx, "Combining -r/--rules-file and -g/--rules-generate is not supported."); @@ -1410,13 +1420,20 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } - if (user_options->increment == true) + if (user_options->increment == INCREMENT_NORMAL) { event_log_error (hashcat_ctx, "Can't change --increment (-i) in benchmark mode."); return -1; } + if (user_options->increment == INCREMENT_INVERSED) + { + 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."); @@ -2031,7 +2048,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 = INCREMENT_NONE; user_options->left = false; user_options->logfile = false; user_options->spin_damp = 0; @@ -2201,7 +2218,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->custom_charset_2 = DEF_MASK_CS_2; user_options->custom_charset_3 = DEF_MASK_CS_3; - user_options->increment = true; + user_options->increment = INCREMENT_NORMAL; } } else if (user_options->stdout_flag == true) @@ -2212,7 +2229,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->custom_charset_2 = DEF_MASK_CS_2; user_options->custom_charset_3 = DEF_MASK_CS_3; - user_options->increment = true; + user_options->increment = INCREMENT_NORMAL; } } else @@ -2223,7 +2240,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->custom_charset_2 = DEF_MASK_CS_2; user_options->custom_charset_3 = DEF_MASK_CS_3; - user_options->increment = true; + user_options->increment = INCREMENT_NORMAL; } } }