diff --git a/include/mpsp.h b/include/mpsp.h index e2335477b..794480167 100644 --- a/include/mpsp.h +++ b/include/mpsp.h @@ -41,6 +41,6 @@ void sp_stretch_root (hcstat_table_t *in, hcstat_table_t *out); int mask_ctx_init (mask_ctx_t *mask_ctx, const user_options_t *user_options, const user_options_extra_t *user_options_extra, const folder_config_t *folder_config, const restore_ctx_t *restore_ctx, const hashconfig_t *hashconfig); void mask_ctx_destroy (mask_ctx_t *mask_ctx); -void mask_ctx_parse_maskfile (mask_ctx_t *mask_ctx, user_options_t *user_options, const hashconfig_t *hashconfig); +int mask_ctx_parse_maskfile (mask_ctx_t *mask_ctx, user_options_t *user_options, const hashconfig_t *hashconfig); #endif // _MPSP_H diff --git a/include/types.h b/include/types.h index 2f33fe89e..12499cfc2 100644 --- a/include/types.h +++ b/include/types.h @@ -817,6 +817,13 @@ typedef struct } cs_t; +typedef struct +{ + char mf_buf[0x100]; + int mf_len; + +} mf_t; + typedef struct { u32 key; @@ -1172,6 +1179,8 @@ typedef struct char *mask; + mf_t *mfs; + } mask_ctx_t; typedef struct diff --git a/src/hashcat.c b/src/hashcat.c index 73d940806..921ae3c5e 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -283,11 +283,13 @@ static int inner1_loop (user_options_t *user_options, user_options_extra_t *user { // nothing yet } - if ((user_options->attack_mode == ATTACK_MODE_HYBRID1) || (user_options->attack_mode == ATTACK_MODE_HYBRID2)) + else if ((user_options->attack_mode == ATTACK_MODE_HYBRID1) || (user_options->attack_mode == ATTACK_MODE_HYBRID2)) { mask_ctx->mask = mask_ctx->masks[mask_ctx->masks_pos]; - mask_ctx_parse_maskfile (mask_ctx, user_options, hashconfig); + const int rc_mask_file = mask_ctx_parse_maskfile (mask_ctx, user_options, hashconfig); + + if (rc_mask_file == -1) return -1; mask_ctx->css_buf = mp_gen_css (mask_ctx->mask, strlen (mask_ctx->mask), mask_ctx->mp_sys, mask_ctx->mp_usr, &mask_ctx->css_cnt, hashconfig, user_options); @@ -312,7 +314,9 @@ static int inner1_loop (user_options_t *user_options, user_options_extra_t *user { mask_ctx->mask = mask_ctx->masks[mask_ctx->masks_pos]; - mask_ctx_parse_maskfile (mask_ctx, user_options, hashconfig); + const int rc_mask_file = mask_ctx_parse_maskfile (mask_ctx, user_options, hashconfig); + + if (rc_mask_file == -1) return -1; if (user_options->attack_mode == ATTACK_MODE_BF) // always true { diff --git a/src/mpsp.c b/src/mpsp.c index d1075a385..103c5bfa6 100644 --- a/src/mpsp.c +++ b/src/mpsp.c @@ -16,6 +16,8 @@ #include "interface.h" #include "mpsp.h" +#define MAX_MFS 5 // 4*charset, 1*mask + void mp_css_to_uniq_tbl (uint css_cnt, cs_t *css, uint uniq_tbls[SP_PW_MAX][CHARSIZ]) { /* generates a lookup table where key is the char itself for fastest possible lookup performance */ @@ -881,6 +883,8 @@ int mask_ctx_init (mask_ctx_t *mask_ctx, const user_options_t *user_options, con mask_ctx->masks_pos = 0; mask_ctx->masks_cnt = 0; + mask_ctx->mfs = (mf_t *) mycalloc (MAX_MFS, sizeof (mf_t)); + mp_setup_sys (mask_ctx->mp_sys); if (user_options->custom_charset_1) mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0, hashconfig, user_options); @@ -1110,112 +1114,108 @@ void mask_ctx_destroy (mask_ctx_t *mask_ctx) myfree (mask_ctx->masks); + myfree (mask_ctx->mfs); + myfree (mask_ctx); } -void mask_ctx_parse_maskfile (mask_ctx_t *mask_ctx, user_options_t *user_options, const hashconfig_t *hashconfig) +int mask_ctx_parse_maskfile (mask_ctx_t *mask_ctx, user_options_t *user_options, const hashconfig_t *hashconfig) { - if (mask_ctx->enabled == false) return; + if (mask_ctx->enabled == false) return 0; - if (mask_ctx->mask_from_file == false) return; + if (mask_ctx->mask_from_file == false) return 0; - if (mask_ctx->mask[0] == '\\' && mask_ctx->mask[1] == '#') mask_ctx->mask++; // escaped comment sign (sharp) "\#" + mf_t *mfs = mask_ctx->mfs; - char *str_ptr; - uint str_pos; + mfs[0].mf_len = 0; + mfs[1].mf_len = 0; + mfs[2].mf_len = 0; + mfs[3].mf_len = 0; + mfs[4].mf_len = 0; - uint mask_offset = 0; + char *mask_buf = mask_ctx->mask; - uint separator_cnt; + const int mask_len = strlen (mask_buf); - for (separator_cnt = 0; separator_cnt < 4; separator_cnt++) + bool escaped = false; + + int mf_cnt = 0; + + for (int i = 0; i < mask_len; i++) { - str_ptr = strstr (mask_ctx->mask + mask_offset, ","); + mf_t *mf = mfs + mf_cnt; - if (str_ptr == NULL) break; - - str_pos = str_ptr - mask_ctx->mask; - - // escaped separator, i.e. "\," - - if (str_pos > 0) + if (escaped == true) { - if (mask_ctx->mask[str_pos - 1] == '\\') + escaped = false; + + mf->mf_buf[mf->mf_len] = mask_buf[i]; + + mf->mf_len++; + } + else + { + if (mask_buf[i] == '\\') { - separator_cnt--; + escaped = true; + } + else if (mask_buf[i] == ',') + { + mf->mf_buf[mf->mf_len] = 0; - mask_offset = str_pos + 1; + mf_cnt++; - continue; + if (mf_cnt >= MAX_MFS) + { + log_error ("ERROR: Invalid line '%s' in maskfile", mask_buf); + + return -1; + } + } + else + { + mf->mf_buf[mf->mf_len] = mask_buf[i]; + + mf->mf_len++; } } + } - // reset the offset + mf_t *mf = mfs + mf_cnt; - mask_offset = 0; + mf->mf_buf[mf->mf_len] = 0; - mask_ctx->mask[str_pos] = 0; - - switch (separator_cnt) + for (int i = 0; i < mf_cnt; i++) + { + switch (i) { case 0: - user_options->custom_charset_1 = mask_ctx->mask; + user_options->custom_charset_1 = mfs[0].mf_buf; mp_reset_usr (mask_ctx->mp_usr, 0); mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0, hashconfig, user_options); break; case 1: - user_options->custom_charset_2 = mask_ctx->mask; + user_options->custom_charset_2 = mfs[1].mf_buf; mp_reset_usr (mask_ctx->mp_usr, 1); mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_2, 1, hashconfig, user_options); break; case 2: - user_options->custom_charset_3 = mask_ctx->mask; + user_options->custom_charset_3 = mfs[2].mf_buf; mp_reset_usr (mask_ctx->mp_usr, 2); mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_3, 2, hashconfig, user_options); break; case 3: - user_options->custom_charset_4 = mask_ctx->mask; + user_options->custom_charset_4 = mfs[3].mf_buf; mp_reset_usr (mask_ctx->mp_usr, 3); mp_setup_usr (mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_4, 3, hashconfig, user_options); break; } - - mask_ctx->mask += str_pos + 1; } - /** - * What follows is a very special case where "\," is within the mask field of a line in a .hcmask file only because otherwise (without the "\") - * it would be interpreted as a custom charset definition. - * - * We need to replace all "\," with just "," within the mask (but allow the special case "\\," which means "\" followed by ",") - * Note: "\\" is not needed to replace all "\" within the mask! The meaning of "\\" within a line containing the string "\\," is just to allow "\" followed by "," - */ + mask_ctx->mask = mfs[mf_cnt].mf_buf; - if (separator_cnt == 0) return; - - uint mask_len_cur = strlen (mask_ctx->mask); - - uint mask_out_pos = 0; - - char mask_prev = 0; - - for (uint mask_iter = 0; mask_iter < mask_len_cur; mask_iter++, mask_out_pos++) - { - if (mask_ctx->mask[mask_iter] == ',') - { - if (mask_prev == '\\') - { - mask_out_pos -= 1; // this means: skip the previous "\" - } - } - - mask_prev = mask_ctx->mask[mask_iter]; - - mask_ctx->mask[mask_out_pos] = mask_ctx->mask[mask_iter]; - } - - mask_ctx->mask[mask_out_pos] = 0; + return 0; }