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(®ex, pattern, REG_EXTENDED);
113
114 while (regexec(®ex, 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(®ex);
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