1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-12-23 07:08:19 +00:00

Add -a 1 support for slow candidates mode

This commit is contained in:
jsteube 2018-09-01 23:12:56 +02:00
parent 5f797147fb
commit d6ed195db9
5 changed files with 544 additions and 31 deletions

View File

@ -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;

View File

@ -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
{

View File

@ -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,24 +967,12 @@ 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))
{
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++;
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);

View File

@ -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;

View File

@ -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.");