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