1 /*
2  *
3  *   Ophcrack is a Lanmanager/NTLM hash cracker based on the faster time-memory
4  *   trade-off using rainbow tables.
5  *
6  *   Created with the help of: Maxime Mueller, Luca Wullschleger, Claude
7  *   Hochreutiner, Andreas Huber and Etienne Dysli.
8  *
9  *   Copyright (c) 2008 Philippe Oechslin, Cedric Tissieres, Bertrand Mesot
10  *
11  *   Ophcrack is free software; you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation; either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   Ophcrack is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Ophcrack; if not, write to the Free Software
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  *
25  *   This program is released under the GPL with the additional exemption
26  *   that compiling, linking, and/or using OpenSSL is allowed.
27  *
28  *
29  *
30  *
31 */
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <stdint.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <unistd.h>
38 #include <regex.h>
39 
40 #include "hash.h"
41 #include "samdump2.h"
42 /*-------------------------------------------------------------------------*/
hash_alloc(hash_kind_t kind,int hlen,int plen,int id)43 hash_t *hash_alloc(hash_kind_t kind, int hlen, int plen, int id) {
44   hash_t *hsh = (hash_t*)malloc(sizeof(hash_t));
45 
46   hsh->kind = kind;
47   hsh->hash = (uchar_t*)malloc(hlen*sizeof(uchar_t));
48   hsh->pwd  = (char*)malloc(plen*sizeof(char));
49   hsh->str  = 0;
50   hsh->status = 0;
51 
52   memset(hsh->hash, 0, hlen);
53   memset(hsh->pwd, 0, plen);
54   memset(hsh->info, 0, 64);
55 
56   hsh->lmhsh1 = 0;
57   hsh->lmhsh2 = 0;
58 
59   hsh->id     = id;
60   hsh->uid    = 0;
61   hsh->done   = 0;
62   hsh->tables = list_alloc();
63   hsh->tnd    = 0;
64 
65   hsh->length   = 0;
66   hsh->category = 0;
67   hsh->time     = -1;
68   hsh->table    = 0;
69 
70   return hsh;
71 }
72 /*-------------------------------------------------------------------------*/
hash_free(hash_t * hsh)73 void hash_free(hash_t *hsh) {
74   free(hsh->hash);
75   free(hsh->pwd);
76   if (hsh->str) free(hsh->str);
77   if (hsh->status) free(hsh->status);
78   if (hsh->table) free(hsh->table);
79 
80   while (hsh->tables->size > 0) {
81     htbl_t *htbl = list_rem_head(hsh->tables);
82     free(htbl);
83   }
84 
85   list_free(hsh->tables);
86   free(hsh);
87 }
88 /*-------------------------------------------------------------------------*/
hash_add_table(hash_t * hsh,table_t * tbl)89 void hash_add_table(hash_t *hsh, table_t *tbl) {
90   htbl_t *htbl = (htbl_t*)malloc(sizeof(htbl_t));
91   const char *status = hsh->status;
92 
93   /* Fill in the htbl_t data structure for the given table. */
94 
95   htbl->tbl = tbl;
96   htbl->col = tbl->ncols-1;
97   htbl->covered = tbl->ncols;
98 
99   /* Look for the table in the status string. */
100 
101   if (status != 0) {
102     char *buff = strdup(status);
103     char *tmp  = buff;
104 
105     /* Compile the regexp. */
106 
107     static const char pattern[] = "([^,]+),([0-9]+)\\(([0-9]+)\\)";
108 
109     regex_t regex;
110     regmatch_t match[4];
111 
112     regcomp(&regex, pattern, REG_EXTENDED);
113 
114     while (regexec(&regex, tmp, 4, match, 0) == 0) {
115       if (match[1].rm_so == -1 ||
116 	  match[2].rm_so == -1 ||
117 	  match[3].rm_so == -1)
118 	break;
119 
120       tmp[match[1].rm_eo] = 0;
121       tmp[match[2].rm_eo] = 0;
122       tmp[match[3].rm_eo] = 0;
123 
124       const char *name = tmp + match[1].rm_so;
125       int idx = atoi(tmp + match[2].rm_so);
126 
127       if (idx == tbl->idx && strcmp(name, table_string(tbl->kind)) == 0) {
128 	htbl->covered = atoi(tmp + match[3].rm_so);
129 	htbl->col = htbl->covered - 1;
130 	break;
131       }
132 
133       tmp += match[3].rm_eo+1;
134     }
135 
136     free(buff);
137     regfree(&regex);
138   }
139 
140   list_add_tail(hsh->tables, htbl);
141 }
142 /*-------------------------------------------------------------------------*/
hash_extract_lmnt(char * buff,list_t * hashes,int id)143 int hash_extract_lmnt(char *buff, list_t *hashes, int id) {
144   /* Split the buffer according to the positions of ':'. */
145 
146   int l;
147   char *p[11] = {0};
148 
149   for (l=0; l<11; ++l)
150     if ((p[l] = strsep(&buff, ":")) == 0) break;
151 
152   /* Copy the LM and NT hashes. */
153 
154   char lmstr[33] = {0};
155   char ntstr[33] = {0};
156 
157   /* PWDUMP formatted string. */
158 
159   if (l >= 7) {
160     if ((strcmp(p[2], pwdump_nopwd) != 0) &&
161 	(strcmp(p[2], samdump_nopwd) != 0))
162       strncpy(lmstr, p[2], sizeof(lmstr));
163     else
164       strncpy(lmstr, "aad3b435b51404eeaad3b435b51404ee", sizeof(lmstr));
165 
166     if ((strcmp(p[3], pwdump_nopwd) != 0) &&
167 	(strcmp(p[3], samdump_nopwd) != 0))
168       strncpy(ntstr, p[3], sizeof(ntstr));
169     else
170       strncpy(ntstr, "31d6cfe0d16ae931b73c59d7e0c089c0", sizeof(ntstr));
171   }
172 
173   /* A pair of LM and NT hashes. */
174 
175   else if (l == 2) {
176     if ((strcmp(p[0], pwdump_nopwd) != 0) &&
177 	(strcmp(p[0], samdump_nopwd) != 0))
178       strncpy(lmstr, p[0], sizeof(lmstr));
179     else
180       strncpy(lmstr, "aad3b435b51404eeaad3b435b51404ee", sizeof(lmstr));
181 
182     if ((strcmp(p[1], pwdump_nopwd) != 0) &&
183 	(strcmp(p[1], samdump_nopwd) != 0))
184       strncpy(ntstr, p[1], sizeof(ntstr));
185     else
186       strncpy(ntstr, "31d6cfe0d16ae931b73c59d7e0c089c0", sizeof(ntstr));
187   }
188 
189   /* A single LM hash. */
190 
191   else if (l == 1) {
192     if ((strcmp(p[0], pwdump_nopwd) != 0) &&
193 	(strcmp(p[0], samdump_nopwd) != 0))
194       strncpy(lmstr, p[0], sizeof(lmstr));
195     else
196       strncpy(lmstr, "aad3b435b51404eeaad3b435b51404ee", sizeof(lmstr));
197   }
198 
199   /* Unknown format. */
200 
201   else
202     return 0;
203 
204   /* Check that the hashes have the correct length. */
205 
206   int lmlen = strlen(lmstr);
207   int ntlen = strlen(ntstr);
208 
209   if (lmlen != 32 && ntlen != 32) return 0;
210 /*   if (l == 1 && lmlen == 0) return 0; */
211 /*   if (lmlen > 0 && lmlen != 32) return 0; */
212 /*   if (ntlen > 0 && ntlen != 32) return 0; */
213 
214   /* Extract the LM hashes. */
215 
216   hash_t *lmhsh1 = 0;
217   hash_t *lmhsh2 = 0;
218 
219   int lmplen1 = l == 7 ? strlen(p[4]) : 8;
220   int lmplen2 = l == 7 ? strlen(p[5]) : 8;
221 
222   if (strcmp(lmstr, "") != 0) {
223     lmhsh1 = hash_alloc(lm1, 8, lmplen1 < 8 ? 8 : lmplen1, id);
224     lmhsh2 = hash_alloc(lm2, 8, lmplen2 < 8 ? 8 : lmplen2, id);
225 
226     lmhsh1->str = strdup(lmstr);
227     lmhsh2->str = strdup(lmstr);
228 
229     int i;
230     uint32_t tmp;
231 
232     for (i=0; i<8; ++i) {
233       if (sscanf(lmstr+2*i, "%2x", &tmp) != 1) return 0;
234       lmhsh1->hash[i] = (uchar_t)tmp;
235 
236       if (sscanf(lmstr+2*i+16, "%2x", &tmp) != 1) return 0;
237       lmhsh2->hash[i] = (uchar_t)tmp;
238     }
239   }
240 
241   /* Extract the NT hash. */
242 
243   hash_t *nthsh = 0;
244   int ntplen = l == 7 ? strlen(p[6]) : 16;
245 
246   if (strcmp(ntstr, "") != 0) {
247     nthsh = hash_alloc(nt, 16, ntplen < 16 ? 16 : ntplen, id);
248     nthsh->str = strdup(ntstr);
249 
250     int i;
251     uint32_t tmp;
252 
253     for (i=0; i<16; ++i) {
254       if (sscanf(ntstr+2*i, "%2x", &tmp) != 1) return 0;
255       nthsh->hash[i] = (uchar_t)tmp;
256     }
257   }
258 
259   /* Store the user name, id and password if provided. */
260 
261   if (l >= 7) {
262     int uid = atoi(p[1]);
263 
264     if (lmhsh1) {
265       strncpy(lmhsh1->info, p[0], sizeof(lmhsh1->info));
266       lmhsh1->uid = uid;
267 
268       if (lmplen1 < 8)
269 	strncpy(lmhsh1->pwd, p[4], lmplen1);
270       convert_to_colon((uchar_t*)lmhsh1->pwd);
271 
272 
273       if (l >= 8)
274 	lmhsh1->status = strdup(p[7]);
275     }
276 
277     if (lmhsh2) {
278       strncpy(lmhsh2->info, p[0], sizeof(lmhsh2->info));
279       lmhsh2->uid = uid;
280 
281       if (lmplen2 < 8)
282 	strncpy(lmhsh2->pwd, p[5], lmplen2);
283       convert_to_colon((uchar_t*)lmhsh2->pwd);
284 
285 
286       if (l >= 9)
287 	lmhsh2->status = strdup(p[8]);
288     }
289 
290     if (nthsh) {
291       strncpy(nthsh->info, p[0], sizeof(nthsh->info));
292       nthsh->uid  = uid;
293 
294       strncpy(nthsh->pwd, p[6], ntplen);
295       convert_to_colon((uchar_t*)nthsh->pwd);
296 
297       if (l >= 10)
298 	nthsh->status = strdup(p[9]);
299     }
300   }
301 
302   /* Check for empty hashes. */
303 
304   int empty1 = 0;
305   int empty2 = 0;
306 
307   if (lmhsh1 && memcmp(lmhsh1->hash, empty_lmhash, 8) == 0) {
308     empty1 = 1;
309     lmhsh1->done = 1;
310   }
311 
312   if (lmhsh2 && memcmp(lmhsh2->hash, empty_lmhash, 8) == 0) {
313     empty2 = 1;
314     lmhsh2->done = 1;
315   }
316 
317   if (nthsh && memcmp(nthsh->hash, empty_nthash, 16) == 0)
318     nthsh->done = 1;
319 
320   /* Check for non empty passwords. */
321 
322   if (lmhsh1 && lmhsh1->pwd[0] != 0)
323     lmhsh1->done = 1;
324 
325   if (lmhsh2 && lmhsh2->pwd[0] != 0)
326     lmhsh2->done = 1;
327 
328   if (nthsh && nthsh->pwd[0] != 0)
329     nthsh->done = 1;
330 
331   /* If both LM hashes are empty, then its like if we do not have any
332      LM at all. */
333 
334   if (empty1 && empty2) {
335     hash_free(lmhsh1);
336     hash_free(lmhsh2);
337 
338     lmhsh1 = 0;
339     lmhsh2 = 0;
340   }
341 
342   /* Each 1st/2nd LM hash keeps a pointer on the associated NT and
343      2nd/1st LM hashes. */
344 
345   if (lmhsh1) {
346     lmhsh1->lmhsh1 = nthsh;
347     lmhsh1->lmhsh2 = lmhsh2;
348   }
349 
350   if (lmhsh2) {
351     lmhsh2->lmhsh1 = lmhsh1;
352     lmhsh2->lmhsh2 = nthsh;
353   }
354 
355   /* The NT hash keeps a pointer on both LM hashes. */
356 
357   if (nthsh) {
358     nthsh->lmhsh1 = lmhsh1;
359     nthsh->lmhsh2 = lmhsh2;
360   }
361 
362   /* Add the 1st LM, 2nd LM and NT hashes to the list of hashes. */
363 
364   if (lmhsh1) list_add_tail(hashes, lmhsh1);
365   if (lmhsh2) list_add_tail(hashes, lmhsh2);
366   if (nthsh) list_add_tail(hashes, nthsh);
367 
368   return 1;
369 }
370 /*-------------------------------------------------------------------------*/
hash_load_pwdump(list_t * hashes,FILE * file,int id)371 int hash_load_pwdump(list_t *hashes, FILE *file, int id) {
372   char buff[STR_BUFF_SIZE];
373 
374   /* Read and parse each entry of the hash file. */
375 
376   int npwds = 0;
377   int n;
378 
379   for (n=0;; ++n) {
380     if (fgets(buff, sizeof(buff), file) == 0) break;
381 
382     /* Remove a potential (\r)\n at the end of the line. */
383 
384     int len = strlen(buff);
385     if (buff[len-1] == '\n') buff[len-1] = 0;
386     if (buff[len-2] == '\r') buff[len-2] = 0;
387 
388     /* Parse the line according to the type of hash we want to crack. */
389 
390     if (hash_extract_lmnt(buff, hashes, id) > 0) {
391       ++id;
392       ++npwds;
393     }
394   }
395 
396   return npwds;
397 }
398 /*-------------------------------------------------------------------------*/
hash_load_sam(list_t * hashes,const char * dir,int id)399 int hash_load_sam(list_t *hashes, const char *dir, int id) {
400   static const char *name[2] = { "SYSTEM", "SAM" };
401   static const int da = 'a' - 'A';
402 
403   /* Try to find the SYSTEM and SAM file by enumerating all the
404      possible upper/lower case variations of both file names. */
405 
406   char fname[2][STR_BUFF_SIZE] = { {0}, {0} };
407   int i, j;
408 
409   for (i=0; i<2; ++i) {
410     int len = strlen(name[i]);
411     int count = 1 << len;
412     char tmp[10] = {0};
413 
414     while (count--) {
415       for (j=0; j<len; ++j) {
416 	tmp[j] = name[i][j];
417 	if ((count >> j) & 1) tmp[j] += da;
418       }
419 
420       snprintf(fname[i], sizeof(fname[i]), "%s/%s", dir, tmp);
421 
422       if (access(fname[i], R_OK) != 0)
423 	fname[i][0] = 0;
424       else
425 	break;
426     }
427   }
428 
429   /* If we did not find both files, then we stop. */
430 
431   char *sys = fname[0];
432   char *sam = fname[1];
433 
434   if (sys[0] == 0) return -1;
435   if (sam[0] == 0) return -2;
436 
437   /* Otherwise, we extract the hashes. */
438 
439   uchar_t pkey[0x10];
440   char error[512];
441 
442   if (bkhive((uchar_t*)sys, pkey, error, 0) == -1) return -3;
443 
444   /* Retrieve the hashes. */
445 
446   list_t *hstr = list_alloc();
447   list_nd_t *nd;
448 
449   int ret = samdump2((uchar_t*)sam, hstr, pkey, error, 0, 0, 0);
450   int npwds = 0;
451 
452   if (ret != -1)
453     for (nd = hstr->head; nd != 0; nd = nd->next) {
454       char *str = (char*)nd->data;
455 
456       if (hash_extract_lmnt(str, hashes, id)) {
457 	++id;
458 	++npwds;
459       }
460     }
461 
462   list_free(hstr);
463 
464   return ret != -1 ? npwds : -4;
465 }
466 /*-------------------------------------------------------------------------*/
hash_dump_sam(list_t * hashes,int id)467 int hash_dump_sam(list_t *hashes, int id) {
468 
469   int npwds = 0;
470 
471 #ifdef WIN32
472   char error[512];
473   uchar_t pkey[0x10];
474   uchar_t *buff_sam;
475   int size = 0;
476 
477   if (get_live_syskey(pkey, error, 0) == -1)
478     return -1;
479 
480   if (get_sam(&buff_sam, &size, error, 0) == -1)
481     return -2;
482 
483   list_t *hstr = list_alloc();
484   list_nd_t *nd;
485 
486   if (samdump2(buff_sam, hstr, pkey, error, 0, 1, size) == -1) {
487     list_free(hstr);
488     return -3;
489   }
490 
491   for (nd = hstr->head; nd != 0; nd = nd->next) {
492     char *str = (char*)nd->data;
493 
494     if (hash_extract_lmnt(str, hashes, id)) {
495       ++id;
496       ++npwds;
497     }
498   }
499 
500   list_free(hstr);
501 
502 #endif
503 
504   return npwds;
505 
506 }
507 /*-------------------------------------------------------------------------*/
hash_print(hash_t * hsh,FILE * file,int nice,int status,int hide)508 void hash_print(hash_t *hsh, FILE *file, int nice, int status, int hide) {
509   hash_kind_t kind = hsh->kind;
510 
511   /* Find the associated LM and NT hashes. */
512 
513   hash_t *lmhsh1 = 0;
514   hash_t *lmhsh2 = 0;
515   hash_t *nthsh  = 0;
516 
517   switch (kind) {
518   case lm1:
519     lmhsh1 = hsh;
520     lmhsh2 = hsh->lmhsh2;
521     nthsh  = hsh->lmhsh1;
522     break;
523 
524   case lm2:
525     lmhsh1 = hsh->lmhsh1;
526     lmhsh2 = hsh;
527     nthsh  = hsh->lmhsh2;
528     break;
529 
530   case nt:
531     lmhsh1 = hsh->lmhsh1;
532     lmhsh2 = hsh->lmhsh2;
533     nthsh  = hsh;
534     break;
535 
536   default:
537     break;
538   }
539 
540   int uid    = hsh->uid;
541   char *info = hsh->info;
542 
543   /* Print in pwdump format. */
544 
545   if (nice == 0) {
546     /* User name, user id, LM hash and NT hash. */
547 
548     if (info[0]) {
549       if (hide)
550 	fprintf(file, "*****");
551       else
552 	fprintf(file, "%s", info);
553     }
554     fprintf(file, ":");
555 
556     if (uid) fprintf(file, "%d", uid);
557     fprintf(file, ":");
558 
559     if (lmhsh1) fprintf(file, "%s", lmhsh1->str);
560     fprintf(file, ":");
561 
562     if (nthsh) fprintf(file, "%s", nthsh->str);
563     fprintf(file, ":");
564 
565     /* Both LM passwords and the NT password. */
566 
567     if (lmhsh1) {
568       convert_from_colon((uchar_t*)lmhsh1->pwd);
569       fprintf(file, "%s", lmhsh1->pwd);
570       convert_to_colon((uchar_t*)lmhsh1->pwd);
571     }
572 
573     fprintf(file, ":");
574 
575     if (lmhsh2) {
576       convert_from_colon((uchar_t*)lmhsh2->pwd);
577       fprintf(file, "%s", lmhsh2->pwd);
578       convert_to_colon((uchar_t*)lmhsh2->pwd);
579     }
580 
581     fprintf(file, ":");
582 
583     if (nthsh) {
584       convert_from_colon((uchar_t*)nthsh->pwd);
585       fprintf(file, "%s", nthsh->pwd);
586       convert_to_colon((uchar_t*)nthsh->pwd);
587     }
588 
589     if (status) {
590       fprintf(file, ":");
591 
592       /* Status of the search in the tables for the 1st LM hash. */
593 
594       if (lmhsh1) {
595 	list_t *tables = lmhsh1->tables;
596 	list_nd_t *nd;
597 
598 	for (nd = tables->head; nd != 0; nd = nd->next) {
599 	  htbl_t *htbl = nd->data;
600 	  table_t *tbl = htbl->tbl;
601 
602 	  int idx = tbl->idx;
603 	  int covered  = htbl->covered;
604 	  const char *name = table_string(tbl->kind);
605 
606 	  fprintf(file, "%s,%d(%d)", name, idx, covered);
607 	}
608       }
609 
610       /* Status of the search in the tables for the 2nd LM hash. */
611 
612       fprintf(file, ":");
613 
614       if (lmhsh2) {
615 	list_t *tables = lmhsh2->tables;
616 	list_nd_t *nd;
617 
618 	for (nd = tables->head; nd != 0; nd = nd->next) {
619 	  htbl_t *htbl = nd->data;
620 	  table_t *tbl = htbl->tbl;
621 
622 	  int idx = tbl->idx;
623 	  int covered  = htbl->covered;
624 	  const char *name = table_string(tbl->kind);
625 
626 	  fprintf(file, "%s,%d(%d)", name, idx, covered);
627 	}
628       }
629 
630       /* Status of the search in the tables for the NT hash. */
631 
632       fprintf(file, ":");
633 
634       if (nthsh) {
635 	list_t *tables = nthsh->tables;
636 	list_nd_t *nd;
637 
638 	for (nd = tables->head; nd != 0; nd = nd->next) {
639 	  htbl_t *htbl = nd->data;
640 	  table_t *tbl = htbl->tbl;
641 
642 	  int idx = tbl->idx;
643 	  int covered  = htbl->covered;
644 	  const char *name = table_string(tbl->kind);
645 
646 	  fprintf(file, "%s,%d(%d)", name, idx, covered);
647 	}
648       }
649     }
650   }
651 
652   /* Print in a human readable format. */
653 
654   else {
655     if (info[0])
656       if (hide)
657 	fprintf(file, "*****");
658       else
659 	fprintf(file, "%-32s", info);
660     else {
661       if (nthsh)
662 	fprintf(file, "%-32s", nthsh->str);
663       else
664 	if (lmhsh1) fprintf(file, "%-32s", lmhsh1->str);
665     }
666     fprintf(file, " ");
667 
668     if (lmhsh1) {
669       if (lmhsh1->done) {
670 	fprintf(file, "%-7s", lmhsh1->pwd);
671       } else fprintf(file, ".......");
672 
673       if (lmhsh2 && lmhsh2->done) {
674 	fprintf(file, "%-7s", lmhsh2->pwd);
675       } else fprintf(file, ".......");
676     } else fprintf(file, "*** empty *** ");
677 
678     fprintf(file, " ");
679 
680     if (nthsh) {
681       if (nthsh->done) {
682 	fprintf(file, "%s", nthsh->pwd);
683 	if (nthsh->pwd[0] == 0) fprintf(file, "*** empty ***");
684       } else fprintf(file, ".......");
685     } else fprintf(file, "*** empty ***");
686   }
687 
688   fprintf(file, "\n");
689 }
690