int cpt_ctx_init (hashcat_ctx_t *hashcat_ctx) { cpt_ctx_t *cpt_ctx = hashcat_ctx->cpt_ctx; user_options_t *user_options = hashcat_ctx->user_options; cpt_ctx->enabled = false; if (user_options->example_hashes == true) return 0; if (user_options->keyspace == true) return 0; if (user_options->left == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->show == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; cpt_ctx->enabled = true; cpt_ctx->cpt_buf = (cpt_t *) hccalloc (CPT_CACHE, sizeof (cpt_t)); cpt_ctx->cpt_total = 0; cpt_ctx->cpt_pos = 0; cpt_ctx->cpt_start = hc_time (NULL); return 0; }
int dictstat_init (hashcat_ctx_t *hashcat_ctx) { dictstat_ctx_t *dictstat_ctx = hashcat_ctx->dictstat_ctx; folder_config_t *folder_config = hashcat_ctx->folder_config; user_options_t *user_options = hashcat_ctx->user_options; dictstat_ctx->enabled = false; if (user_options->benchmark == true) return 0; if (user_options->example_hashes == true) return 0; if (user_options->keyspace == true) return 0; if (user_options->left == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->show == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; if (user_options->attack_mode == ATTACK_MODE_BF) return 0; dictstat_ctx->enabled = true; dictstat_ctx->base = (dictstat_t *) hccalloc (MAX_DICTSTAT, sizeof (dictstat_t)); dictstat_ctx->cnt = 0; hc_asprintf (&dictstat_ctx->filename, "%s/%s", folder_config->profile_dir, DICTSTAT_FILENAME); return 0; }
static int mp_css_append_salt (hashcat_ctx_t *hashcat_ctx, salt_t *salt_buf) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; u32 salt_len = salt_buf->salt_len; u8 *salt_buf_ptr = (u8 *) salt_buf->salt_buf; u32 css_cnt_salt = mask_ctx->css_cnt + salt_len; cs_t *css_buf_salt = (cs_t *) hccalloc (css_cnt_salt, sizeof (cs_t)); memcpy (css_buf_salt, mask_ctx->css_buf, mask_ctx->css_cnt * sizeof (cs_t)); for (u32 i = 0, j = mask_ctx->css_cnt; i < salt_len; i++, j++) { css_buf_salt[j].cs_buf[0] = salt_buf_ptr[i]; css_buf_salt[j].cs_len = 1; } hcfree (mask_ctx->css_buf); mask_ctx->css_buf = css_buf_salt; mask_ctx->css_cnt = css_cnt_salt; return 0; }
static void main_outerloop_starting (MAYBE_UNUSED hashcat_ctx_t *hashcat_ctx, MAYBE_UNUSED const void *buf, MAYBE_UNUSED const size_t len) { const user_options_t *user_options = hashcat_ctx->user_options; const user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; hashcat_user_t *hashcat_user = hashcat_ctx->hashcat_user; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; /** * keypress thread */ hashcat_user->outer_threads_cnt = 0; hashcat_user->outer_threads = (hc_thread_t *) hccalloc (2, sizeof (hc_thread_t)); if (hashcat_user->outer_threads == NULL) return; status_ctx->shutdown_outer = false; if (user_options->keyspace == false && user_options->benchmark == false && user_options->stdout_flag == false && user_options->opencl_info == false && user_options->speed_only == false) { if ((user_options_extra->wordlist_mode == WL_MODE_FILE) || (user_options_extra->wordlist_mode == WL_MODE_MASK)) { // see thread_keypress() how to access status information hc_thread_create (hashcat_user->outer_threads[hashcat_user->outer_threads_cnt], thread_keypress, hashcat_ctx); hashcat_user->outer_threads_cnt++; } } }
u32 hlfmt_detect (hashcat_ctx_t *hashcat_ctx, FILE *fp, u32 max_check) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; // Exception: those formats are wrongly detected as HLFMT_SHADOW, prevent it if (hashconfig->hash_mode == 5300) return HLFMT_HASHCAT; if (hashconfig->hash_mode == 5400) return HLFMT_HASHCAT; u32 *formats_cnt = (u32 *) hccalloc (HLFMTS_CNT, sizeof (u32)); u32 num_check = 0; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (fp)) { const size_t line_len = fgetl (fp, line_buf); if (line_len == 0) continue; if (hlfmt_detect_pwdump (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_PWDUMP]++; if (hlfmt_detect_passwd (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_PASSWD]++; if (hlfmt_detect_shadow (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_SHADOW]++; if (num_check == max_check) break; num_check++; } hcfree (line_buf); u32 hashlist_format = HLFMT_HASHCAT; for (u32 i = 1; i < HLFMTS_CNT; i++) { if (formats_cnt[i - 1] >= formats_cnt[i]) continue; hashlist_format = i; } free (formats_cnt); return hashlist_format; }
static int mp_css_utf16be_expand (hashcat_ctx_t *hashcat_ctx) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; u32 css_cnt_utf16be = mask_ctx->css_cnt * 2; cs_t *css_buf_utf16be = (cs_t *) hccalloc (css_cnt_utf16be, sizeof (cs_t)); for (u32 i = 0, j = 0; i < mask_ctx->css_cnt; i += 1, j += 2) { css_buf_utf16be[j + 0].cs_buf[0] = 0; css_buf_utf16be[j + 0].cs_len = 1; memcpy (&css_buf_utf16be[j + 1], &mask_ctx->css_buf[i], sizeof (cs_t)); } hcfree (mask_ctx->css_buf); mask_ctx->css_buf = css_buf_utf16be; mask_ctx->css_cnt = css_cnt_utf16be; return 0; }
static int sp_setup_tbl (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_t *user_options = hashcat_ctx->user_options; char *shared_dir = folder_config->shared_dir; char *hcstat = user_options->markov_hcstat; u32 disable = user_options->markov_disable; u32 classic = user_options->markov_classic; hcstat_table_t *root_table_buf = mask_ctx->root_table_buf; hcstat_table_t *markov_table_buf = mask_ctx->markov_table_buf; /** * Initialize hcstats */ u64 *root_stats_buf = (u64 *) hccalloc (SP_ROOT_CNT, sizeof (u64)); u64 *root_stats_ptr = root_stats_buf; u64 *root_stats_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_stats_buf_by_pos[i] = root_stats_ptr; root_stats_ptr += CHARSIZ; } u64 *markov_stats_buf = (u64 *) hccalloc (SP_MARKOV_CNT, sizeof (u64)); u64 *markov_stats_ptr = markov_stats_buf; u64 *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_stats_buf_by_key[i][j] = markov_stats_ptr; markov_stats_ptr += CHARSIZ; } } /** * Load hcstats File */ char hcstat_tmp[256]; if (hcstat == NULL) { snprintf (hcstat_tmp, sizeof (hcstat_tmp), "%s/%s", shared_dir, SP_HCSTAT); hcstat = hcstat_tmp; } struct stat s; if (stat (hcstat, &s) == -1) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } FILE *fd = fopen (hcstat, "rb"); if (fd == NULL) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } u8 *inbuf = (u8 *) hcmalloc (s.st_size); SizeT inlen = (SizeT) hc_fread (inbuf, 1, s.st_size, fd); if (inlen != (SizeT) s.st_size) { event_log_error (hashcat_ctx, "%s: Could not read data.", hcstat); fclose (fd); hcfree (inbuf); return -1; } fclose (fd); u8 *outbuf = (u8 *) hcmalloc (SP_FILESZ); SizeT outlen = SP_FILESZ; const char props = 0x1c; // lzma properties constant, retrieved with 7z2hashcat const SRes res = hc_lzma2_decompress (inbuf, &inlen, outbuf, &outlen, &props); if (res != SZ_OK) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } if (outlen != SP_FILESZ) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } u64 *ptr = (u64 *) outbuf; u64 v = *ptr++; u64 z = *ptr++; memcpy (root_stats_buf, ptr, sizeof (u64) * SP_ROOT_CNT); ptr += SP_ROOT_CNT; memcpy (markov_stats_buf, ptr, sizeof (u64) * SP_MARKOV_CNT); // ptr += SP_MARKOV_CNT; hcfree (inbuf); hcfree (outbuf); /** * switch endianess */ v = byte_swap_64 (v); z = byte_swap_64 (z); for (int i = 0; i < SP_ROOT_CNT; i++) root_stats_buf[i] = byte_swap_64 (root_stats_buf[i]); for (int i = 0; i < SP_MARKOV_CNT; i++) markov_stats_buf[i] = byte_swap_64 (markov_stats_buf[i]); /** * verify header */ if (v != SP_VERSION) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } if (z != 0) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } /** * Markov modifier of hcstat_table on user request */ if (disable) { memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (u64)); memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (u64)); } if (classic) { /* Add all stats to first position */ for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = root_stats_buf_by_pos[0]; u64 *in = root_stats_buf_by_pos[i]; for (int j = 0; j < CHARSIZ; j++) { *out++ += *in++; } } for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = markov_stats_buf_by_key[0][0]; u64 *in = markov_stats_buf_by_key[i][0]; for (int j = 0; j < CHARSIZ; j++) { for (int k = 0; k < CHARSIZ; k++) { *out++ += *in++; } } } /* copy them to all pw_positions */ for (int i = 1; i < SP_PW_MAX; i++) { memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (u64)); } for (int i = 1; i < SP_PW_MAX; i++) { memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (u64)); } } /** * Initialize tables */ hcstat_table_t *root_table_ptr = root_table_buf; hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_table_buf_by_pos[i] = root_table_ptr; root_table_ptr += CHARSIZ; } hcstat_table_t *markov_table_ptr = markov_table_buf; hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_table_buf_by_key[i][j] = markov_table_ptr; markov_table_ptr += CHARSIZ; } } /** * Convert hcstat to tables */ for (int i = 0; i < SP_ROOT_CNT; i++) { u32 key = i % CHARSIZ; root_table_buf[i].key = key; root_table_buf[i].val = root_stats_buf[i]; } for (int i = 0; i < SP_MARKOV_CNT; i++) { u32 key = i % CHARSIZ; markov_table_buf[i].key = key; markov_table_buf[i].val = markov_stats_buf[i]; } hcfree (root_stats_buf); hcfree (markov_stats_buf); /** * Finally sort them */ for (int i = 0; i < SP_PW_MAX; i++) { qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } } return 0; }
int mask_ctx_init (hashcat_ctx_t *hashcat_ctx) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; user_options_t *user_options = hashcat_ctx->user_options; mask_ctx->enabled = false; if (user_options->example_hashes == true) return 0; if (user_options->left == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->show == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; if (user_options->attack_mode == ATTACK_MODE_STRAIGHT) return 0; if (user_options->attack_mode == ATTACK_MODE_COMBI) return 0; mask_ctx->enabled = true; mask_ctx->root_table_buf = (hcstat_table_t *) hccalloc (SP_ROOT_CNT, sizeof (hcstat_table_t)); mask_ctx->markov_table_buf = (hcstat_table_t *) hccalloc (SP_MARKOV_CNT, sizeof (hcstat_table_t)); const int rc_setup_tbl = sp_setup_tbl (hashcat_ctx); if (rc_setup_tbl == -1) return -1; mask_ctx->root_css_buf = (cs_t *) hccalloc (SP_PW_MAX, sizeof (cs_t)); mask_ctx->markov_css_buf = (cs_t *) hccalloc (SP_PW_MAX * CHARSIZ, sizeof (cs_t)); mask_ctx->css_cnt = 0; mask_ctx->css_buf = NULL; mask_ctx->mask_from_file = false; mask_ctx->masks = NULL; mask_ctx->masks_pos = 0; mask_ctx->masks_cnt = 0; mask_ctx->mfs = (mf_t *) hccalloc (MAX_MFS, sizeof (mf_t)); mp_setup_sys (mask_ctx->mp_sys); if (user_options->custom_charset_1) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0); if (rc == -1) return -1; } if (user_options->custom_charset_2) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_2, 1); if (rc == -1) return -1; } if (user_options->custom_charset_3) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_3, 2); if (rc == -1) return -1; } if (user_options->custom_charset_4) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_4, 3); if (rc == -1) return -1; } if (user_options->attack_mode == ATTACK_MODE_BF) { if (user_options->benchmark == false) { if (user_options_extra->hc_workc) { char *arg = user_options_extra->hc_workv[0]; if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { mask_ctx->mask_from_file = true; for (int i = 0; i < user_options_extra->hc_workc; i++) { arg = user_options_extra->hc_workv[i]; if (hc_path_is_file (arg) == true) { FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } } else { const char *mask = DEF_MASK; const int rc = mask_append (hashcat_ctx, mask, NULL); if (rc == -1) return -1; } } else { const char *mask = hashconfig_benchmark_mask (hashcat_ctx); const int rc = mask_append (hashcat_ctx, mask, NULL); if (rc == -1) return -1; } } else if (user_options->attack_mode == ATTACK_MODE_HYBRID1) { // display char *arg = user_options_extra->hc_workv[user_options_extra->hc_workc - 1]; // mod if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { if (hc_path_is_file (arg) == true) { mask_ctx->mask_from_file = true; FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } else if (user_options->attack_mode == ATTACK_MODE_HYBRID2) { // display char *arg = user_options_extra->hc_workv[0]; // mod if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { if (hc_path_is_file (arg) == true) { mask_ctx->mask_from_file = true; FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } if (mask_ctx->masks_cnt == 0) { event_log_error (hashcat_ctx, "Invalid mask."); return -1; } mask_ctx->mask = mask_ctx->masks[0]; return 0; }
static int inner2_loop (hashcat_ctx_t *hashcat_ctx) { hashes_t *hashes = hashcat_ctx->hashes; induct_ctx_t *induct_ctx = hashcat_ctx->induct_ctx; logfile_ctx_t *logfile_ctx = hashcat_ctx->logfile_ctx; opencl_ctx_t *opencl_ctx = hashcat_ctx->opencl_ctx; restore_ctx_t *restore_ctx = hashcat_ctx->restore_ctx; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; user_options_t *user_options = hashcat_ctx->user_options; //status_ctx->run_main_level1 = true; //status_ctx->run_main_level2 = true; //status_ctx->run_main_level3 = true; status_ctx->run_thread_level1 = true; status_ctx->run_thread_level2 = true; status_ctx->devices_status = STATUS_INIT; logfile_generate_subid (hashcat_ctx); logfile_sub_msg ("START"); status_progress_reset (hashcat_ctx); status_ctx->msec_paused = 0; status_ctx->words_off = 0; status_ctx->words_cur = 0; if (restore_ctx->rd) { restore_data_t *rd = restore_ctx->rd; if (rd->words_cur > 0) { status_ctx->words_off = rd->words_cur; status_ctx->words_cur = status_ctx->words_off; rd->words_cur = 0; // --restore always overrides --skip user_options->skip = 0; } } if (user_options->skip > 0) { status_ctx->words_off = user_options->skip; status_ctx->words_cur = status_ctx->words_off; user_options->skip = 0; } opencl_session_reset (hashcat_ctx); cpt_ctx_reset (hashcat_ctx); /** * Update attack-mode specific stuff based on mask */ const int rc_mask_ctx_update_loop = mask_ctx_update_loop (hashcat_ctx); if (rc_mask_ctx_update_loop == -1) return 0; /** * Update attack-mode specific stuff based on wordlist */ const int rc_straight_ctx_update_loop = straight_ctx_update_loop (hashcat_ctx); if (rc_straight_ctx_update_loop == -1) return 0; // words base const u64 amplifier_cnt = user_options_extra_amplifier (hashcat_ctx); status_ctx->words_base = status_ctx->words_cnt / amplifier_cnt; EVENT (EVENT_CALCULATED_WORDS_BASE); if (user_options->keyspace == true) return 0; // restore stuff if (status_ctx->words_off > status_ctx->words_base) { event_log_error (hashcat_ctx, "Restore value is greater than keyspace."); return -1; } const u64 progress_restored = status_ctx->words_off * amplifier_cnt; for (u32 i = 0; i < hashes->salts_cnt; i++) { status_ctx->words_progress_restored[i] = progress_restored; } /** * limit kernel loops by the amplification count we have from: * - straight_ctx, combinator_ctx or mask_ctx for fast hashes * - hash iteration count for slow hashes * this is required for autotune */ opencl_ctx_devices_kernel_loops (hashcat_ctx); /** * prepare thread buffers */ thread_param_t *threads_param = (thread_param_t *) hccalloc (opencl_ctx->devices_cnt, sizeof (thread_param_t)); hc_thread_t *c_threads = (hc_thread_t *) hccalloc (opencl_ctx->devices_cnt, sizeof (hc_thread_t)); /** * create autotune threads */ EVENT (EVENT_AUTOTUNE_STARTING); status_ctx->devices_status = STATUS_AUTOTUNE; for (u32 device_id = 0; device_id < opencl_ctx->devices_cnt; device_id++) { thread_param_t *thread_param = threads_param + device_id; thread_param->hashcat_ctx = hashcat_ctx; thread_param->tid = device_id; hc_thread_create (c_threads[device_id], thread_autotune, thread_param); } hc_thread_wait (opencl_ctx->devices_cnt, c_threads); EVENT (EVENT_AUTOTUNE_FINISHED); /** * autotune modified kernel_accel, which modifies opencl_ctx->kernel_power_all */ opencl_ctx_devices_update_power (hashcat_ctx); /** * Begin loopback recording */ if (user_options->loopback == true) { loopback_write_open (hashcat_ctx); } /** * Prepare cracking stats */ hc_timer_set (&status_ctx->timer_running); hc_time_t runtime_start; hc_time (&runtime_start); status_ctx->runtime_start = runtime_start; /** * create cracker threads */ EVENT (EVENT_CRACKER_STARTING); status_ctx->devices_status = STATUS_RUNNING; status_ctx->accessible = true; for (u32 device_id = 0; device_id < opencl_ctx->devices_cnt; device_id++) { thread_param_t *thread_param = threads_param + device_id; thread_param->hashcat_ctx = hashcat_ctx; thread_param->tid = device_id; if (user_options_extra->wordlist_mode == WL_MODE_STDIN) { hc_thread_create (c_threads[device_id], thread_calc_stdin, thread_param); } else { hc_thread_create (c_threads[device_id], thread_calc, thread_param); } } hc_thread_wait (opencl_ctx->devices_cnt, c_threads); hcfree (c_threads); hcfree (threads_param); if ((status_ctx->devices_status == STATUS_RUNNING) && (status_ctx->checkpoint_shutdown == true)) { myabort_checkpoint (hashcat_ctx); } if ((status_ctx->devices_status != STATUS_CRACKED) && (status_ctx->devices_status != STATUS_ABORTED) && (status_ctx->devices_status != STATUS_ABORTED_CHECKPOINT) && (status_ctx->devices_status != STATUS_ABORTED_RUNTIME) && (status_ctx->devices_status != STATUS_QUIT) && (status_ctx->devices_status != STATUS_BYPASS)) { status_ctx->devices_status = STATUS_EXHAUSTED; } // update some timer hc_time_t runtime_stop; hc_time (&runtime_stop); status_ctx->runtime_stop = runtime_stop; logfile_sub_uint (runtime_start); logfile_sub_uint (runtime_stop); if (hashcat_get_status (hashcat_ctx, status_ctx->hashcat_status_final) == -1) { fprintf (stderr, "Initialization problem: the hashcat status monitoring function returned an unexpected value\n"); } status_ctx->accessible = false; EVENT (EVENT_CRACKER_FINISHED); // mark sub logfile logfile_sub_var_uint ("status-after-work", status_ctx->devices_status); logfile_sub_msg ("STOP"); // stop loopback recording if (user_options->loopback == true) { loopback_write_close (hashcat_ctx); } // New induction folder check, which is a controlled recursion if (induct_ctx->induction_dictionaries_cnt == 0) { induct_ctx_scan (hashcat_ctx); while (induct_ctx->induction_dictionaries_cnt) { for (induct_ctx->induction_dictionaries_pos = 0; induct_ctx->induction_dictionaries_pos < induct_ctx->induction_dictionaries_cnt; induct_ctx->induction_dictionaries_pos++) { if (status_ctx->devices_status == STATUS_EXHAUSTED) { const int rc_inner2_loop = inner2_loop (hashcat_ctx); if (rc_inner2_loop == -1) myabort (hashcat_ctx); if (status_ctx->run_main_level3 == false) break; } unlink (induct_ctx->induction_dictionaries[induct_ctx->induction_dictionaries_pos]); } hcfree (induct_ctx->induction_dictionaries); induct_ctx_scan (hashcat_ctx); } } return 0; }
int mask_ctx_update_loop (hashcat_ctx_t *hashcat_ctx) { combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx; hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; logfile_ctx_t *logfile_ctx = hashcat_ctx->logfile_ctx; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; user_options_t *user_options = hashcat_ctx->user_options; if (user_options_extra->attack_kern == ATTACK_KERN_COMBI) { if (user_options->attack_mode == ATTACK_MODE_COMBI) { } else if ((user_options->attack_mode == ATTACK_MODE_HYBRID1) || (user_options->attack_mode == ATTACK_MODE_HYBRID2)) { if (((hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) == 0) && (user_options->attack_mode == ATTACK_MODE_HYBRID2)) { mask_ctx->mask = mask_ctx->masks[mask_ctx->masks_pos]; const int rc_mask_file = mask_ctx_parse_maskfile (hashcat_ctx); if (rc_mask_file == -1) return -1; mask_ctx->css_buf = (cs_t *) hccalloc (256, sizeof (cs_t)); const int rc_gen_css = mp_gen_css (hashcat_ctx, mask_ctx->mask, strlen (mask_ctx->mask), mask_ctx->mp_sys, mask_ctx->mp_usr, mask_ctx->css_buf, &mask_ctx->css_cnt); if (rc_gen_css == -1) return -1; u32 uniq_tbls[SP_PW_MAX][CHARSIZ] = { { 0 } }; mp_css_to_uniq_tbl (hashcat_ctx, mask_ctx->css_cnt, mask_ctx->css_buf, uniq_tbls); sp_tbl_to_css (mask_ctx->root_table_buf, mask_ctx->markov_table_buf, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, user_options->markov_threshold, uniq_tbls); const int rc_get_sum = sp_get_sum (0, mask_ctx->css_cnt, mask_ctx->root_css_buf, &mask_ctx->bfs_cnt); if (rc_get_sum == -1) { event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of mask: %s", mask_ctx->mask); return -1; } const int rc_update_mp = opencl_session_update_mp (hashcat_ctx); if (rc_update_mp == -1) return -1; } else { mask_ctx->mask = mask_ctx->masks[mask_ctx->masks_pos]; const int rc_mask_file = mask_ctx_parse_maskfile (hashcat_ctx); if (rc_mask_file == -1) return -1; mask_ctx->css_buf = (cs_t *) hccalloc (256, sizeof (cs_t)); const int rc_gen_css = mp_gen_css (hashcat_ctx, mask_ctx->mask, strlen (mask_ctx->mask), mask_ctx->mp_sys, mask_ctx->mp_usr, mask_ctx->css_buf, &mask_ctx->css_cnt); if (rc_gen_css == -1) return -1; u32 uniq_tbls[SP_PW_MAX][CHARSIZ] = { { 0 } }; mp_css_to_uniq_tbl (hashcat_ctx, mask_ctx->css_cnt, mask_ctx->css_buf, uniq_tbls); sp_tbl_to_css (mask_ctx->root_table_buf, mask_ctx->markov_table_buf, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, user_options->markov_threshold, uniq_tbls); const int rc_get_sum = sp_get_sum (0, mask_ctx->css_cnt, mask_ctx->root_css_buf, &combinator_ctx->combs_cnt); if (rc_get_sum == -1) { event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of mask: %s", mask_ctx->mask); return -1; } const int rc_update_mp = opencl_session_update_mp (hashcat_ctx); if (rc_update_mp == -1) return -1; } } const int rc_update_combinator = opencl_session_update_combinator (hashcat_ctx); if (rc_update_combinator == -1) return -1; } else if (user_options_extra->attack_kern == ATTACK_KERN_BF) { mask_ctx->mask = mask_ctx->masks[mask_ctx->masks_pos]; const int rc_mask_file = mask_ctx_parse_maskfile (hashcat_ctx); if (rc_mask_file == -1) return -1; if (user_options->attack_mode == ATTACK_MODE_BF) // always true { mask_ctx->css_buf = (cs_t *) hccalloc (256, sizeof (cs_t)); const int rc_gen_css = mp_gen_css (hashcat_ctx, mask_ctx->mask, strlen (mask_ctx->mask), mask_ctx->mp_sys, mask_ctx->mp_usr, mask_ctx->css_buf, &mask_ctx->css_cnt); if (rc_gen_css == -1) return -1; // special case for benchmark u32 pw_min = hashconfig->pw_min; u32 pw_max = hashconfig->pw_max; if (user_options->benchmark == true) { pw_min = mp_get_length (mask_ctx->mask); pw_max = pw_min; } hashconfig->pw_min = pw_min; hashconfig->pw_max = pw_max; // check if mask is not too large or too small for pw_min/pw_max u32 mask_min = hashconfig->pw_min; u32 mask_max = hashconfig->pw_max; if ((mask_ctx->css_cnt < mask_min) || (mask_ctx->css_cnt > mask_max)) { if (mask_ctx->css_cnt < mask_min) { event_log_warning (hashcat_ctx, "Skipping mask '%s' because it is smaller than the minimum password length.", mask_ctx->mask); event_log_warning (hashcat_ctx, NULL); } if (mask_ctx->css_cnt > mask_max) { event_log_warning (hashcat_ctx, "Skipping mask '%s' because it is larger than the maximum password length.", mask_ctx->mask); event_log_warning (hashcat_ctx, NULL); } // skip to next mask logfile_sub_msg ("STOP"); return -1; } if (hashconfig->opts_type & OPTS_TYPE_PT_UTF16LE) { const int rc = mp_css_utf16le_expand (hashcat_ctx); if (rc == -1) return -1; } else if (hashconfig->opts_type & OPTS_TYPE_PT_UTF16BE) { const int rc = mp_css_utf16be_expand (hashcat_ctx); if (rc == -1) return -1; } u32 css_cnt_orig = mask_ctx->css_cnt; if (hashconfig->opti_type & OPTI_TYPE_SINGLE_HASH) { if (hashconfig->opti_type & OPTI_TYPE_APPENDED_SALT) { const int rc = mp_css_append_salt (hashcat_ctx, &hashes->salts_buf[0]); if (rc == -1) return -1; } } u32 uniq_tbls[SP_PW_MAX][CHARSIZ] = { { 0 } }; mp_css_to_uniq_tbl (hashcat_ctx, mask_ctx->css_cnt, mask_ctx->css_buf, uniq_tbls); sp_tbl_to_css (mask_ctx->root_table_buf, mask_ctx->markov_table_buf, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, user_options->markov_threshold, uniq_tbls); const int rc_get_sum1 = sp_get_sum (0, mask_ctx->css_cnt, mask_ctx->root_css_buf, &status_ctx->words_cnt); if (rc_get_sum1 == -1) { event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of mask: %s", mask_ctx->mask); return -1; } // copy + args u32 css_cnt_lr[2]; mp_css_split_cnt (hashcat_ctx, css_cnt_orig, css_cnt_lr); const int rc_get_sum2 = sp_get_sum (0, css_cnt_lr[1], mask_ctx->root_css_buf, &mask_ctx->bfs_cnt); if (rc_get_sum2 == -1) { event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of mask: %s", mask_ctx->mask); return -1; } const int rc_update_mp_rl = opencl_session_update_mp_rl (hashcat_ctx, css_cnt_lr[0], css_cnt_lr[1]); if (rc_update_mp_rl == -1) return -1; } } return 0; }
int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; user_options_t *user_options = hashcat_ctx->user_options; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; /** * load hashes, part I: find input mode, count hashes */ const char *hashfile = hashes->hashfile; const u32 hashlist_mode = hashes->hashlist_mode; u32 hashlist_format = HLFMT_HASHCAT; u64 hashes_avail = 0; if ((user_options->benchmark == false) && (user_options->stdout_flag == false) && (user_options->keyspace == false)) { if (hashlist_mode == HL_MODE_ARG) { if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { struct stat st; if (stat (hashes->hashfile, &st) == -1) { event_log_error (hashcat_ctx, "%s: %s", hashes->hashfile, strerror (errno)); return -1; } // 392 = old hccap_t size if ((st.st_size % 392) == 0) { const int rc = check_old_hccap (hashes->hashfile); if (rc == 1) { event_log_error (hashcat_ctx, "%s: Old hccap format detected! You need to update: https://hashcat.net/q/hccapx", hashes->hashfile); return -1; } } hashes_avail = st.st_size / sizeof (hccapx_t); } else if (hashconfig->hash_mode == 14600) { struct stat st; if (stat (hashes->hashfile, &st) == -1) { event_log_error (hashcat_ctx, "%s: %s", hashes->hashfile, strerror (errno)); return -1; } hashes_avail = LUKS_NUMKEYS; } else { hashes_avail = 1; } } else if (hashlist_mode == HL_MODE_FILE) { FILE *fp = NULL; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %s", hashfile, strerror (errno)); return -1; } EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_PRE, hashfile, strlen (hashfile)); hashes_avail = count_lines (fp); EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_POST, hashfile, strlen (hashfile)); rewind (fp); if (hashes_avail == 0) { event_log_error (hashcat_ctx, "hashfile is empty or corrupt."); fclose (fp); return -1; } hashlist_format = hlfmt_detect (hashcat_ctx, fp, 100); // 100 = max numbers to "scan". could be hashes_avail, too if ((user_options->remove == true) && (hashlist_format != HLFMT_HASHCAT)) { event_log_error (hashcat_ctx, "Use of --remove is not supported in native hashfile-format mode."); fclose (fp); return -1; } fclose (fp); } } else { hashes_avail = 1; } if (hashconfig->hash_mode == 3000) hashes_avail *= 2; hashes->hashlist_format = hashlist_format; /** * load hashes, part II: allocate required memory, set pointers */ hash_t *hashes_buf = (hash_t *) hccalloc (hashes_avail, sizeof (hash_t)); void *digests_buf = hccalloc (hashes_avail, hashconfig->dgst_size); salt_t *salts_buf = NULL; void *esalts_buf = NULL; void *hook_salts_buf = NULL; if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT)) { u32 hash_pos; for (hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashinfo_t *hash_info = (hashinfo_t *) hcmalloc (sizeof (hashinfo_t)); hashes_buf[hash_pos].hash_info = hash_info; if (user_options->username == true) { hash_info->user = (user_t *) hcmalloc (sizeof (user_t)); } if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { if (user_options->benchmark == false) { hash_info->orighash = (char *) hcmalloc (256); } } if (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT) { hash_info->split = (split_t *) hcmalloc (sizeof (split_t)); } } } if (hashconfig->is_salted == true) { salts_buf = (salt_t *) hccalloc (hashes_avail, sizeof (salt_t)); if (hashconfig->esalt_size > 0) { esalts_buf = hccalloc (hashes_avail, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hook_salts_buf = (seven_zip_hook_salt_t *) hccalloc (hashes_avail, hashconfig->hook_salt_size); } } else { salts_buf = (salt_t *) hccalloc (1, sizeof (salt_t)); } for (u32 hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashes_buf[hash_pos].digest = ((char *) digests_buf) + (hash_pos * hashconfig->dgst_size); if (hashconfig->is_salted == true) { hashes_buf[hash_pos].salt = &salts_buf[hash_pos]; if (hashconfig->esalt_size > 0) { hashes_buf[hash_pos].esalt = ((char *) esalts_buf) + (hash_pos * hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hashes_buf[hash_pos].hook_salt = ((char *) hook_salts_buf) + (hash_pos * hashconfig->hook_salt_size); } } else { hashes_buf[hash_pos].salt = &salts_buf[0]; } } hashes->hashes_buf = hashes_buf; hashes->digests_buf = digests_buf; hashes->salts_buf = salts_buf; hashes->esalts_buf = esalts_buf; hashes->hook_salts_buf = hook_salts_buf; /** * load hashes, part III: parse hashes or generate them if benchmark */ u32 hashes_cnt = 0; if (user_options->benchmark == true) { hashconfig_benchmark_defaults (hashcat_ctx, hashes_buf[0].salt, hashes_buf[0].esalt, hashes_buf[0].hook_salt); hashes->hashfile = "-"; hashes_cnt = 1; } else if (user_options->example_hashes == true) { } else if (user_options->keyspace == true) { } else if (user_options->stdout_flag == true) { } else if (user_options->opencl_info == true) { } else { if (hashes_avail == 0) { // ??? } else if (hashlist_mode == HL_MODE_ARG) { char *input_buf = user_options_extra->hc_hash; size_t input_len = strlen (input_buf); char *hash_buf = NULL; size_t hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, input_buf, input_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "Failed to parse hashes using the '%s' format.", strhlfmt (hashlist_format)); } else { if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted == true) { memset (hashes_buf[0].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[0].esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[0].hook_salt, 0, hashconfig->hook_salt_size); } int parser_status = PARSER_OK; if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { hashes->hashlist_mode = HL_MODE_FILE; FILE *fp = fopen (hash_buf, "rb"); if (fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", hash_buf, strerror (errno)); return -1; } char *in = (char *) hcmalloc (sizeof (hccapx_t)); while (!feof (fp)) { const size_t nread = hc_fread (in, sizeof (hccapx_t), 1, fp); if (nread == 0) break; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s': File changed during runtime. Skipping new data.", hash_buf); break; } if (hashconfig->is_salted == true) { memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[hashes_cnt].esalt, 0, hashconfig->esalt_size); if ((user_options->hash_mode == 2500) || (user_options->hash_mode == 2501)) { wpa_t *wpa = (wpa_t *) hashes_buf[hashes_cnt].esalt; if (user_options->hccapx_message_pair_chgd == true) { wpa->message_pair_chgd = (int) user_options->hccapx_message_pair_chgd; wpa->message_pair = (u8) user_options->hccapx_message_pair; } wpa->nonce_error_corrections = user_options->nonce_error_corrections; } } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[hashes_cnt].hook_salt, 0, hashconfig->hook_salt_size); } parser_status = hashconfig->parse_func ((u8 *) in, sizeof (hccapx_t), &hashes_buf[hashes_cnt], hashconfig); if (parser_status != PARSER_OK) { event_log_warning (hashcat_ctx, "Hashfile '%s': %s", hash_buf, strparser (parser_status)); continue; } hashes_cnt++; } hcfree (in); fclose (fp); } else if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_LEFT; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_RIGHT; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_buf[hashes_cnt].hash_info->split->split_group = 0; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_NONE; hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } else if (hashconfig->hash_mode == 14600) { hashes->hashlist_mode = HL_MODE_FILE; for (int keyslot_idx = 0; keyslot_idx < LUKS_NUMKEYS; keyslot_idx++) { parser_status = luks_parse_hash ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig, keyslot_idx); if (parser_status != PARSER_OK) { if (parser_status != PARSER_LUKS_KEY_DISABLED) { event_log_warning (hashcat_ctx, "Hashfile '%s': %s", hash_buf, strparser (parser_status)); } continue; } hashes_cnt++; } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } } else if (hashlist_mode == HL_MODE_FILE) { FILE *fp; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %s", hashfile, strerror (errno)); return -1; } u32 line_num = 0; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); time_t prev = 0; time_t now = 0; while (!feof (fp)) { line_num++; const size_t line_len = fgetl (fp, line_buf); if (line_len == 0) continue; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u: File changed during runtime. Skipping new data.", hashes->hashfile, line_num); break; } char *hash_buf = NULL; size_t hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, line_buf, line_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "Failed to parse hashes using the '%s' format.", strhlfmt (hashlist_format)); continue; } if (user_options->username == true) { char *user_buf = NULL; size_t user_len = 0; hlfmt_user (hashcat_ctx, hashlist_format, line_buf, line_len, &user_buf, &user_len); // special case: // both hash_t need to have the username info if the pwdump format is used (i.e. we have 2 hashes for 3000, both with same user) u32 hashes_per_user = 1; if (hashconfig->hash_mode == 3000) // the following conditions should be true if (hashlist_format == HLFMT_PWDUMP) { if (hash_len == 32) { hashes_per_user = 2; } } for (u32 i = 0; i < hashes_per_user; i++) { user_t **user = &hashes_buf[hashes_cnt + i].hash_info->user; *user = (user_t *) hcmalloc (sizeof (user_t)); user_t *user_ptr = *user; if (user_buf != NULL) { user_ptr->user_name = hcstrdup (user_buf); } else { user_ptr->user_name = hcstrdup (""); } user_ptr->user_len = (u32) user_len; } } if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted == true) { memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hashes_buf[hashes_cnt].esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hashes_buf[hashes_cnt].hook_salt, 0, hashconfig->hook_salt_size); } if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_LEFT; hashes_cnt++; parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_RIGHT; hashes_cnt++; } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_buf[hashes_cnt].hash_info->split->split_group = line_num; hashes_buf[hashes_cnt].hash_info->split->split_origin = SPLIT_ORIGIN_NONE; hashes_cnt++; } } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, (u32) hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { char *tmp_line_buf; hc_asprintf (&tmp_line_buf, "%s", line_buf); compress_terminal_line_length (tmp_line_buf, 38, 32); event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, tmp_line_buf, strparser (parser_status)); hcfree (tmp_line_buf); continue; } hashes_cnt++; } time (&now); if ((now - prev) == 0) continue; time (&prev); hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); } hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); hcfree (line_buf); fclose (fp); } } hashes->hashes_cnt = hashes_cnt; if (hashes_cnt) { EVENT (EVENT_HASHLIST_SORT_HASH_PRE); if (hashconfig->is_salted == true) { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); } EVENT (EVENT_HASHLIST_SORT_HASH_POST); } if (hashconfig->hash_mode == 3000) { // update split split_neighbor after sorting // see https://github.com/hashcat/hashcat/issues/1034 for good examples for testing for (u32 i = 0; i < hashes_cnt; i++) { split_t *split1 = hashes_buf[i].hash_info->split; if (split1->split_origin != SPLIT_ORIGIN_LEFT) continue; for (u32 j = 0; j < hashes_cnt; j++) { split_t *split2 = hashes_buf[j].hash_info->split; if (split2->split_origin != SPLIT_ORIGIN_RIGHT) continue; if (split1->split_group != split2->split_group) continue; split1->split_neighbor = j; split2->split_neighbor = i; break; } } } return 0; }
int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; const hashes_t *hashes = hashcat_ctx->hashes; const potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; if (potfile_ctx->enabled == false) return 0; // if no potfile exists yet we don't need to do anything here if (hc_path_exist (potfile_ctx->filename) == false) return 0; hash_t *hashes_buf = hashes->hashes_buf; u32 hashes_cnt = hashes->hashes_cnt; // no solution for these special hash types (for instane because they use hashfile in output etc) if (hashconfig->hash_mode == 5200) return 0; if ((hashconfig->hash_mode >= 6200) && (hashconfig->hash_mode <= 6299)) return 0; if (hashconfig->hash_mode == 9000) return 0; if ((hashconfig->hash_mode >= 13700) && (hashconfig->hash_mode <= 13799)) return 0; if (hashconfig->hash_mode == 14600) return 0; hash_t hash_buf; hash_buf.digest = hcmalloc (hashconfig->dgst_size); hash_buf.salt = NULL; hash_buf.esalt = NULL; hash_buf.hook_salt = NULL; hash_buf.hash_info = NULL; hash_buf.cracked = 0; if (hashconfig->is_salted == true) { hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { hash_buf.esalt = hcmalloc (hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hash_buf.hook_salt = hcmalloc (hashconfig->hook_salt_size); } // we only need this variable in a very specific situation: // whenever we use --username and --show together we want to keep all hashes sorted within a nice structure pot_tree_entry_t *all_hashes_tree = NULL; pot_tree_entry_t *tree_entry_cache = NULL; pot_hash_node_t *tree_nodes_cache = NULL; if (potfile_ctx->keep_all_hashes == true) { // we need *at most* one entry for every hash // (if there are no hashes with the same keys (hash + salt), a counter example would be: same hash but different user name) tree_entry_cache = (pot_tree_entry_t *) hccalloc (hashes_cnt, sizeof (pot_tree_entry_t)); // we need *always exactly* one linked list for every hash tree_nodes_cache = (pot_hash_node_t *) hccalloc (hashes_cnt, sizeof (pot_hash_node_t)); for (u32 hash_pos = 0; hash_pos < hashes_cnt; hash_pos++) { // initialize the linked list node: // we always need to create a new one and add it, because we want to keep and later update all hashes: pot_hash_node_t *new_node = &tree_nodes_cache[hash_pos]; new_node->hash_buf = &hashes_buf[hash_pos]; new_node->next = NULL; // initialize the entry: pot_tree_entry_t *new_entry = &tree_entry_cache[hash_pos]; // note: the "key" (hash + salt) is indirectly accessible via the first nodes "hash_buf" new_entry->nodes = new_node; // the hashconfig is needed here because we need to be able to check within the sort function if we also need // to sort by salt and we also need to have the correct order of dgst_pos0...dgst_pos3: new_entry->hashconfig = (hashconfig_t *) hashconfig; // "const hashconfig_t" gives a warning // the following function searches if the "key" is already present and if not inserts the new entry: void **found = tsearch (new_entry, (void **) &all_hashes_tree, sort_pot_tree_by_hash); pot_tree_entry_t *found_entry = (pot_tree_entry_t *) *found; // we now need to check these cases; tsearch () could return: // 1. NULL : if we have a memory allocation problem (not enough memory for the tree structure) // 2. found_entry == new_entry: if we successfully insert a new key (which was not present yet) // 3. found_entry != new_entry: if the key was already present // case 1: memory allocation error if (found_entry == NULL) { fprintf (stderr, "Error while allocating memory for the potfile search: %s\n", MSG_ENOMEM); return -1; } // case 2: this means it was a new insert (and the insert was successful) if (found_entry == new_entry) { // no updates to the linked list required (since it is the first one!) } // case 3: if we have found an already existing entry else { new_node->next = found_entry->nodes; } // we always insert the new node at the very beginning // (or in other words: the head of the linked list always points to *this* new inserted node) found_entry->nodes = new_node; } } // special case for a split hash if (hashconfig->hash_mode == 3000) { int parser_status = hashconfig->parse_func ((u8 *) LM_ZERO_HASH, 16, &hash_buf, hashconfig); if (parser_status == PARSER_OK) { if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, NULL, 0, all_hashes_tree); } else { hash_t *found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); potfile_update_hash (hashcat_ctx, found, NULL, 0); } } } const int rc = potfile_read_open (hashcat_ctx); if (rc == -1) return -1; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (potfile_ctx->fp)) { int line_len = fgetl (potfile_ctx->fp, line_buf); if (line_len == 0) continue; char *last_separator = strrchr (line_buf, hashconfig->separator); if (last_separator == NULL) continue; // ?? char *line_pw_buf = last_separator + 1; int line_pw_len = line_buf + line_len - line_pw_buf; char *line_hash_buf = line_buf; int line_hash_len = last_separator - line_buf; line_hash_buf[line_hash_len] = 0; if (line_hash_len == 0) continue; if (hashconfig->is_salted == true) { memset (hash_buf.salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hash_buf.esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hash_buf.hook_salt, 0, hashconfig->hook_salt_size); } hash_t *found = NULL; if (hashconfig->hash_mode == 6800) { if (line_hash_len < 256) // 64 = 64 * u32 in salt_buf[] { // manipulate salt_buf memcpy (hash_buf.salt->salt_buf, line_hash_buf, line_hash_len); hash_buf.salt->salt_len = line_hash_len; found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt); } } else if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { // here we have in line_hash_buf: hash:macap:macsta:essid:password char *sep_pos = strrchr (line_hash_buf, ':'); if (sep_pos == NULL) continue; sep_pos[0] = 0; char *hash_pos = line_hash_buf; const size_t hash_len = strlen (hash_pos); if (hash_len != 32 + 1 + 12 + 1 + 12) continue; char *essid_pos = sep_pos + 1; int essid_len = (int) strlen (essid_pos); if (is_hexify ((const u8 *) essid_pos, (const int) essid_len) == true) { essid_len = exec_unhexify ((const u8 *) essid_pos, essid_len, (u8 *) essid_pos, essid_len); } if (essid_len > 32) continue; if (hashconfig->is_salted == true) { // this should be always true, but we need it to make scan-build happy memcpy (hash_buf.salt->salt_buf, essid_pos, essid_len); hash_buf.salt->salt_len = essid_len; hash_buf.salt->salt_iter = ROUNDS_WPA - 1; u32 hash[4]; hash[0] = hex_to_u32 ((const u8 *) &hash_pos[ 0]); hash[1] = hex_to_u32 ((const u8 *) &hash_pos[ 8]); hash[2] = hex_to_u32 ((const u8 *) &hash_pos[16]); hash[3] = hex_to_u32 ((const u8 *) &hash_pos[24]); hash[0] = byte_swap_32 (hash[0]); hash[1] = byte_swap_32 (hash[1]); hash[2] = byte_swap_32 (hash[2]); hash[3] = byte_swap_32 (hash[3]); u32 *digest = (u32 *) hash_buf.digest; digest[0] = hash[0]; digest[1] = hash[1]; digest[2] = hash[2]; digest[3] = hash[3]; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { int parser_status = hashconfig->parse_func ((u8 *) line_hash_buf, line_hash_len, &hash_buf, hashconfig); if (parser_status != PARSER_OK) continue; if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, line_pw_buf, line_pw_len, all_hashes_tree); continue; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } potfile_update_hash (hashcat_ctx, found, line_pw_buf, line_pw_len); } hcfree (line_buf); potfile_read_close (hashcat_ctx); if (potfile_ctx->keep_all_hashes == true) { pot_tree_destroy (all_hashes_tree); // this could be slow (should we just skip it?) hcfree (tree_nodes_cache); hcfree (tree_entry_cache); } if (hashconfig->esalt_size > 0) { hcfree (hash_buf.esalt); } if (hashconfig->hook_salt_size > 0) { hcfree (hash_buf.hook_salt); } if (hashconfig->is_salted == true) { hcfree (hash_buf.salt); } hcfree (hash_buf.digest); return 0; }
int hashes_init_selftest (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; user_options_t *user_options = hashcat_ctx->user_options; if (hashconfig->st_hash == NULL) return 0; void *st_digests_buf = NULL; salt_t *st_salts_buf = NULL; void *st_esalts_buf = NULL; void *st_hook_salts_buf = NULL; st_digests_buf = hccalloc (1, hashconfig->dgst_size); st_salts_buf = (salt_t *) hccalloc (1, sizeof (salt_t)); if (hashconfig->esalt_size > 0) { st_esalts_buf = hccalloc (1, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { st_hook_salts_buf = hccalloc (1, hashconfig->hook_salt_size); } hash_t hash; hash.digest = st_digests_buf; hash.salt = st_salts_buf; hash.esalt = st_esalts_buf; hash.hook_salt = st_hook_salts_buf; hash.cracked = 0; hash.hash_info = NULL; hash.pw_buf = NULL; hash.pw_len = 0; int parser_status; if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { char *tmpdata = (char *) hcmalloc (sizeof (hccapx_t)); const size_t st_hash_len = strlen (hashconfig->st_hash); for (size_t i = 0, j = 0; j < st_hash_len; i += 1, j += 2) { const u8 c = hex_to_u8 ((const u8 *) hashconfig->st_hash + j); tmpdata[i] = c; } parser_status = hashconfig->parse_func ((u8 *) tmpdata, sizeof (hccapx_t), &hash, hashconfig); hcfree (tmpdata); wpa_t *wpa = (wpa_t *) st_esalts_buf; wpa->nonce_error_corrections = 3; } else if (hashconfig->opts_type & OPTS_TYPE_BINARY_HASHFILE) { char *tmpfile_bin; hc_asprintf (&tmpfile_bin, "%s/selftest.hash", folder_config->session_dir); FILE *fp = fopen (tmpfile_bin, "wb"); const size_t st_hash_len = strlen (hashconfig->st_hash); for (size_t i = 0; i < st_hash_len; i += 2) { const u8 c = hex_to_u8 ((const u8 *) hashconfig->st_hash + i); fputc (c, fp); } fclose (fp); parser_status = hashconfig->parse_func ((u8 *) tmpfile_bin, (u32) strlen (tmpfile_bin), &hash, hashconfig); unlink (tmpfile_bin); hcfree (tmpfile_bin); } else { hashconfig_t *hashconfig_st = (hashconfig_t *) hcmalloc (sizeof (hashconfig_t)); memcpy (hashconfig_st, hashconfig, sizeof (hashconfig_t)); hashconfig_st->separator = SEPARATOR; if (user_options->hex_salt) { if (hashconfig->salt_type == SALT_TYPE_GENERIC) { // this is save as there's no hash mode that has both SALT_TYPE_GENERIC and OPTS_TYPE_ST_HEX by default hashconfig_st->opts_type &= ~OPTS_TYPE_ST_HEX; } } // Make sure that we do not modify constant data. Make a copy of the constant self-test hash // Note: sometimes parse_func () modifies the data internally. We always need to use a copy of the original data char *tmpdata = hcstrdup (hashconfig->st_hash); parser_status = hashconfig->parse_func ((u8 *) tmpdata, (u32) strlen (hashconfig->st_hash), &hash, hashconfig_st); hcfree (tmpdata); hcfree (hashconfig_st); } if (parser_status == PARSER_OK) { // nothing to do } else { event_log_error (hashcat_ctx, "Self-test hash parsing error: %s", strparser (parser_status)); return -1; } hashes->st_digests_buf = st_digests_buf; hashes->st_salts_buf = st_salts_buf; hashes->st_esalts_buf = st_esalts_buf; hashes->st_hook_salts_buf = st_hook_salts_buf; return 0; }
int check_cracked (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 salt_pos) { cpt_ctx_t *cpt_ctx = hashcat_ctx->cpt_ctx; hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; user_options_t *user_options = hashcat_ctx->user_options; salt_t *salt_buf = &hashes->salts_buf[salt_pos]; u32 num_cracked; cl_int CL_err; CL_err = hc_clEnqueueReadBuffer (hashcat_ctx, device_param->command_queue, device_param->d_result, CL_TRUE, 0, sizeof (u32), &num_cracked, 0, NULL, NULL); if (CL_err != CL_SUCCESS) { event_log_error (hashcat_ctx, "clEnqueueReadBuffer(): %s", val2cstr_cl (CL_err)); return -1; } if (user_options->speed_only == true) { // we want the hc_clEnqueueReadBuffer to run in benchmark mode because it has an influence in performance // however if the benchmark cracks the artificial hash used for benchmarks we don't want to see that! return 0; } if (num_cracked) { plain_t *cracked = (plain_t *) hccalloc (num_cracked, sizeof (plain_t)); CL_err = hc_clEnqueueReadBuffer (hashcat_ctx, device_param->command_queue, device_param->d_plain_bufs, CL_TRUE, 0, num_cracked * sizeof (plain_t), cracked, 0, NULL, NULL); if (CL_err != CL_SUCCESS) { event_log_error (hashcat_ctx, "clEnqueueReadBuffer(): %s", val2cstr_cl (CL_err)); return -1; } u32 cpt_cracked = 0; hc_thread_mutex_lock (status_ctx->mux_display); for (u32 i = 0; i < num_cracked; i++) { const u32 hash_pos = cracked[i].hash_pos; if (hashes->digests_shown[hash_pos] == 1) continue; if ((hashconfig->opts_type & OPTS_TYPE_PT_NEVERCRACK) == 0) { hashes->digests_shown[hash_pos] = 1; hashes->digests_done++; cpt_cracked++; salt_buf->digests_done++; if (salt_buf->digests_done == salt_buf->digests_cnt) { hashes->salts_shown[salt_pos] = 1; hashes->salts_done++; } } if (hashes->salts_done == hashes->salts_cnt) mycracked (hashcat_ctx); check_hash (hashcat_ctx, device_param, &cracked[i]); } hc_thread_mutex_unlock (status_ctx->mux_display); hcfree (cracked); if (cpt_cracked > 0) { hc_thread_mutex_lock (status_ctx->mux_display); cpt_ctx->cpt_buf[cpt_ctx->cpt_pos].timestamp = time (NULL); cpt_ctx->cpt_buf[cpt_ctx->cpt_pos].cracked = cpt_cracked; cpt_ctx->cpt_pos++; cpt_ctx->cpt_total += cpt_cracked; if (cpt_ctx->cpt_pos == CPT_CACHE) cpt_ctx->cpt_pos = 0; hc_thread_mutex_unlock (status_ctx->mux_display); } if (hashconfig->opts_type & OPTS_TYPE_PT_NEVERCRACK) { // we need to reset cracked state on the device // otherwise host thinks again and again the hash was cracked // and returns invalid password each time memset (hashes->digests_shown_tmp, 0, salt_buf->digests_cnt * sizeof (u32)); CL_err = hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->command_queue, device_param->d_digests_shown, CL_TRUE, salt_buf->digests_offset * sizeof (u32), salt_buf->digests_cnt * sizeof (u32), &hashes->digests_shown_tmp[salt_buf->digests_offset], 0, NULL, NULL); if (CL_err != CL_SUCCESS) { event_log_error (hashcat_ctx, "clEnqueueWriteBuffer(): %s", val2cstr_cl (CL_err)); return -1; } } num_cracked = 0; CL_err = hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->command_queue, device_param->d_result, CL_TRUE, 0, sizeof (u32), &num_cracked, 0, NULL, NULL); if (CL_err != CL_SUCCESS) { event_log_error (hashcat_ctx, "clEnqueueWriteBuffer(): %s", val2cstr_cl (CL_err)); return -1; } } return 0; }
static int outer_loop (hashcat_ctx_t *hashcat_ctx) { hashes_t *hashes = hashcat_ctx->hashes; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; opencl_ctx_t *opencl_ctx = hashcat_ctx->opencl_ctx; outcheck_ctx_t *outcheck_ctx = hashcat_ctx->outcheck_ctx; restore_ctx_t *restore_ctx = hashcat_ctx->restore_ctx; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx; user_options_t *user_options = hashcat_ctx->user_options; status_ctx->devices_status = STATUS_INIT; //status_ctx->run_main_level1 = true; status_ctx->run_main_level2 = true; status_ctx->run_main_level3 = true; status_ctx->run_thread_level1 = true; status_ctx->run_thread_level2 = true; /** * setup variables and buffers depending on hash_mode */ const int rc_hashconfig = hashconfig_init (hashcat_ctx); if (rc_hashconfig == -1) { event_log_error (hashcat_ctx, "Unknown hash-type '%u' selected.", user_options->hash_mode); return -1; } /** * load hashes, stage 1 */ const int rc_hashes_init_stage1 = hashes_init_stage1 (hashcat_ctx); if (rc_hashes_init_stage1 == -1) return -1; if ((user_options->keyspace == false) && (user_options->stdout_flag == false)) { if (hashes->hashes_cnt == 0) { event_log_error (hashcat_ctx, "No hashes loaded."); return -1; } } /** * load hashes, stage 2, remove duplicates, build base structure */ hashes->hashes_cnt_orig = hashes->hashes_cnt; const int rc_hashes_init_stage2 = hashes_init_stage2 (hashcat_ctx); if (rc_hashes_init_stage2 == -1) return -1; /** * potfile removes */ if (user_options->potfile_disable == false) { EVENT (EVENT_POTFILE_REMOVE_PARSE_PRE); if (user_options->loopback == true) { loopback_write_open (hashcat_ctx); } potfile_remove_parse (hashcat_ctx); if (user_options->loopback == true) { loopback_write_close (hashcat_ctx); } EVENT (EVENT_POTFILE_REMOVE_PARSE_POST); } /** * load hashes, stage 3, update cracked results from potfile */ const int rc_hashes_init_stage3 = hashes_init_stage3 (hashcat_ctx); if (rc_hashes_init_stage3 == -1) return -1; /** * potfile show/left handling */ if (user_options->show == true) { outfile_write_open (hashcat_ctx); const int rc = potfile_handle_show (hashcat_ctx); if (rc == -1) return -1; outfile_write_close (hashcat_ctx); return 0; } else if (user_options->left == true) { outfile_write_open (hashcat_ctx); const int rc = potfile_handle_left (hashcat_ctx); if (rc == -1) return -1; outfile_write_close (hashcat_ctx); return 0; } /** * maybe all hashes were cracked, we can exit here */ if (status_ctx->devices_status == STATUS_CRACKED) { if ((user_options->remove == true) && (hashes->hashlist_mode == HL_MODE_FILE)) { if (hashes->digests_saved != hashes->digests_done) { const int rc = save_hash (hashcat_ctx); if (rc == -1) return -1; } } EVENT (EVENT_POTFILE_ALL_CRACKED); return 0; } /** * load hashes, stage 4, automatic Optimizers */ const int rc_hashes_init_stage4 = hashes_init_stage4 (hashcat_ctx); if (rc_hashes_init_stage4 == -1) return -1; /** * load hashes, selftest */ const int rc_hashes_init_selftest = hashes_init_selftest (hashcat_ctx); if (rc_hashes_init_selftest == -1) return -1; /** * Done loading hashes, log results */ hashes_logger (hashcat_ctx); /** * bitmaps */ EVENT (EVENT_BITMAP_INIT_PRE); const int rc_bitmap_init = bitmap_ctx_init (hashcat_ctx); if (rc_bitmap_init == -1) return -1; EVENT (EVENT_BITMAP_INIT_POST); /** * cracks-per-time allocate buffer */ cpt_ctx_init (hashcat_ctx); /** * Wordlist allocate buffer */ const int rc_wl_data_init = wl_data_init (hashcat_ctx); if (rc_wl_data_init == -1) return -1; /** * straight mode init */ const int rc_straight_init = straight_ctx_init (hashcat_ctx); if (rc_straight_init == -1) return -1; /** * straight mode init */ const int rc_combinator_init = combinator_ctx_init (hashcat_ctx); if (rc_combinator_init == -1) return -1; /** * charsets : keep them together for more easy maintainnce */ const int rc_mask_init = mask_ctx_init (hashcat_ctx); if (rc_mask_init == -1) return -1; /** * prevent the user from using --skip/--limit together with maskfile and/or multiple word lists */ if (user_options->skip != 0 || user_options->limit != 0) { if ((mask_ctx->masks_cnt > 1) || (straight_ctx->dicts_cnt > 1)) { event_log_error (hashcat_ctx, "Use of --skip/--limit is not supported with --increment or mask files."); return -1; } } /** * prevent the user from using --keyspace together with maskfile and/or multiple word lists */ if (user_options->keyspace == true) { if ((mask_ctx->masks_cnt > 1) || (straight_ctx->dicts_cnt > 1)) { event_log_error (hashcat_ctx, "Use of --keyspace is not supported with --increment or mask files."); return -1; } } /** * status progress init; needs hashes that's why we have to do it here and separate from status_ctx_init */ const int rc_status_init = status_progress_init (hashcat_ctx); if (rc_status_init == -1) return -1; /** * main screen */ EVENT (EVENT_OUTERLOOP_MAINSCREEN); /** * Tell user about cracked hashes by potfile */ EVENT (EVENT_POTFILE_NUM_CRACKED); /** * inform the user */ EVENT (EVENT_OPENCL_SESSION_PRE); const int rc_session_begin = opencl_session_begin (hashcat_ctx); if (rc_session_begin == -1) return -1; EVENT (EVENT_OPENCL_SESSION_POST); /** * create self-test threads */ EVENT (EVENT_SELFTEST_STARTING); thread_param_t *threads_param = (thread_param_t *) hccalloc (opencl_ctx->devices_cnt, sizeof (thread_param_t)); hc_thread_t *selftest_threads = (hc_thread_t *) hccalloc (opencl_ctx->devices_cnt, sizeof (hc_thread_t)); status_ctx->devices_status = STATUS_SELFTEST; for (u32 device_id = 0; device_id < opencl_ctx->devices_cnt; device_id++) { thread_param_t *thread_param = threads_param + device_id; thread_param->hashcat_ctx = hashcat_ctx; thread_param->tid = device_id; hc_thread_create (selftest_threads[device_id], thread_selftest, thread_param); } hc_thread_wait (opencl_ctx->devices_cnt, selftest_threads); hcfree (threads_param); hcfree (selftest_threads); status_ctx->devices_status = STATUS_INIT; EVENT (EVENT_SELFTEST_FINISHED); /** * (old) weak hash check is the first to write to potfile, so open it for writing from here * the weak hash check was removed maybe we can move this more to the bottom now */ const int rc_potfile_write = potfile_write_open (hashcat_ctx); if (rc_potfile_write == -1) return -1; /** * status and monitor threads */ int inner_threads_cnt = 0; hc_thread_t *inner_threads = (hc_thread_t *) hccalloc (10, sizeof (hc_thread_t)); status_ctx->shutdown_inner = false; /** * Outfile remove */ if (user_options->keyspace == false && user_options->stdout_flag == false && user_options->speed_only == false) { hc_thread_create (inner_threads[inner_threads_cnt], thread_monitor, hashcat_ctx); inner_threads_cnt++; if (outcheck_ctx->enabled == true) { hc_thread_create (inner_threads[inner_threads_cnt], thread_outfile_remove, hashcat_ctx); inner_threads_cnt++; } } // main call if (restore_ctx->rd) { restore_data_t *rd = restore_ctx->rd; if (rd->masks_pos > 0) { mask_ctx->masks_pos = rd->masks_pos; rd->masks_pos = 0; } } EVENT (EVENT_INNERLOOP1_STARTING); if (mask_ctx->masks_cnt) { for (u32 masks_pos = mask_ctx->masks_pos; masks_pos < mask_ctx->masks_cnt; masks_pos++) { mask_ctx->masks_pos = masks_pos; const int rc_inner1_loop = inner1_loop (hashcat_ctx); if (rc_inner1_loop == -1) myabort (hashcat_ctx); if (status_ctx->run_main_level2 == false) break; } if (mask_ctx->masks_pos + 1 == mask_ctx->masks_cnt) mask_ctx->masks_pos = 0; } else { const int rc_inner1_loop = inner1_loop (hashcat_ctx); if (rc_inner1_loop == -1) myabort (hashcat_ctx); } // wait for inner threads status_ctx->shutdown_inner = true; for (int thread_idx = 0; thread_idx < inner_threads_cnt; thread_idx++) { hc_thread_wait (1, &inner_threads[thread_idx]); } hcfree (inner_threads); EVENT (EVENT_INNERLOOP1_FINISHED); // finalize potfile potfile_write_close (hashcat_ctx); // finalize opencl session opencl_session_destroy (hashcat_ctx); // clean up bitmap_ctx_destroy (hashcat_ctx); combinator_ctx_destroy (hashcat_ctx); cpt_ctx_destroy (hashcat_ctx); hashconfig_destroy (hashcat_ctx); hashes_destroy (hashcat_ctx); mask_ctx_destroy (hashcat_ctx); status_progress_destroy (hashcat_ctx); straight_ctx_destroy (hashcat_ctx); wl_data_destroy (hashcat_ctx); return 0; }
int hashes_init_stage2 (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; user_options_t *user_options = hashcat_ctx->user_options; potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; hash_t *hashes_buf = hashes->hashes_buf; u32 hashes_cnt = hashes->hashes_cnt; /** * Remove duplicates */ EVENT (EVENT_HASHLIST_UNIQUE_HASH_PRE); u32 hashes_cnt_new = 1; for (u32 hashes_pos = 1; hashes_pos < hashes_cnt; hashes_pos++) { if (potfile_ctx->keep_all_hashes == true) { // do not sort, because we need to keep all hashes in this particular case } else if (hashconfig->is_salted == true) { if (sort_by_salt (hashes_buf[hashes_pos].salt, hashes_buf[hashes_pos - 1].salt) == 0) { if (sort_by_digest_p0p1 (hashes_buf[hashes_pos].digest, hashes_buf[hashes_pos - 1].digest, (void *) hashconfig) == 0) continue; } } else { if (sort_by_digest_p0p1 (hashes_buf[hashes_pos].digest, hashes_buf[hashes_pos - 1].digest, (void *) hashconfig) == 0) continue; } hash_t tmp; memcpy (&tmp, &hashes_buf[hashes_pos], sizeof (hash_t)); memcpy (&hashes_buf[hashes_cnt_new], &tmp, sizeof (hash_t)); hashes_cnt_new++; } for (u32 i = hashes_cnt_new; i < hashes->hashes_cnt; i++) { memset (&hashes_buf[i], 0, sizeof (hash_t)); } hashes_cnt = hashes_cnt_new; hashes->hashes_cnt = hashes_cnt; EVENT (EVENT_HASHLIST_UNIQUE_HASH_POST); /** * Now generate all the buffers required for later */ void *digests_buf_new = hccalloc (hashes_cnt, hashconfig->dgst_size); salt_t *salts_buf_new = NULL; void *esalts_buf_new = NULL; void *hook_salts_buf_new = NULL; if (hashconfig->is_salted == true) { salts_buf_new = (salt_t *) hccalloc (hashes_cnt, sizeof (salt_t)); } else { salts_buf_new = (salt_t *) hccalloc (1, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { esalts_buf_new = hccalloc (hashes_cnt, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hook_salts_buf_new = hccalloc (hashes_cnt, hashconfig->hook_salt_size); } EVENT (EVENT_HASHLIST_SORT_SALT_PRE); u32 digests_cnt = hashes_cnt; u32 digests_done = 0; u32 *digests_shown = (u32 *) hccalloc (digests_cnt, sizeof (u32)); u32 *digests_shown_tmp = (u32 *) hccalloc (digests_cnt, sizeof (u32)); u32 salts_cnt = 0; u32 salts_done = 0; hashinfo_t **hash_info = NULL; if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT)) { hash_info = (hashinfo_t **) hccalloc (hashes_cnt, sizeof (hashinfo_t *)); } u32 *salts_shown = (u32 *) hccalloc (digests_cnt, sizeof (u32)); salt_t *salt_buf; { // copied from inner loop salt_buf = &salts_buf_new[salts_cnt]; memcpy (salt_buf, hashes_buf[0].salt, sizeof (salt_t)); hashes_buf[0].salt = salt_buf; if (hashconfig->hook_salt_size > 0) { char *hook_salts_buf_new_ptr = ((char *) hook_salts_buf_new) + (salts_cnt * hashconfig->hook_salt_size); memcpy (hook_salts_buf_new_ptr, hashes_buf[0].hook_salt, hashconfig->hook_salt_size); hashes_buf[0].hook_salt = hook_salts_buf_new_ptr; } salt_buf->digests_cnt = 0; salt_buf->digests_done = 0; salt_buf->digests_offset = 0; salts_cnt++; } salt_buf->digests_cnt++; char *digests_buf_new_ptr = ((char *) digests_buf_new) + (0 * hashconfig->dgst_size); memcpy (digests_buf_new_ptr, hashes_buf[0].digest, hashconfig->dgst_size); hashes_buf[0].digest = digests_buf_new_ptr; if (hashconfig->esalt_size > 0) { char *esalts_buf_new_ptr = ((char *) esalts_buf_new) + (0 * hashconfig->esalt_size); memcpy (esalts_buf_new_ptr, hashes_buf[0].esalt, hashconfig->esalt_size); hashes_buf[0].esalt = esalts_buf_new_ptr; } if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT)) { hash_info[0] = hashes_buf[0].hash_info; } // copy from inner loop for (u32 hashes_pos = 1; hashes_pos < hashes_cnt; hashes_pos++) { if (hashconfig->is_salted == true) { if (sort_by_salt (hashes_buf[hashes_pos].salt, hashes_buf[hashes_pos - 1].salt) != 0) { salt_buf = &salts_buf_new[salts_cnt]; memcpy (salt_buf, hashes_buf[hashes_pos].salt, sizeof (salt_t)); hashes_buf[hashes_pos].salt = salt_buf; if (hashconfig->hook_salt_size > 0) { char *hook_salts_buf_new_ptr = ((char *) hook_salts_buf_new) + (salts_cnt * hashconfig->hook_salt_size); memcpy (hook_salts_buf_new_ptr, hashes_buf[hashes_pos].hook_salt, hashconfig->hook_salt_size); hashes_buf[hashes_pos].hook_salt = hook_salts_buf_new_ptr; } salt_buf->digests_cnt = 0; salt_buf->digests_done = 0; salt_buf->digests_offset = hashes_pos; salts_cnt++; } hashes_buf[hashes_pos].salt = salt_buf; if (hashconfig->hook_salt_size > 0) { char *hook_salts_buf_new_ptr = ((char *) hook_salts_buf_new) + (salts_cnt * hashconfig->hook_salt_size); hashes_buf[hashes_pos].hook_salt = hook_salts_buf_new_ptr; } } salt_buf->digests_cnt++; digests_buf_new_ptr = ((char *) digests_buf_new) + (hashes_pos * hashconfig->dgst_size); memcpy (digests_buf_new_ptr, hashes_buf[hashes_pos].digest, hashconfig->dgst_size); hashes_buf[hashes_pos].digest = digests_buf_new_ptr; if (hashconfig->esalt_size > 0) { char *esalts_buf_new_ptr = ((char *) esalts_buf_new) + (hashes_pos * hashconfig->esalt_size); memcpy (esalts_buf_new_ptr, hashes_buf[hashes_pos].esalt, hashconfig->esalt_size); hashes_buf[hashes_pos].esalt = esalts_buf_new_ptr; } if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HASH_SPLIT)) { hash_info[hashes_pos] = hashes_buf[hashes_pos].hash_info; } } EVENT (EVENT_HASHLIST_SORT_SALT_POST); hcfree (hashes->digests_buf); hcfree (hashes->salts_buf); hcfree (hashes->esalts_buf); hcfree (hashes->hook_salts_buf); hashes->digests_cnt = digests_cnt; hashes->digests_done = digests_done; hashes->digests_buf = digests_buf_new; hashes->digests_shown = digests_shown; hashes->digests_shown_tmp = digests_shown_tmp; hashes->salts_cnt = salts_cnt; hashes->salts_done = salts_done; hashes->salts_buf = salts_buf_new; hashes->salts_shown = salts_shown; hashes->esalts_buf = esalts_buf_new; hashes->hook_salts_buf = hook_salts_buf_new; hashes->hash_info = hash_info; return 0; }
int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; user_options_t *user_options = hashcat_ctx->user_options; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; char *hash_or_file = user_options_extra->hc_hash; /** * load hashes, part I: find input mode, count hashes */ u32 hashlist_mode = 0; u32 hashlist_format = HLFMT_HASHCAT; u32 hashes_avail = 0; if ((user_options->benchmark == false) && (user_options->stdout_flag == false)) { hc_stat_t f; hashlist_mode = (hc_stat (hash_or_file, &f) == 0) ? HL_MODE_FILE : HL_MODE_ARG; if (hashconfig->opts_type & OPTS_TYPE_BINARY_HASHFILE) { hashlist_mode = HL_MODE_ARG; char *hashfile = hash_or_file; hashes->hashfile = hashfile; } if (hashlist_mode == HL_MODE_ARG) { if (hashconfig->hash_mode == 2500) { hc_stat_t st; if (hc_stat (hashes->hashfile, &st) == -1) { event_log_error (hashcat_ctx, "%s: %m", hashes->hashfile); return -1; } hashes_avail = st.st_size / sizeof (hccap_t); } else { hashes_avail = 1; } } else if (hashlist_mode == HL_MODE_FILE) { char *hashfile = hash_or_file; hashes->hashfile = hashfile; FILE *fp = NULL; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %m", hashfile); return -1; } EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_PRE, hashfile, strlen (hashfile)); hashes_avail = count_lines (fp); EVENT_DATA (EVENT_HASHLIST_COUNT_LINES_POST, hashfile, strlen (hashfile)); rewind (fp); if (hashes_avail == 0) { event_log_error (hashcat_ctx, "hashfile is empty or corrupt"); fclose (fp); return -1; } hashlist_format = hlfmt_detect (hashcat_ctx, fp, 100); // 100 = max numbers to "scan". could be hashes_avail, too if ((user_options->remove == 1) && (hashlist_format != HLFMT_HASHCAT)) { event_log_error (hashcat_ctx, "remove not supported in native hashfile-format mode"); fclose (fp); return -1; } fclose (fp); } } else { hashlist_mode = HL_MODE_ARG; hashes_avail = 1; } if (hashconfig->hash_mode == 3000) hashes_avail *= 2; hashes->hashlist_mode = hashlist_mode; hashes->hashlist_format = hashlist_format; /** * load hashes, part II: allocate required memory, set pointers */ hash_t *hashes_buf = NULL; void *digests_buf = NULL; salt_t *salts_buf = NULL; void *esalts_buf = NULL; hashes_buf = (hash_t *) hccalloc (hashes_avail, sizeof (hash_t)); digests_buf = (void *) hccalloc (hashes_avail, hashconfig->dgst_size); if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY)) { u32 hash_pos; for (hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashinfo_t *hash_info = (hashinfo_t *) hcmalloc (sizeof (hashinfo_t)); hashes_buf[hash_pos].hash_info = hash_info; if (user_options->username == true) { hash_info->user = (user_t*) hcmalloc (sizeof (user_t)); } if (user_options->benchmark == true) { hash_info->orighash = (char *) hcmalloc (256); } } } if (hashconfig->is_salted) { salts_buf = (salt_t *) hccalloc (hashes_avail, sizeof (salt_t)); if (hashconfig->esalt_size) { esalts_buf = (void *) hccalloc (hashes_avail, hashconfig->esalt_size); } } else { salts_buf = (salt_t *) hccalloc (1, sizeof (salt_t)); } for (u32 hash_pos = 0; hash_pos < hashes_avail; hash_pos++) { hashes_buf[hash_pos].digest = ((char *) digests_buf) + (hash_pos * hashconfig->dgst_size); if (hashconfig->is_salted) { hashes_buf[hash_pos].salt = &salts_buf[hash_pos]; if (hashconfig->esalt_size) { hashes_buf[hash_pos].esalt = ((char *) esalts_buf) + (hash_pos * hashconfig->esalt_size); } } else { hashes_buf[hash_pos].salt = &salts_buf[0]; } } hashes->hashes_buf = hashes_buf; hashes->digests_buf = digests_buf; hashes->salts_buf = salts_buf; hashes->esalts_buf = esalts_buf; /** * load hashes, part III: parse hashes or generate them if benchmark */ u32 hashes_cnt = 0; if (user_options->benchmark == true) { hashconfig_benchmark_defaults (hashcat_ctx, hashes_buf[0].salt, hashes_buf[0].esalt); hashes->hashfile = "-"; hashes_cnt = 1; } else if (user_options->keyspace == true) { } else if (user_options->stdout_flag == true) { } else if (user_options->opencl_info == true) { } else { if (hashes_avail == 0) { // ??? } else if (hashlist_mode == HL_MODE_ARG) { char *input_buf = hash_or_file; u32 input_len = strlen (input_buf); char *hash_buf = NULL; int hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, input_buf, input_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "Failed to parse hashes using the '%s' format", strhlfmt (hashlist_format)); } else { if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted) { memset (hashes_buf[0].salt, 0, sizeof (salt_t)); } int parser_status = PARSER_OK; if (hashconfig->hash_mode == 2500) { if (hash_len == 0) { event_log_error (hashcat_ctx, "hccap file not specified"); return -1; } hashlist_mode = HL_MODE_FILE; hashes->hashlist_mode = hashlist_mode; FILE *fp = fopen (hash_buf, "rb"); if (fp == NULL) { event_log_error (hashcat_ctx, "%s: %m", hash_buf); return -1; } if (hashes_avail < 1) { event_log_error (hashcat_ctx, "hccap file is empty or corrupt"); fclose (fp); return -1; } char *in = (char *) hcmalloc (sizeof (hccap_t)); while (!feof (fp)) { const int nread = fread (in, sizeof (hccap_t), 1, fp); if (nread == 0) break; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s': File changed during runtime, skipping new data", hash_buf); break; } parser_status = hashconfig->parse_func ((u8 *) in, sizeof (hccap_t), &hashes_buf[hashes_cnt], hashconfig); if (parser_status != PARSER_OK) { event_log_warning (hashcat_ctx, "Hashfile '%s': %s", hash_buf, strparser (parser_status)); continue; } hashes_cnt++; } hcfree (in); fclose (fp); } else if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } else { parser_status = hashconfig->parse_func ((u8 *) hash_buf, hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status == PARSER_OK) { hashes_cnt++; } else { event_log_warning (hashcat_ctx, "Hash '%s': %s", input_buf, strparser (parser_status)); } } } } else if (hashlist_mode == HL_MODE_FILE) { char *hashfile = hashes->hashfile; FILE *fp; if ((fp = fopen (hashfile, "rb")) == NULL) { event_log_error (hashcat_ctx, "%s: %m", hashfile); return -1; } u32 line_num = 0; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); time_t prev = 0; time_t now = 0; while (!feof (fp)) { line_num++; int line_len = fgetl (fp, line_buf); if (line_len == 0) continue; if (hashes_avail == hashes_cnt) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u: File changed during runtime, skipping new data", hashes->hashfile, line_num); break; } char *hash_buf = NULL; int hash_len = 0; hlfmt_hash (hashcat_ctx, hashlist_format, line_buf, line_len, &hash_buf, &hash_len); bool hash_fmt_error = 0; if (hash_len < 1) hash_fmt_error = 1; if (hash_buf == NULL) hash_fmt_error = 1; if (hash_fmt_error) { event_log_warning (hashcat_ctx, "failed to parse hashes using the '%s' format", strhlfmt (hashlist_format)); continue; } if (user_options->username == true) { char *user_buf = NULL; int user_len = 0; hlfmt_user (hashcat_ctx, hashlist_format, line_buf, line_len, &user_buf, &user_len); user_t **user = &hashes_buf[hashes_cnt].hash_info->user; *user = (user_t *) hcmalloc (sizeof (user_t)); user_t *user_ptr = *user; if (user_buf != NULL) { user_ptr->user_name = hcstrdup (user_buf); } else { user_ptr->user_name = hcstrdup (""); } user_ptr->user_len = user_len; } if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) { hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info; hash_info_tmp->orighash = hcstrdup (hash_buf); } if (hashconfig->is_salted) { memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t)); } if (hashconfig->hash_mode == 3000) { if (hash_len == 32) { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, line_buf, strparser (parser_status)); continue; } hashes_cnt++; parser_status = hashconfig->parse_func ((u8 *) hash_buf + 16, 16, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, line_buf, strparser (parser_status)); continue; } hashes_cnt++; } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, line_buf, strparser (parser_status)); continue; } hashes_cnt++; } } else { int parser_status = hashconfig->parse_func ((u8 *) hash_buf, hash_len, &hashes_buf[hashes_cnt], hashconfig); if (parser_status < PARSER_GLOBAL_ZERO) { event_log_warning (hashcat_ctx, "Hashfile '%s' on line %u (%s): %s", hashes->hashfile, line_num, line_buf, strparser (parser_status)); continue; } hashes_cnt++; } time (&now); if ((now - prev) == 0) continue; time (&prev); hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); } hashlist_parse_t hashlist_parse; hashlist_parse.hashes_cnt = hashes_cnt; hashlist_parse.hashes_avail = hashes_avail; EVENT_DATA (EVENT_HASHLIST_PARSE_HASH, &hashlist_parse, sizeof (hashlist_parse_t)); hcfree (line_buf); fclose (fp); } } hashes->hashes_cnt = hashes_cnt; if (hashes_cnt) { EVENT (EVENT_HASHLIST_SORT_HASH_PRE); if (hashconfig->is_salted) { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { hc_qsort_r (hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); } EVENT (EVENT_HASHLIST_SORT_HASH_POST); } return 0; }
int tuning_db_init (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; tuning_db_t *tuning_db = hashcat_ctx->tuning_db; user_options_t *user_options = hashcat_ctx->user_options; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; tuning_db->enabled = false; if (user_options->example_hashes == true) return 0; if (user_options->keyspace == true) return 0; if (user_options->left == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->show == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; tuning_db->enabled = true; char *tuning_db_file; hc_asprintf (&tuning_db_file, "%s/%s", folder_config->shared_dir, TUNING_DB_FILE); FILE *fp = fopen (tuning_db_file, "rb"); if (fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", tuning_db_file, strerror (errno)); return -1; } hcfree (tuning_db_file); int num_lines = count_lines (fp); // a bit over-allocated tuning_db->alias_buf = (tuning_db_alias_t *) hccalloc (num_lines + 1, sizeof (tuning_db_alias_t)); tuning_db->alias_cnt = 0; tuning_db->entry_buf = (tuning_db_entry_t *) hccalloc (num_lines + 1, sizeof (tuning_db_entry_t)); tuning_db->entry_cnt = 0; rewind (fp); int line_num = 0; char *buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (fp)) { char *line_buf = fgets (buf, HCBUFSIZ_LARGE - 1, fp); if (line_buf == NULL) break; line_num++; const int line_len = in_superchop (line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; // start processing char *token_ptr[7] = { NULL }; int token_cnt = 0; char *saveptr = NULL; char *next = strtok_r (line_buf, "\t ", &saveptr); token_ptr[token_cnt] = next; token_cnt++; while ((next = strtok_r ((char *) NULL, "\t ", &saveptr)) != NULL) { token_ptr[token_cnt] = next; token_cnt++; } if (token_cnt == 2) { char *device_name = token_ptr[0]; char *alias_name = token_ptr[1]; tuning_db_alias_t *alias = &tuning_db->alias_buf[tuning_db->alias_cnt]; alias->device_name = hcstrdup (device_name); alias->alias_name = hcstrdup (alias_name); tuning_db->alias_cnt++; } else if (token_cnt == 6) { if ((token_ptr[1][0] != '0') && (token_ptr[1][0] != '1') && (token_ptr[1][0] != '3') && (token_ptr[1][0] != '*')) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid attack_mode '%c' in Line '%d'", token_ptr[1][0], line_num); continue; } if ((token_ptr[3][0] != '1') && (token_ptr[3][0] != '2') && (token_ptr[3][0] != '4') && (token_ptr[3][0] != '8') && (token_ptr[3][0] != 'N')) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid vector_width '%c' in Line '%d'", token_ptr[3][0], line_num); continue; } char *device_name = token_ptr[0]; int attack_mode = -1; int hash_type = -1; int vector_width = -1; int kernel_accel = -1; int kernel_loops = -1; if (token_ptr[1][0] != '*') attack_mode = strtol (token_ptr[1], NULL, 10); if (token_ptr[2][0] != '*') hash_type = strtol (token_ptr[2], NULL, 10); if (token_ptr[3][0] != 'N') vector_width = strtol (token_ptr[3], NULL, 10); if (token_ptr[4][0] == 'A') { kernel_accel = 0; } else if (token_ptr[4][0] == 'M') { kernel_accel = 1024; } else { kernel_accel = strtol (token_ptr[4], NULL, 10); if ((kernel_accel < 1) || (kernel_accel > 1024)) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid kernel_accel '%d' in Line '%d'", kernel_accel, line_num); continue; } } if (token_ptr[5][0] == 'A') { kernel_loops = 0; } else if (token_ptr[5][0] == 'M') { if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT) { kernel_loops = KERNEL_RULES; } else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI) { kernel_loops = KERNEL_COMBS; } else if (user_options_extra->attack_kern == ATTACK_KERN_BF) { kernel_loops = KERNEL_BFS; } } else { kernel_loops = strtol (token_ptr[5], NULL, 10); if (kernel_loops < 1) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid kernel_loops '%d' in Line '%d'", kernel_loops, line_num); continue; } if ((user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT) && (kernel_loops > KERNEL_RULES)) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid kernel_loops '%d' in Line '%d'", kernel_loops, line_num); continue; } if ((user_options_extra->attack_kern == ATTACK_KERN_COMBI) && (kernel_loops > KERNEL_COMBS)) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid kernel_loops '%d' in Line '%d'", kernel_loops, line_num); continue; } if ((user_options_extra->attack_kern == ATTACK_KERN_BF) && (kernel_loops > KERNEL_BFS)) { event_log_warning (hashcat_ctx, "Tuning-db: Invalid kernel_loops '%d' in Line '%d'", kernel_loops, line_num); continue; } } tuning_db_entry_t *entry = &tuning_db->entry_buf[tuning_db->entry_cnt]; entry->device_name = hcstrdup (device_name); entry->attack_mode = attack_mode; entry->hash_type = hash_type; entry->vector_width = vector_width; entry->kernel_accel = kernel_accel; entry->kernel_loops = kernel_loops; tuning_db->entry_cnt++; } else { event_log_warning (hashcat_ctx, "Tuning-db: Invalid number of token in Line '%d'", line_num); continue; } } hcfree (buf); fclose (fp); // todo: print loaded 'cnt' message // sort the database qsort (tuning_db->alias_buf, tuning_db->alias_cnt, sizeof (tuning_db_alias_t), sort_by_tuning_db_alias); qsort (tuning_db->entry_buf, tuning_db->entry_cnt, sizeof (tuning_db_entry_t), sort_by_tuning_db_entry); return 0; }
static int outfile_remove (hashcat_ctx_t *hashcat_ctx) { // some hash-dependent constants hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; outcheck_ctx_t *outcheck_ctx = hashcat_ctx->outcheck_ctx; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; user_options_t *user_options = hashcat_ctx->user_options; u32 dgst_size = hashconfig->dgst_size; u32 is_salted = hashconfig->is_salted; u32 esalt_size = hashconfig->esalt_size; u32 hash_mode = hashconfig->hash_mode; char separator = hashconfig->separator; char *root_directory = outcheck_ctx->root_directory; u32 outfile_check_timer = user_options->outfile_check_timer; // buffers hash_t hash_buf = { 0, 0, 0, 0, 0, NULL, 0 }; hash_buf.digest = hcmalloc (dgst_size); if (is_salted) hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t)); if (esalt_size) hash_buf.esalt = (void *) hcmalloc (esalt_size); u32 digest_buf[64] = { 0 }; outfile_data_t *out_info = NULL; char **out_files = NULL; time_t folder_mtime = 0; int out_cnt = 0; u32 check_left = outfile_check_timer; // or 1 if we want to check it at startup while (status_ctx->shutdown_inner == false) { hc_sleep (1); if (status_ctx->devices_status != STATUS_RUNNING) continue; check_left--; if (check_left == 0) { hc_stat_t outfile_check_stat; if (hc_stat (root_directory, &outfile_check_stat) == 0) { u32 is_dir = S_ISDIR (outfile_check_stat.st_mode); if (is_dir == 1) { if (outfile_check_stat.st_mtime > folder_mtime) { char **out_files_new = scan_directory (root_directory); int out_cnt_new = count_dictionaries (out_files_new); outfile_data_t *out_info_new = NULL; if (out_cnt_new > 0) { out_info_new = (outfile_data_t *) hccalloc (out_cnt_new, sizeof (outfile_data_t)); for (int i = 0; i < out_cnt_new; i++) { out_info_new[i].file_name = out_files_new[i]; // check if there are files that we have seen/checked before (and not changed) for (int j = 0; j < out_cnt; j++) { if (strcmp (out_info[j].file_name, out_info_new[i].file_name) == 0) { hc_stat_t outfile_stat; if (hc_stat (out_info_new[i].file_name, &outfile_stat) == 0) { if (outfile_stat.st_ctime == out_info[j].ctime) { out_info_new[i].ctime = out_info[j].ctime; out_info_new[i].seek = out_info[j].seek; } } } } } } hcfree (out_info); hcfree (out_files); out_files = out_files_new; out_cnt = out_cnt_new; out_info = out_info_new; folder_mtime = outfile_check_stat.st_mtime; } for (int j = 0; j < out_cnt; j++) { FILE *fp = fopen (out_info[j].file_name, "rb"); if (fp != NULL) { //hc_thread_mutex_lock (status_ctx->mux_display); hc_stat_t outfile_stat; hc_fstat (fileno (fp), &outfile_stat); if (outfile_stat.st_ctime > out_info[j].ctime) { out_info[j].ctime = outfile_stat.st_ctime; out_info[j].seek = 0; } fseeko (fp, out_info[j].seek, SEEK_SET); char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (fp)) { char *ptr = fgets (line_buf, HCBUFSIZ_LARGE - 1, fp); if (ptr == NULL) break; size_t line_len = strlen (line_buf); if (line_len == 0) continue; size_t iter = MAX_CUT_TRIES; for (size_t i = line_len - 1; i && iter; i--, line_len--) { if (line_buf[i] != separator) continue; iter--; int parser_status = PARSER_OK; if ((hash_mode != 2500) && (hash_mode != 6800)) { parser_status = hashconfig->parse_func ((u8 *) line_buf, line_len - 1, &hash_buf, hashconfig); } u32 found = 0; if (parser_status == PARSER_OK) { for (u32 salt_pos = 0; (found == 0) && (salt_pos < hashes->salts_cnt); salt_pos++) { if (hashes->salts_shown[salt_pos] == 1) continue; salt_t *salt_buf = &hashes->salts_buf[salt_pos]; for (u32 digest_pos = 0; (found == 0) && (digest_pos < salt_buf->digests_cnt); digest_pos++) { u32 idx = salt_buf->digests_offset + digest_pos; if (hashes->digests_shown[idx] == 1) continue; u32 cracked = 0; if (hash_mode == 6800) { if (i == salt_buf->salt_len) { cracked = (memcmp (line_buf, salt_buf->salt_buf, salt_buf->salt_len) == 0); } } else if (hash_mode == 2500) { // BSSID : MAC1 : MAC2 (:plain) if (i == (salt_buf->salt_len + 1 + 12 + 1 + 12)) { cracked = (memcmp (line_buf, salt_buf->salt_buf, salt_buf->salt_len) == 0); if (!cracked) continue; // now compare MAC1 and MAC2 too, since we have this additional info char *mac1_pos = line_buf + salt_buf->salt_len + 1; char *mac2_pos = mac1_pos + 12 + 1; wpa_t *wpas = (wpa_t *) hashes->esalts_buf; wpa_t *wpa = &wpas[salt_pos]; // compare hex string(s) vs binary MAC address(es) for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx++, orig_mac_idx += 2) { if (wpa->orig_mac1[mac_idx] != hex_to_u8 ((const u8 *) &mac1_pos[orig_mac_idx])) { cracked = 0; break; } } // early skip ;) if (!cracked) continue; for (u32 mac_idx = 0, orig_mac_idx = 0; mac_idx < 6; mac_idx++, orig_mac_idx += 2) { if (wpa->orig_mac2[mac_idx] != hex_to_u8 ((const u8 *) &mac2_pos[orig_mac_idx])) { cracked = 0; break; } } } } else { char *digests_buf_ptr = (char *) hashes->digests_buf; memcpy (digest_buf, digests_buf_ptr + (hashes->salts_buf[salt_pos].digests_offset * dgst_size) + (digest_pos * dgst_size), dgst_size); cracked = (sort_by_digest_p0p1 (digest_buf, hash_buf.digest, hashconfig) == 0); } if (cracked == 1) { found = 1; hashes->digests_shown[idx] = 1; hashes->digests_done++; salt_buf->digests_done++; if (salt_buf->digests_done == salt_buf->digests_cnt) { hashes->salts_shown[salt_pos] = 1; hashes->salts_done++; if (hashes->salts_done == hashes->salts_cnt) mycracked (hashcat_ctx); } } } if (status_ctx->devices_status == STATUS_CRACKED) break; } } if (found) break; if (status_ctx->devices_status == STATUS_CRACKED) break; } if (status_ctx->devices_status == STATUS_CRACKED) break; } hcfree (line_buf); out_info[j].seek = ftello (fp); //hc_thread_mutex_unlock (status_ctx->mux_display); fclose (fp); } } } } check_left = outfile_check_timer; } } hcfree (hash_buf.esalt); hcfree (hash_buf.salt); hcfree (hash_buf.digest); hcfree (out_info); hcfree (out_files); return 0; }
static int outfile_remove (hashcat_ctx_t *hashcat_ctx) { // some hash-dependent constants hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashes_t *hashes = hashcat_ctx->hashes; outcheck_ctx_t *outcheck_ctx = hashcat_ctx->outcheck_ctx; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; user_options_t *user_options = hashcat_ctx->user_options; u32 dgst_size = hashconfig->dgst_size; bool is_salted = hashconfig->is_salted; u32 esalt_size = hashconfig->esalt_size; u32 hook_salt_size = hashconfig->hook_salt_size; u32 hash_mode = hashconfig->hash_mode; char separator = hashconfig->separator; char *root_directory = outcheck_ctx->root_directory; u32 outfile_check_timer = user_options->outfile_check_timer; // buffers hash_t hash_buf = { 0, 0, 0, 0, 0, 0, NULL, 0 }; hash_buf.digest = hcmalloc (dgst_size); if (is_salted == true) hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t)); if (esalt_size > 0) hash_buf.esalt = hcmalloc (esalt_size); if (hook_salt_size > 0) hash_buf.hook_salt = hcmalloc (hook_salt_size); u32 digest_buf[64] = { 0 }; outfile_data_t *out_info = NULL; char **out_files = NULL; time_t folder_mtime = 0; int out_cnt = 0; u32 check_left = outfile_check_timer; // or 1 if we want to check it at startup while (status_ctx->shutdown_inner == false) { sleep (1); if (status_ctx->devices_status != STATUS_RUNNING) continue; check_left--; if (check_left == 0) { if (hc_path_exist (root_directory) == true) { const bool is_dir = hc_path_is_directory (root_directory); if (is_dir == true) { struct stat outfile_check_stat; if (stat (root_directory, &outfile_check_stat) == -1) { event_log_error (hashcat_ctx, "%s: %s", root_directory, strerror (errno)); hcfree (out_files); hcfree (out_info); return -1; } if (outfile_check_stat.st_mtime > folder_mtime) { char **out_files_new = scan_directory (root_directory); int out_cnt_new = count_dictionaries (out_files_new); outfile_data_t *out_info_new = NULL; if (out_cnt_new > 0) { out_info_new = (outfile_data_t *) hccalloc (out_cnt_new, sizeof (outfile_data_t)); for (int i = 0; i < out_cnt_new; i++) { out_info_new[i].file_name = out_files_new[i]; // check if there are files that we have seen/checked before (and not changed) for (int j = 0; j < out_cnt; j++) { if (strcmp (out_info[j].file_name, out_info_new[i].file_name) == 0) { struct stat outfile_stat; if (stat (out_info_new[i].file_name, &outfile_stat) == 0) { if (outfile_stat.st_ctime == out_info[j].ctime) { out_info_new[i].ctime = out_info[j].ctime; out_info_new[i].seek = out_info[j].seek; } } } } } } hcfree (out_info); hcfree (out_files); out_files = out_files_new; out_cnt = out_cnt_new; out_info = out_info_new; folder_mtime = outfile_check_stat.st_mtime; } for (int j = 0; j < out_cnt; j++) { FILE *fp = fopen (out_info[j].file_name, "rb"); if (fp != NULL) { //hc_thread_mutex_lock (status_ctx->mux_display); struct stat outfile_stat; if (fstat (fileno (fp), &outfile_stat)) { fclose (fp); continue; } if (outfile_stat.st_ctime > out_info[j].ctime) { out_info[j].ctime = outfile_stat.st_ctime; out_info[j].seek = 0; } fseeko (fp, out_info[j].seek, SEEK_SET); char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (fp)) { char *ptr = fgets (line_buf, HCBUFSIZ_LARGE - 1, fp); if (ptr == NULL) break; size_t line_len = strlen (line_buf); if (line_len == 0) continue; size_t iter = 1; for (size_t i = line_len - 1; i && iter; i--, line_len--) { if (line_buf[i] != separator) continue; iter--; int parser_status = PARSER_OK; if ((hash_mode != 2500) && (hash_mode != 2501) && (hash_mode != 6800)) { parser_status = hashconfig->parse_func ((u8 *) line_buf, line_len - 1, &hash_buf, hashconfig); } u32 found = 0; if (parser_status == PARSER_OK) { for (u32 salt_pos = 0; (found == 0) && (salt_pos < hashes->salts_cnt); salt_pos++) { if (hashes->salts_shown[salt_pos] == 1) continue; salt_t *salt_buf = &hashes->salts_buf[salt_pos]; for (u32 digest_pos = 0; (found == 0) && (digest_pos < salt_buf->digests_cnt); digest_pos++) { u32 idx = salt_buf->digests_offset + digest_pos; if (hashes->digests_shown[idx] == 1) continue; u32 cracked = 0; if (hash_mode == 6800) { if (i == salt_buf->salt_len) { cracked = (memcmp (line_buf, salt_buf->salt_buf, salt_buf->salt_len) == 0); } } else if ((hash_mode == 2500) || (hash_mode == 2501)) { // this comparison is a bit inaccurate as we compare only ESSID // call it a bug, but it's good enough for a special case used in a special case // in this case all essid will be marked as cracked that match the essid if (i == salt_buf->salt_len) { cracked = (memcmp (line_buf, salt_buf->salt_buf, salt_buf->salt_len) == 0); } } else { char *digests_buf_ptr = (char *) hashes->digests_buf; memcpy (digest_buf, digests_buf_ptr + (hashes->salts_buf[salt_pos].digests_offset * dgst_size) + (digest_pos * dgst_size), dgst_size); cracked = (sort_by_digest_p0p1 (digest_buf, hash_buf.digest, hashconfig) == 0); } if (cracked == 1) { found = 1; hashes->digests_shown[idx] = 1; hashes->digests_done++; salt_buf->digests_done++; if (salt_buf->digests_done == salt_buf->digests_cnt) { hashes->salts_shown[salt_pos] = 1; hashes->salts_done++; if (hashes->salts_done == hashes->salts_cnt) mycracked (hashcat_ctx); } } } if (status_ctx->devices_status == STATUS_CRACKED) break; } } if (found) break; if (status_ctx->devices_status == STATUS_CRACKED) break; } if (status_ctx->devices_status == STATUS_CRACKED) break; } hcfree (line_buf); out_info[j].seek = ftello (fp); //hc_thread_mutex_unlock (status_ctx->mux_display); fclose (fp); } } } } check_left = outfile_check_timer; } } hcfree (hash_buf.esalt); hcfree (hash_buf.hook_salt); hcfree (hash_buf.salt); hcfree (hash_buf.digest); hcfree (out_info); hcfree (out_files); return 0; }
static int sp_setup_tbl (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_t *user_options = hashcat_ctx->user_options; char *shared_dir = folder_config->shared_dir; char *hcstat = user_options->markov_hcstat; u32 disable = user_options->markov_disable; u32 classic = user_options->markov_classic; hcstat_table_t *root_table_buf = mask_ctx->root_table_buf; hcstat_table_t *markov_table_buf = mask_ctx->markov_table_buf; /** * Initialize hcstats */ u64 *root_stats_buf = (u64 *) hccalloc (SP_ROOT_CNT, sizeof (u64)); u64 *root_stats_ptr = root_stats_buf; u64 *root_stats_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_stats_buf_by_pos[i] = root_stats_ptr; root_stats_ptr += CHARSIZ; } u64 *markov_stats_buf = (u64 *) hccalloc (SP_MARKOV_CNT, sizeof (u64)); u64 *markov_stats_ptr = markov_stats_buf; u64 *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_stats_buf_by_key[i][j] = markov_stats_ptr; markov_stats_ptr += CHARSIZ; } } /** * Load hcstats File */ if (hcstat == NULL) { char hcstat_tmp[256] = { 0 }; snprintf (hcstat_tmp, sizeof (hcstat_tmp) - 1, "%s/%s", shared_dir, SP_HCSTAT); hcstat = hcstat_tmp; } FILE *fd = fopen (hcstat, "rb"); if (fd == NULL) { event_log_error (hashcat_ctx, "%s: %m", hcstat); return -1; } if (fread (root_stats_buf, sizeof (u64), SP_ROOT_CNT, fd) != SP_ROOT_CNT) { event_log_error (hashcat_ctx, "%s: Could not load data", hcstat); fclose (fd); return -1; } if (fread (markov_stats_buf, sizeof (u64), SP_MARKOV_CNT, fd) != SP_MARKOV_CNT) { event_log_error (hashcat_ctx, "%s: Could not load data", hcstat); fclose (fd); return -1; } fclose (fd); /** * Markov modifier of hcstat_table on user request */ if (disable) { memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (u64)); memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (u64)); } if (classic) { /* Add all stats to first position */ for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = root_stats_buf_by_pos[0]; u64 *in = root_stats_buf_by_pos[i]; for (int j = 0; j < CHARSIZ; j++) { *out++ += *in++; } } for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = markov_stats_buf_by_key[0][0]; u64 *in = markov_stats_buf_by_key[i][0]; for (int j = 0; j < CHARSIZ; j++) { for (int k = 0; k < CHARSIZ; k++) { *out++ += *in++; } } } /* copy them to all pw_positions */ for (int i = 1; i < SP_PW_MAX; i++) { memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (u64)); } for (int i = 1; i < SP_PW_MAX; i++) { memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (u64)); } } /** * Initialize tables */ hcstat_table_t *root_table_ptr = root_table_buf; hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_table_buf_by_pos[i] = root_table_ptr; root_table_ptr += CHARSIZ; } hcstat_table_t *markov_table_ptr = markov_table_buf; hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_table_buf_by_key[i][j] = markov_table_ptr; markov_table_ptr += CHARSIZ; } } /** * Convert hcstat to tables */ for (int i = 0; i < SP_ROOT_CNT; i++) { u32 key = i % CHARSIZ; root_table_buf[i].key = key; root_table_buf[i].val = root_stats_buf[i]; } for (int i = 0; i < SP_MARKOV_CNT; i++) { u32 key = i % CHARSIZ; markov_table_buf[i].key = key; markov_table_buf[i].val = markov_stats_buf[i]; } hcfree (root_stats_buf); hcfree (markov_stats_buf); /** * Finally sort them */ for (int i = 0; i < SP_PW_MAX; i++) { qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } } return 0; }