From d6ed195db9a743f5b734c75b97f95e47cf88ba36 Mon Sep 17 00:00:00 2001 From: jsteube Date: Sat, 1 Sep 2018 23:12:56 +0200 Subject: [PATCH] Add -a 1 support for slow candidates mode --- include/slow_candidates.h | 20 ++- src/combinator.c | 106 +++++++++++++++ src/dispatch.c | 270 ++++++++++++++++++++++++++++++++++---- src/slow_candidates.c | 178 ++++++++++++++++++++++++- src/user_options.c | 1 + 5 files changed, 544 insertions(+), 31 deletions(-) diff --git a/include/slow_candidates.h b/include/slow_candidates.h index 0988eafc0..2798d7aa6 100644 --- a/include/slow_candidates.h +++ b/include/slow_candidates.h @@ -8,7 +8,7 @@ typedef struct extra_info_straight { - FILE *fd; + FILE *fp; u64 rule_pos_prev; u64 rule_pos; @@ -21,6 +21,24 @@ typedef struct extra_info_straight } extra_info_straight_t; +typedef struct extra_info_combi +{ + FILE *base_fp; + FILE *combs_fp; + + u64 comb_pos_prev; + u64 comb_pos; + + char *scratch_buf; + + u8 base_buf[256]; + u32 base_len; + + u8 out_buf[256]; + u32 out_len; + +} extra_info_combi_t; + typedef struct extra_info_mask { u64 pos; diff --git a/src/combinator.c b/src/combinator.c index e8be7fb7d..090098ae5 100644 --- a/src/combinator.c +++ b/src/combinator.c @@ -35,6 +35,112 @@ int combinator_ctx_init (hashcat_ctx_t *hashcat_ctx) if (user_options->slow_candidates == true) { + // this is always need to be COMBINATOR_MODE_BASE_LEFT + + if (user_options->attack_mode == ATTACK_MODE_COMBI) + { + // display + + char *dictfile1 = user_options_extra->hc_workv[0]; + char *dictfile2 = user_options_extra->hc_workv[1]; + + // at this point we know the file actually exist + // find the bigger dictionary and use as base + + if (hc_path_is_file (dictfile1) == false) + { + event_log_error (hashcat_ctx, "%s: Not a regular file.", dictfile1); + + return -1; + } + + if (hc_path_is_file (dictfile2) == false) + { + event_log_error (hashcat_ctx, "%s: Not a regular file.", dictfile2); + + return -1; + } + + FILE *fp1 = NULL; + FILE *fp2 = NULL; + + if ((fp1 = fopen (dictfile1, "rb")) == NULL) + { + event_log_error (hashcat_ctx, "%s: %s", dictfile1, strerror (errno)); + + return -1; + } + + if ((fp2 = fopen (dictfile2, "rb")) == NULL) + { + event_log_error (hashcat_ctx, "%s: %s", dictfile2, strerror (errno)); + + fclose (fp1); + + return -1; + } + + combinator_ctx->combs_cnt = 1; + + u64 words1_cnt = 0; + + const int rc1 = count_words (hashcat_ctx, fp1, dictfile1, &words1_cnt); + + if (rc1 == -1) + { + event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", dictfile1); + + fclose (fp1); + fclose (fp2); + + return -1; + } + + if (words1_cnt == 0) + { + event_log_error (hashcat_ctx, "%s: empty file.", dictfile1); + + fclose (fp1); + fclose (fp2); + + return -1; + } + + combinator_ctx->combs_cnt = 1; + + u64 words2_cnt = 0; + + const int rc2 = count_words (hashcat_ctx, fp2, dictfile2, &words2_cnt); + + if (rc2 == -1) + { + event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", dictfile2); + + fclose (fp1); + fclose (fp2); + + return -1; + } + + if (words2_cnt == 0) + { + event_log_error (hashcat_ctx, "%s: empty file.", dictfile2); + + fclose (fp1); + fclose (fp2); + + return -1; + } + + fclose (fp1); + fclose (fp2); + + combinator_ctx->dict1 = dictfile1; + combinator_ctx->dict2 = dictfile2; + + combinator_ctx->combs_mode = COMBINATOR_MODE_BASE_LEFT; + combinator_ctx->combs_cnt = words2_cnt; + } } else { diff --git a/src/dispatch.c b/src/dispatch.c index 641f278e0..0c5a3fe50 100644 --- a/src/dispatch.c +++ b/src/dispatch.c @@ -654,20 +654,50 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (words_fin == 0) break; } } - - else if (attack_mode == ATTACK_MODE_STRAIGHT) + else if (attack_mode == ATTACK_MODE_COMBI) { - char *dictfile = straight_ctx->dict; + const u32 combs_mode = combinator_ctx->combs_mode; - FILE *fd = fopen (dictfile, "rb"); + char *base_file; + char *combs_file; - if (fd == NULL) + if (combs_mode == COMBINATOR_MODE_BASE_LEFT) { - event_log_error (hashcat_ctx, "%s: %s", dictfile, strerror (errno)); + base_file = combinator_ctx->dict1; + combs_file = combinator_ctx->dict2; + } + else + { + base_file = combinator_ctx->dict2; + combs_file = combinator_ctx->dict1; + } + + FILE *base_fp = fopen (base_file, "rb"); + + if (base_fp == NULL) + { + event_log_error (hashcat_ctx, "%s: %s", base_file, strerror (errno)); + + return -1; + } + + FILE *combs_fp = fopen (combs_file, "rb"); + + if (combs_fp == NULL) + { + event_log_error (hashcat_ctx, "%s: %s", combs_file, strerror (errno)); return -1; } + extra_info_combi_t extra_info_combi; + + memset (&extra_info_combi, 0, sizeof (extra_info_combi)); + + extra_info_combi.base_fp = base_fp; + extra_info_combi.combs_fp = combs_fp; + extra_info_combi.scratch_buf = device_param->scratch_buf; + hashcat_ctx_t *hashcat_ctx_tmp = (hashcat_ctx_t *) hcmalloc (sizeof (hashcat_ctx_t)); memcpy (hashcat_ctx_tmp, hashcat_ctx, sizeof (hashcat_ctx_t)); // yes we actually want to copy these pointers @@ -678,7 +708,9 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (rc_wl_data_init == -1) { - fclose (fd); + fclose (combs_fp); + + fclose (base_fp); hcfree (hashcat_ctx_tmp->wl_data); @@ -687,11 +719,209 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) return -1; } + u64 words_cur = 0; + + while (status_ctx->run_thread_level1 == true) + { + u64 words_fin = 0; + + memset (device_param->pws_comp, 0, device_param->size_pws_comp); + memset (device_param->pws_idx, 0, device_param->size_pws_idx); + memset (device_param->pws_base_buf, 0, device_param->size_pws_base); + + u64 pre_rejects = -1u; + + while (pre_rejects) + { + u64 words_extra_total = 0; + + u64 words_extra = pre_rejects; + + pre_rejects = 0; + + memset (device_param->pws_pre_buf, 0, device_param->size_pws_pre); + + device_param->pws_pre_cnt = 0; + + while (words_extra) + { + const u64 work = get_work (hashcat_ctx, device_param, words_extra); + + if (work == 0) break; + + words_extra = 0; + + u64 words_off = device_param->words_off; + + words_fin = words_off + work; + + slow_candidates_seek (hashcat_ctx_tmp, &extra_info_combi, words_cur, words_off); + + words_cur = words_off; + + for (u64 i = words_cur; i < words_fin; i++) + { + slow_candidates_next (hashcat_ctx_tmp, &extra_info_combi); + + if ((extra_info_combi.out_len < hashconfig->pw_min) || (extra_info_combi.out_len > hashconfig->pw_max)) + { + words_extra++; + + continue; + } + + pw_pre_add (device_param, extra_info_combi.out_buf, extra_info_combi.out_len, NULL, 0, 0); + + if (status_ctx->run_thread_level1 == false) break; + } + + words_cur = words_fin; + + words_extra_total += words_extra; + + if (status_ctx->run_thread_level1 == false) break; + } + + if (0) + { + } + else + { + u64 pws_pre_cnt = device_param->pws_pre_cnt; + + for (u64 pws_pre_idx = 0; pws_pre_idx < pws_pre_cnt; pws_pre_idx++) + { + pw_pre_t *pw_pre = device_param->pws_pre_buf + pws_pre_idx; + + pw_base_add (device_param, pw_pre); + + pw_add (device_param, (const u8 *) pw_pre->pw_buf, (const int) pw_pre->pw_len); + } + } + + words_extra_total += pre_rejects; + + if (status_ctx->run_thread_level1 == false) break; + + if (words_extra_total > 0) + { + hc_thread_mutex_lock (status_ctx->mux_counter); + + for (u32 salt_pos = 0; salt_pos < hashes->salts_cnt; salt_pos++) + { + status_ctx->words_progress_rejected[salt_pos] += words_extra_total; + } + + hc_thread_mutex_unlock (status_ctx->mux_counter); + } + } + + // + // flush + // + + const u64 pws_cnt = device_param->pws_cnt; + + if (pws_cnt) + { + int CL_rc; + + CL_rc = run_copy (hashcat_ctx, device_param, pws_cnt); + + if (CL_rc == -1) + { + fclose (combs_fp); + + fclose (base_fp); + + hcfree (hashcat_ctx_tmp->wl_data); + + hcfree (hashcat_ctx_tmp); + + return -1; + } + + CL_rc = run_cracker (hashcat_ctx, device_param, pws_cnt); + + if (CL_rc == -1) + { + fclose (combs_fp); + + fclose (base_fp); + + hcfree (hashcat_ctx_tmp->wl_data); + + hcfree (hashcat_ctx_tmp); + + return -1; + } + + device_param->pws_cnt = 0; + + device_param->pws_base_cnt = 0; + } + + if (device_param->speed_only_finish == true) break; + + if (status_ctx->run_thread_level2 == true) + { + device_param->words_done = words_fin; + + status_ctx->words_cur = get_lowest_words_done (hashcat_ctx); + } + + if (status_ctx->run_thread_level1 == false) break; + + if (words_fin == 0) break; + } + + fclose (combs_fp); + + fclose (base_fp); + + wl_data_destroy (hashcat_ctx_tmp); + + hcfree (hashcat_ctx_tmp->wl_data); + + hcfree (hashcat_ctx_tmp); + } + else if (attack_mode == ATTACK_MODE_STRAIGHT) + { + char *dictfile = straight_ctx->dict; + + FILE *fp = fopen (dictfile, "rb"); + + if (fp == NULL) + { + event_log_error (hashcat_ctx, "%s: %s", dictfile, strerror (errno)); + + return -1; + } + extra_info_straight_t extra_info_straight; memset (&extra_info_straight, 0, sizeof (extra_info_straight)); - extra_info_straight.fd = fd; + extra_info_straight.fp = fp; + + hashcat_ctx_t *hashcat_ctx_tmp = (hashcat_ctx_t *) hcmalloc (sizeof (hashcat_ctx_t)); + + memcpy (hashcat_ctx_tmp, hashcat_ctx, sizeof (hashcat_ctx_t)); // yes we actually want to copy these pointers + + hashcat_ctx_tmp->wl_data = (wl_data_t *) hcmalloc (sizeof (wl_data_t)); + + const int rc_wl_data_init = wl_data_init (hashcat_ctx_tmp); + + if (rc_wl_data_init == -1) + { + fclose (fp); + + hcfree (hashcat_ctx_tmp->wl_data); + + hcfree (hashcat_ctx_tmp); + + return -1; + } u64 words_cur = 0; @@ -737,23 +967,11 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) { slow_candidates_next (hashcat_ctx_tmp, &extra_info_straight); - if (attack_kern == ATTACK_KERN_STRAIGHT) + if ((extra_info_straight.out_len < hashconfig->pw_min) || (extra_info_straight.out_len > hashconfig->pw_max)) { - if ((extra_info_straight.out_len < hashconfig->pw_min) || (extra_info_straight.out_len > hashconfig->pw_max)) - { - words_extra++; - - continue; - } - } - else if (attack_kern == ATTACK_KERN_COMBI) - { - if ((extra_info_straight.out_len < hashconfig->pw_min) || (extra_info_straight.out_len > hashconfig->pw_max)) - { - words_extra++; + words_extra++; - continue; - } + continue; } pw_pre_add (device_param, extra_info_straight.out_buf, extra_info_straight.out_len, extra_info_straight.base_buf, extra_info_straight.base_len, extra_info_straight.rule_pos_prev); @@ -816,7 +1034,7 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (CL_rc == -1) { - fclose (fd); + fclose (fp); hcfree (hashcat_ctx_tmp->wl_data); @@ -829,7 +1047,7 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (CL_rc == -1) { - fclose (fd); + fclose (fp); hcfree (hashcat_ctx_tmp->wl_data); @@ -857,7 +1075,7 @@ static int calc (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (words_fin == 0) break; } - fclose (fd); + fclose (fp); wl_data_destroy (hashcat_ctx_tmp); diff --git a/src/slow_candidates.c b/src/slow_candidates.c index fdf289646..acc2aa219 100644 --- a/src/slow_candidates.c +++ b/src/slow_candidates.c @@ -11,10 +11,12 @@ #include "rp_kernel_on_cpu_optimized.h" #include "wordlist.h" #include "mpsp.h" +#include "filehandling.h" #include "slow_candidates.h" void slow_candidates_seek (hashcat_ctx_t *hashcat_ctx, void *extra_info, const u64 cur, const u64 end) { + combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx; straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx; user_options_t *user_options = hashcat_ctx->user_options; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; @@ -25,7 +27,7 @@ void slow_candidates_seek (hashcat_ctx_t *hashcat_ctx, void *extra_info, const u { extra_info_straight_t *extra_info_straight = (extra_info_straight_t *) extra_info; - FILE *fd = extra_info_straight->fd; + FILE *fp = extra_info_straight->fp; const u64 overlap = end % straight_ctx->kernel_rules_cnt; @@ -38,7 +40,7 @@ void slow_candidates_seek (hashcat_ctx_t *hashcat_ctx, void *extra_info, const u while (1) { - get_next_word (hashcat_ctx, fd, &line_buf, &line_len); + get_next_word (hashcat_ctx, fp, &line_buf, &line_len); // post-process rule engine @@ -69,6 +71,85 @@ void slow_candidates_seek (hashcat_ctx_t *hashcat_ctx, void *extra_info, const u extra_info_straight->rule_pos_prev = overlap; extra_info_straight->rule_pos = overlap; } + else if (attack_mode == ATTACK_MODE_COMBI) + { + extra_info_combi_t *extra_info_combi = (extra_info_combi_t *) extra_info; + + FILE *base_fp = extra_info_combi->base_fp; + FILE *combs_fp = extra_info_combi->combs_fp; + + u64 overlap_cur = cur % combinator_ctx->combs_cnt; + const u64 overlap = end % combinator_ctx->combs_cnt; + + const u64 init = end - overlap; + + for (u64 i = cur; i < init; i += combinator_ctx->combs_cnt) + { + char *line_buf = NULL; + u32 line_len = 0; + + while (1) + { + get_next_word (hashcat_ctx, base_fp, &line_buf, &line_len); + + // post-process rule engine + + if (run_rule_engine ((int) user_options_extra->rule_len_l, user_options->rule_buf_l)) + { + if (line_len >= RP_PASSWORD_SIZE) continue; + + char rule_buf_out[RP_PASSWORD_SIZE]; + + memset (rule_buf_out, 0, sizeof (rule_buf_out)); + + const int rule_len_out = _old_apply_rule (user_options->rule_buf_l, (int) user_options_extra->rule_len_l, line_buf, (int) line_len, rule_buf_out); + + if (rule_len_out < 0) continue; + } + + break; + } + + memcpy (extra_info_combi->base_buf, line_buf, line_len); + + extra_info_combi->base_len = line_len; + + rewind (combs_fp); + + overlap_cur = 0; + } + + for (u64 i = overlap_cur; i < overlap; i++) + { + char *line_buf = extra_info_combi->scratch_buf; + u32 line_len = 0; + + while (1) + { + line_len = (u32) fgetl (combs_fp, line_buf); + + // post-process rule engine + + if (run_rule_engine ((int) user_options_extra->rule_len_l, user_options->rule_buf_l)) + { + if (line_len >= RP_PASSWORD_SIZE) continue; + + char rule_buf_out[RP_PASSWORD_SIZE]; + + memset (rule_buf_out, 0, sizeof (rule_buf_out)); + + const int rule_len_out = _old_apply_rule (user_options->rule_buf_l, (int) user_options_extra->rule_len_l, line_buf, (int) line_len, rule_buf_out); + + if (rule_len_out < 0) continue; + } + + break; + } + } + + extra_info_combi->comb_pos_prev = overlap; + extra_info_combi->comb_pos = overlap; + } else if (attack_mode == ATTACK_MODE_BF) { // nothing to do @@ -78,6 +159,7 @@ void slow_candidates_seek (hashcat_ctx_t *hashcat_ctx, void *extra_info, const u void slow_candidates_next (hashcat_ctx_t *hashcat_ctx, void *extra_info) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; + combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx; user_options_t *user_options = hashcat_ctx->user_options; @@ -89,7 +171,7 @@ void slow_candidates_next (hashcat_ctx_t *hashcat_ctx, void *extra_info) { extra_info_straight_t *extra_info_straight = (extra_info_straight_t *) extra_info; - FILE *fd = extra_info_straight->fd; + FILE *fp = extra_info_straight->fp; if (extra_info_straight->rule_pos == 0) { @@ -98,7 +180,7 @@ void slow_candidates_next (hashcat_ctx_t *hashcat_ctx, void *extra_info) while (1) { - get_next_word (hashcat_ctx, fd, &line_buf, &line_len); + get_next_word (hashcat_ctx, fp, &line_buf, &line_len); line_len = (u32) convert_from_hex (hashcat_ctx, line_buf, line_len); @@ -154,6 +236,94 @@ void slow_candidates_next (hashcat_ctx_t *hashcat_ctx, void *extra_info) extra_info_straight->rule_pos = 0; } } + else if (attack_mode == ATTACK_MODE_COMBI) + { + extra_info_combi_t *extra_info_combi = (extra_info_combi_t *) extra_info; + + FILE *base_fp = extra_info_combi->base_fp; + FILE *combs_fp = extra_info_combi->combs_fp; + + if (extra_info_combi->comb_pos == 0) + { + char *line_buf; + u32 line_len; + + while (1) + { + get_next_word (hashcat_ctx, base_fp, &line_buf, &line_len); + + line_len = (u32) convert_from_hex (hashcat_ctx, line_buf, line_len); + + // post-process rule engine + + if (run_rule_engine ((int) user_options_extra->rule_len_l, user_options->rule_buf_l)) + { + if (line_len >= RP_PASSWORD_SIZE) continue; + + char rule_buf_out[RP_PASSWORD_SIZE]; + + memset (rule_buf_out, 0, sizeof (rule_buf_out)); + + const int rule_len_out = _old_apply_rule (user_options->rule_buf_l, (int) user_options_extra->rule_len_l, line_buf, (int) line_len, rule_buf_out); + + if (rule_len_out < 0) continue; + } + + break; + } + + memcpy (extra_info_combi->base_buf, line_buf, line_len); + + extra_info_combi->base_len = line_len; + + rewind (combs_fp); + } + + memcpy (extra_info_combi->out_buf, extra_info_combi->base_buf, extra_info_combi->base_len); + + extra_info_combi->out_len = extra_info_combi->base_len; + + char *line_buf = extra_info_combi->scratch_buf; + + u32 line_len = 0; + + while (1) + { + line_len = (u32) fgetl (combs_fp, line_buf); + + // post-process rule engine + + if (run_rule_engine ((int) user_options_extra->rule_len_r, user_options->rule_buf_r)) + { + if (line_len >= RP_PASSWORD_SIZE) continue; + + char rule_buf_out[RP_PASSWORD_SIZE]; + + memset (rule_buf_out, 0, sizeof (rule_buf_out)); + + const int rule_len_out = _old_apply_rule (user_options->rule_buf_r, (int) user_options_extra->rule_len_r, line_buf, (int) line_len, rule_buf_out); + + if (rule_len_out < 0) continue; + } + + break; + } + + memcpy (extra_info_combi->out_buf + extra_info_combi->out_len, line_buf, line_len); + + extra_info_combi->out_len += line_len; + + memset (extra_info_combi->out_buf + extra_info_combi->out_len, 0, sizeof (extra_info_combi->out_buf) - extra_info_combi->out_len); + + extra_info_combi->comb_pos_prev = extra_info_combi->comb_pos; + + extra_info_combi->comb_pos++; + + if (extra_info_combi->comb_pos == combinator_ctx->combs_cnt) + { + extra_info_combi->comb_pos = 0; + } + } else if (attack_mode == ATTACK_MODE_BF) { extra_info_mask_t *extra_info_mask = (extra_info_mask_t *) extra_info; diff --git a/src/user_options.c b/src/user_options.c index a473ebb03..9f0e6ebc0 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -451,6 +451,7 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) if (user_options->slow_candidates == true) { if ((user_options->attack_mode != ATTACK_MODE_STRAIGHT) + && (user_options->attack_mode != ATTACK_MODE_COMBI) && (user_options->attack_mode != ATTACK_MODE_BF)) { event_log_error (hashcat_ctx, "Invalid attack mode (-a) value specified in slow-candidates mode.");