1 /**
2 * Author......: See docs/credits.txt
3 * License.....: MIT
4 */
5
6 #include "common.h"
7 #include "types.h"
8 #include "memory.h"
9 #include "event.h"
10 #include "logfile.h"
11 #include "shared.h"
12 #include "folder.h"
13 #include "rp.h"
14 #include "wordlist.h"
15 #include "straight.h"
16
straight_ctx_add_wl(hashcat_ctx_t * hashcat_ctx,const char * dict)17 static int straight_ctx_add_wl (hashcat_ctx_t *hashcat_ctx, const char *dict)
18 {
19 if (hc_path_has_bom (dict) == true)
20 {
21 event_log_warning (hashcat_ctx, "%s: Byte Order Mark (BOM) was detected", dict);
22
23 //return -1;
24 }
25
26 straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx;
27
28 if (straight_ctx->dicts_avail == straight_ctx->dicts_cnt)
29 {
30 straight_ctx->dicts = (char **) hcrealloc (straight_ctx->dicts, straight_ctx->dicts_avail * sizeof (char *), INCR_DICTS * sizeof (char *));
31
32 straight_ctx->dicts_avail += INCR_DICTS;
33 }
34
35 straight_ctx->dicts[straight_ctx->dicts_cnt] = hcstrdup (dict);
36
37 straight_ctx->dicts_cnt++;
38
39 return 0;
40 }
41
straight_ctx_update_loop(hashcat_ctx_t * hashcat_ctx)42 int straight_ctx_update_loop (hashcat_ctx_t *hashcat_ctx)
43 {
44 combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx;
45 induct_ctx_t *induct_ctx = hashcat_ctx->induct_ctx;
46 hashes_t *hashes = hashcat_ctx->hashes;
47 logfile_ctx_t *logfile_ctx = hashcat_ctx->logfile_ctx;
48 mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx;
49 status_ctx_t *status_ctx = hashcat_ctx->status_ctx;
50 straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx;
51 user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra;
52 user_options_t *user_options = hashcat_ctx->user_options;
53
54 if (user_options->attack_mode == ATTACK_MODE_STRAIGHT)
55 {
56 if (user_options_extra->wordlist_mode == WL_MODE_FILE)
57 {
58 if (induct_ctx->induction_dictionaries_cnt)
59 {
60 straight_ctx->dict = induct_ctx->induction_dictionaries[induct_ctx->induction_dictionaries_pos];
61 }
62 else
63 {
64 straight_ctx->dict = straight_ctx->dicts[straight_ctx->dicts_pos];
65 }
66
67 logfile_sub_string (straight_ctx->dict);
68
69 for (u32 i = 0; i < user_options->rp_files_cnt; i++)
70 {
71 logfile_sub_var_string ("rulefile", user_options->rp_files[i]);
72 }
73
74 HCFILE fp;
75
76 if (hc_fopen (&fp, straight_ctx->dict, "rb") == false)
77 {
78 event_log_error (hashcat_ctx, "%s: %s", straight_ctx->dict, strerror (errno));
79
80 return -1;
81 }
82
83 const int rc = count_words (hashcat_ctx, &fp, straight_ctx->dict, &status_ctx->words_cnt);
84
85 hc_fclose (&fp);
86
87 if (rc == -1)
88 {
89 event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", straight_ctx->dict);
90
91 return -1;
92 }
93
94 if (status_ctx->words_cnt == 0)
95 {
96 logfile_sub_msg ("STOP");
97
98 return 0;
99 }
100 }
101 }
102 else if (user_options->attack_mode == ATTACK_MODE_COMBI)
103 {
104 logfile_sub_string (combinator_ctx->dict1);
105 logfile_sub_string (combinator_ctx->dict2);
106
107 if (combinator_ctx->combs_mode == COMBINATOR_MODE_BASE_LEFT)
108 {
109 HCFILE fp;
110
111 if (hc_fopen (&fp, combinator_ctx->dict1, "rb") == false)
112 {
113 event_log_error (hashcat_ctx, "%s: %s", combinator_ctx->dict1, strerror (errno));
114
115 return -1;
116 }
117
118 const int rc = count_words (hashcat_ctx, &fp, combinator_ctx->dict1, &status_ctx->words_cnt);
119
120 hc_fclose (&fp);
121
122 if (rc == -1)
123 {
124 event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", combinator_ctx->dict1);
125
126 return -1;
127 }
128 }
129 else if (combinator_ctx->combs_mode == COMBINATOR_MODE_BASE_RIGHT)
130 {
131 HCFILE fp;
132
133 if (hc_fopen (&fp, combinator_ctx->dict2, "rb") == false)
134 {
135 event_log_error (hashcat_ctx, "%s: %s", combinator_ctx->dict2, strerror (errno));
136
137 return -1;
138 }
139
140 const int rc = count_words (hashcat_ctx, &fp, combinator_ctx->dict2, &status_ctx->words_cnt);
141
142 hc_fclose (&fp);
143
144 if (rc == -1)
145 {
146 event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", combinator_ctx->dict2);
147
148 return -1;
149 }
150 }
151
152 if (status_ctx->words_cnt == 0)
153 {
154 logfile_sub_msg ("STOP");
155
156 return 0;
157 }
158 }
159 else if (user_options->attack_mode == ATTACK_MODE_BF)
160 {
161 logfile_sub_string (mask_ctx->mask);
162 }
163 else if ((user_options->attack_mode == ATTACK_MODE_HYBRID1) || (user_options->attack_mode == ATTACK_MODE_HYBRID2))
164 {
165 if (induct_ctx->induction_dictionaries_cnt)
166 {
167 straight_ctx->dict = induct_ctx->induction_dictionaries[induct_ctx->induction_dictionaries_pos];
168 }
169 else
170 {
171 straight_ctx->dict = straight_ctx->dicts[straight_ctx->dicts_pos];
172 }
173
174 logfile_sub_string (straight_ctx->dict);
175 logfile_sub_string (mask_ctx->mask);
176
177 HCFILE fp;
178
179 if (hc_fopen (&fp, straight_ctx->dict, "rb") == false)
180 {
181 event_log_error (hashcat_ctx, "%s: %s", straight_ctx->dict, strerror (errno));
182
183 return -1;
184 }
185
186 const int rc = count_words (hashcat_ctx, &fp, straight_ctx->dict, &status_ctx->words_cnt);
187
188 hc_fclose (&fp);
189
190 if (rc == -1)
191 {
192 event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", straight_ctx->dict);
193
194 return -1;
195 }
196
197 if (status_ctx->words_cnt == 0)
198 {
199 logfile_sub_msg ("STOP");
200
201 return 0;
202 }
203 }
204 else if (user_options->attack_mode == ATTACK_MODE_ASSOCIATION)
205 {
206 if (user_options_extra->wordlist_mode == WL_MODE_FILE)
207 {
208 straight_ctx->dict = straight_ctx->dicts[straight_ctx->dicts_pos];
209
210 logfile_sub_string (straight_ctx->dict);
211
212 for (u32 i = 0; i < user_options->rp_files_cnt; i++)
213 {
214 logfile_sub_var_string ("rulefile", user_options->rp_files[i]);
215 }
216
217 HCFILE fp;
218
219 if (hc_fopen (&fp, straight_ctx->dict, "rb") == false)
220 {
221 event_log_error (hashcat_ctx, "%s: %s", straight_ctx->dict, strerror (errno));
222
223 return -1;
224 }
225
226 const int rc = count_words (hashcat_ctx, &fp, straight_ctx->dict, &status_ctx->words_cnt);
227
228 hc_fclose (&fp);
229
230 if (rc == -1)
231 {
232 event_log_error (hashcat_ctx, "Integer overflow detected in keyspace of wordlist: %s", straight_ctx->dict);
233
234 return -1;
235 }
236
237 if ((status_ctx->words_cnt / straight_ctx->kernel_rules_cnt) != hashes->salts_cnt)
238 {
239 event_log_error (hashcat_ctx, "Number of words in wordlist '%s' is not in sync with number of unique salts", straight_ctx->dict);
240 event_log_error (hashcat_ctx, "Words: %" PRIu64 ", salts: %d", status_ctx->words_cnt / straight_ctx->kernel_rules_cnt, hashes->salts_cnt);
241
242 return -1;
243 }
244
245 if (status_ctx->words_cnt == 0)
246 {
247 logfile_sub_msg ("STOP");
248
249 return 0;
250 }
251 }
252 }
253
254 return 0;
255 }
256
straight_ctx_init(hashcat_ctx_t * hashcat_ctx)257 int straight_ctx_init (hashcat_ctx_t *hashcat_ctx)
258 {
259 straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx;
260 user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra;
261 user_options_t *user_options = hashcat_ctx->user_options;
262
263 straight_ctx->enabled = false;
264
265 if (user_options->hash_info == true) return 0;
266 if (user_options->left == true) return 0;
267 if (user_options->backend_info == true) return 0;
268 if (user_options->show == true) return 0;
269 if (user_options->usage == true) return 0;
270 if (user_options->version == true) return 0;
271
272 if (user_options->attack_mode == ATTACK_MODE_BF) return 0;
273
274 straight_ctx->enabled = true;
275
276 /**
277 * generate NOP rules
278 */
279
280 if ((user_options->rp_files_cnt == 0) && (user_options->rp_gen == 0))
281 {
282 straight_ctx->kernel_rules_buf = (kernel_rule_t *) hcmalloc (sizeof (kernel_rule_t));
283
284 straight_ctx->kernel_rules_buf[0].cmds[0] = RULE_OP_MANGLE_NOOP;
285
286 straight_ctx->kernel_rules_cnt = 1;
287 }
288 else
289 {
290 if (user_options->rp_files_cnt)
291 {
292 if (kernel_rules_load (hashcat_ctx, &straight_ctx->kernel_rules_buf, &straight_ctx->kernel_rules_cnt) == -1) return -1;
293 }
294 else if (user_options->rp_gen)
295 {
296 if (kernel_rules_generate (hashcat_ctx, &straight_ctx->kernel_rules_buf, &straight_ctx->kernel_rules_cnt, user_options->rp_gen_func_sel) == -1) return -1;
297 }
298 }
299
300 /**
301 * wordlist based work
302 */
303
304 if ((user_options->attack_mode == ATTACK_MODE_STRAIGHT) || (user_options->attack_mode == ATTACK_MODE_ASSOCIATION))
305 {
306 if (user_options_extra->wordlist_mode == WL_MODE_FILE)
307 {
308 for (int i = 0; i < user_options_extra->hc_workc; i++)
309 {
310 char *l0_filename = user_options_extra->hc_workv[i];
311
312 // at this point we already verified the path actually exist and is readable
313
314 if (hc_path_is_directory (l0_filename) == true)
315 {
316 char **dictionary_files;
317
318 dictionary_files = scan_directory (l0_filename);
319
320 if (dictionary_files != NULL)
321 {
322 qsort (dictionary_files, (size_t) count_dictionaries (dictionary_files), sizeof (char *), sort_by_stringptr);
323
324 for (int d = 0; dictionary_files[d] != NULL; d++)
325 {
326 char *l1_filename = dictionary_files[d];
327
328 if (hc_path_read (l1_filename) == false)
329 {
330 event_log_error (hashcat_ctx, "%s: %s", l1_filename, strerror (errno));
331
332 hcfree (dictionary_files);
333
334 return -1;
335 }
336
337 if (hc_path_is_file (l1_filename) == true)
338 {
339 if (straight_ctx_add_wl (hashcat_ctx, l1_filename) == -1)
340 {
341 hcfree (dictionary_files);
342
343 return -1;
344 }
345 }
346 }
347 }
348
349 hcfree (dictionary_files);
350 }
351 else
352 {
353 if (straight_ctx_add_wl (hashcat_ctx, l0_filename) == -1) return -1;
354 }
355 }
356
357 if (straight_ctx->dicts_cnt == 0)
358 {
359 event_log_error (hashcat_ctx, "No usable dictionary file found.");
360
361 return -1;
362 }
363 }
364 }
365 else if (user_options->attack_mode == ATTACK_MODE_COMBI)
366 {
367
368 }
369 else if (user_options->attack_mode == ATTACK_MODE_BF)
370 {
371
372 }
373 else if (user_options->attack_mode == ATTACK_MODE_HYBRID1)
374 {
375 for (int i = 0; i < user_options_extra->hc_workc - 1; i++)
376 {
377 char *l0_filename = user_options_extra->hc_workv[i];
378
379 // at this point we already verified the path actually exist and is readable
380
381 if (hc_path_is_directory (l0_filename) == true)
382 {
383 char **dictionary_files;
384
385 dictionary_files = scan_directory (l0_filename);
386
387 if (dictionary_files != NULL)
388 {
389 qsort (dictionary_files, (size_t) count_dictionaries (dictionary_files), sizeof (char *), sort_by_stringptr);
390
391 for (int d = 0; dictionary_files[d] != NULL; d++)
392 {
393 char *l1_filename = dictionary_files[d];
394
395 if (hc_path_read (l1_filename) == false)
396 {
397 event_log_error (hashcat_ctx, "%s: %s", l1_filename, strerror (errno));
398
399 hcfree (dictionary_files);
400
401 return -1;
402 }
403
404 if (hc_path_is_file (l1_filename) == true)
405 {
406 if (straight_ctx_add_wl (hashcat_ctx, l1_filename) == -1)
407 {
408 hcfree (dictionary_files);
409
410 return -1;
411 }
412 }
413 }
414 }
415
416 hcfree (dictionary_files);
417 }
418 else
419 {
420 if (straight_ctx_add_wl (hashcat_ctx, l0_filename) == -1) return -1;
421 }
422 }
423
424 if (straight_ctx->dicts_cnt == 0)
425 {
426 event_log_error (hashcat_ctx, "No usable dictionary file found.");
427
428 return -1;
429 }
430 }
431 else if (user_options->attack_mode == ATTACK_MODE_HYBRID2)
432 {
433 for (int i = 1; i < user_options_extra->hc_workc; i++)
434 {
435 char *l0_filename = user_options_extra->hc_workv[i];
436
437 // at this point we already verified the path actually exist and is readable
438
439 if (hc_path_is_directory (l0_filename) == true)
440 {
441 char **dictionary_files;
442
443 dictionary_files = scan_directory (l0_filename);
444
445 if (dictionary_files != NULL)
446 {
447 qsort (dictionary_files, (size_t) count_dictionaries (dictionary_files), sizeof (char *), sort_by_stringptr);
448
449 for (int d = 0; dictionary_files[d] != NULL; d++)
450 {
451 char *l1_filename = dictionary_files[d];
452
453 if (hc_path_read (l1_filename) == false)
454 {
455 event_log_error (hashcat_ctx, "%s: %s", l1_filename, strerror (errno));
456
457 hcfree (dictionary_files);
458
459 return -1;
460 }
461
462 if (hc_path_is_file (l1_filename) == true)
463 {
464 if (straight_ctx_add_wl (hashcat_ctx, l1_filename) == -1)
465 {
466 hcfree (dictionary_files);
467
468 return -1;
469 }
470 }
471 }
472 }
473
474 hcfree (dictionary_files);
475 }
476 else
477 {
478 if (straight_ctx_add_wl (hashcat_ctx, l0_filename) == -1) return -1;
479 }
480 }
481
482 if (straight_ctx->dicts_cnt == 0)
483 {
484 event_log_error (hashcat_ctx, "No usable dictionary file found.");
485
486 return -1;
487 }
488 }
489
490 return 0;
491 }
492
straight_ctx_destroy(hashcat_ctx_t * hashcat_ctx)493 void straight_ctx_destroy (hashcat_ctx_t *hashcat_ctx)
494 {
495 straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx;
496
497 if (straight_ctx->enabled == false) return;
498
499 for (u32 dict_pos = 0; dict_pos < straight_ctx->dicts_cnt; dict_pos++)
500 {
501 hcfree (straight_ctx->dicts[dict_pos]);
502 }
503
504 hcfree (straight_ctx->dicts);
505
506 hcfree (straight_ctx->kernel_rules_buf);
507
508 memset (straight_ctx, 0, sizeof (straight_ctx_t));
509 }
510