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 <string.h>
33 #include <ctype.h>
34 
35 #include "ntseven.h"
36 #include "table.h"
37 #include "hash.h"
38 #include "ophel.h"
39 #include "original.h"
40 #include "lmtable.h"
41 /*-------------------------------------------------------------------------*/
ntseven_setup(void * tbl_)42 int ntseven_setup(void *tbl_) {
43   table_t *tbl = tbl_;
44 
45   tbl->ncols  = 50000;
46   tbl->offset = 100000;
47   tbl->sizes  = ntseven_sizes;
48 
49   tbl->find    = ntseven_find;
50   tbl->check   = ntseven_check;
51   tbl->isvalid = ntseven_isvalid;
52 
53   tbl->lookup_idx = lmtable_lookup_idx;
54   tbl->lookup_end = lmtable_lookup_end;
55   tbl->lookup_srt = ntseven_lookup_srt;
56 
57   return 1;
58 }
59 /*-------------------------------------------------------------------------*/
ntseven_find(void * hsh_,void * tbl_,void * el_)60 void ntseven_find(void *hsh_, void *tbl_, void *el_) {
61   hash_t  *hsh  = hsh_;
62   table_t *tbl  = tbl_;
63   ophel_t *el   = el_;
64   uchar_t *hash = hsh->hash;
65   uchar_t *pwd  = (uchar_t*)el->pwd;
66   ophstat_t *stat = el->stat;
67 
68   int c;
69   int col     = el->col;
70   int ncols   = tbl->ncols;
71   int n_redux = col + tbl->idx * tbl->offset;
72 
73   uchar_t tmp[16];
74 
75   /* Hash and redux until the last column. */
76 
77   ntseven_mkredux(tbl, hash, pwd, n_redux);
78 
79   for (c=1; c<ncols-col; ++c) {
80     ++n_redux;
81 
82     ntseven_mkhash(pwd, tmp);
83     ntseven_mkredux(tbl, tmp, pwd, n_redux);
84     ++stat->hredux;
85   }
86 
87   /* Compute the prefix and postfix. */
88 
89   uint64_t binary  = ntseven_bin95(pwd, 7);
90   uint32_t prefix  = (uint32_t)(binary >> 23);
91   uint16_t postfix = (uint16_t)(binary & 0xffff);
92 
93   el->prefix  = prefix;
94   el->postfix = postfix;
95 }
96 /*-------------------------------------------------------------------------*/
ntseven_lookup_srt(void * hsh_,void * tbl_,void * el_)97 int ntseven_lookup_srt(void *hsh_, void *tbl_, void *el_) {
98   table_t *tbl = tbl_;
99   ophel_t *el  = el_;
100 
101   uint64_t offset = el->offset;
102   uint32_t start;
103 
104   ophstat_t *stat = el->stat;
105   ++stat->start;
106 
107   /* If the .start file has been preloaded, then we look into the memory. */
108 
109   if (tbl->srtmem) {
110     uint32_t *mem = (uint32_t*)(tbl->srtmem + offset);
111     start = mem[0];
112   }
113 
114   /* Otherwise, we access the disk. */
115 
116   else {
117     FILE *srtfile = tbl->srtfile;
118 
119     fseeko(srtfile, offset, SEEK_SET);
120     fread(&start, sizeof(start), 1, srtfile);
121     ++stat->fseek_srt;
122   }
123 
124   /* Make sure that start is in the correct byte order. */
125 
126   start = ftohl(start);
127 
128   /* Convert it to a valid password. */
129 
130   uchar_t *pwd = (uchar_t*)el->pwd;
131 
132   pwd[5] = 0;
133   pwd[6] = 0;
134   pwd[7] = 0;
135   pwd[8] = 0;
136 
137   ntseven_unbin95(start, pwd, 5);
138 
139   return 1;
140 }
141 /*-------------------------------------------------------------------------*/
ntseven_check(void * hsh_,void * tbl_,void * el_)142 int ntseven_check(void *hsh_, void *tbl_, void *el_) {
143   hash_t *hsh   = hsh_;
144   table_t *tbl  = tbl_;
145   ophel_t *el   = el_;
146   uchar_t *hash = hsh->hash;
147   uchar_t *pwd  = (uchar_t*)el->pwd;
148   ophstat_t *stat = el->stat;
149 
150   int c;
151   int col     = el->col;
152   int ncols   = tbl->ncols;
153   int n_redux = tbl->idx * tbl->offset;
154 
155   uchar_t tmp[16];
156 
157   /* Hash and redux until the starting column. */
158 
159   stat->falarm_hredux = 0;
160 
161   for (c=ncols-col; c<ncols; ++c) {
162     ntseven_mkhash(pwd, tmp);
163     ntseven_mkredux(tbl, tmp, pwd, n_redux);
164 
165     ++n_redux;
166     ++stat->hredux;
167     ++stat->falarm_hredux;
168   }
169 
170   /* Check if we got the same hash. */
171 
172   ntseven_mkhash(pwd, tmp);
173 
174   if (memcmp(tmp, hash, sizeof(tmp)) == 0) {
175     ++stat->match_table;
176     stat->falarm_hredux = 0;
177     return 1;
178   }
179 
180   else {
181     ++stat->falarm;
182     return 0;
183   }
184 }
185 /*-------------------------------------------------------------------------*/
ntseven_isvalid(void * hsh_,void * tbl_)186 int ntseven_isvalid(void *hsh_, void *tbl_) {
187   hash_t *hsh = hsh_;
188 
189   return hsh->kind == nt ? 1 : 0;
190 }
191 /*-------------------------------------------------------------------------*/
ntseven_mkredux(table_t * tbl,uchar_t * hash,uchar_t * pwd,int n_redux)192 void ntseven_mkredux(table_t *tbl, uchar_t *hash, uchar_t *pwd,
193 			int n_redux) {
194 
195   /* Convert the hash to four unsigned 32-bit integers. */
196 
197   uint32_t idx[4];
198 
199   idx[0] = ftohl(*(uint32_t*)hash) ^ n_redux;
200   idx[1] = ftohl(*(uint32_t*)(hash+4));
201   idx[2] = ftohl(*(uint32_t*)(hash+8));
202   idx[3] = ftohl(*(uint32_t*)(hash+12));
203 
204   /* Compute the password */
205 
206   idx[0] %= power2_95;
207   idx[1] %= power2_95;
208   idx[2] %= power2_95;
209   idx[3] %= power2_95;
210 
211   pwd[0] = ntseven_ext95[idx[0]/95];
212   pwd[1] = ntseven_ext95[idx[0]%95];
213   pwd[2] = ntseven_ext95[idx[1]/95];
214   pwd[3] = ntseven_ext95[idx[1]%95];
215   pwd[4] = ntseven_ext95[idx[2]/95];
216   pwd[5] = ntseven_ext95[idx[2]%95];
217   pwd[6] = ntseven_ext95[idx[3]/95];
218 
219   /* Finish the password. */
220 
221   pwd[7] = 0;
222 
223 }
224 /*-------------------------------------------------------------------------*/
ntseven_mkhash(uchar_t * pwd,uchar_t * hash)225 void ntseven_mkhash(uchar_t *pwd, uchar_t *hash) {
226   make_nthash((char*)pwd, (char*)hash);
227 }
228 /*-------------------------------------------------------------------------*/
ntseven_bin95(uchar_t * input,int length)229 uint64_t ntseven_bin95(uchar_t *input, int length) {
230 
231   uint64_t sum=0;
232   int i = 0;
233 
234   for (i=0; i<length; i++)  {
235     sum = sum*95 + (uint64_t) (strchr((char*)ntseven_ext95,input[i]) - (char*)ntseven_ext95);
236   }
237   return sum;
238 }
239 /*-------------------------------------------------------------------------*/
ntseven_unbin95(uint32_t input,uchar_t * output,int length)240 int ntseven_unbin95(uint32_t input, uchar_t *output, int length) {
241 
242   int i = 0;
243 
244   for (i=length-1; i>=0; i--) {
245     output[i]=ntseven_ext95[input%95];
246     input/=95;
247   }
248   return 1;
249 }
250