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 #include <assert.h>
35
36 #include "nteightxl.h"
37 #include "table.h"
38 #include "hash.h"
39 #include "ophel.h"
40 #include "original.h"
41 #include "lmtable.h"
42 /*-------------------------------------------------------------------------*/
nteightxl_setup(void * tbl_)43 int nteightxl_setup(void *tbl_) {
44 table_t *tbl = tbl_;
45
46 tbl->ncols = 100000;
47 tbl->offset = 1000000;
48 tbl->sizes = nteightxl_sizes;
49
50 tbl->find = nteightxl_find;
51 tbl->check = nteightxl_check;
52 tbl->isvalid = nteightxl_isvalid;
53
54 tbl->lookup_idx = nteightxl_lookup_idx;
55 tbl->lookup_end = nteightxl_lookup_end;
56 tbl->lookup_srt = nteightxl_lookup_srt;
57
58 return 1;
59 }
60 /*-------------------------------------------------------------------------*/
nteightxl_find(void * hsh_,void * tbl_,void * el_)61 void nteightxl_find(void *hsh_, void *tbl_, void *el_) {
62 hash_t *hsh = hsh_;
63 table_t *tbl = tbl_;
64 ophel_t *el = el_;
65 uchar_t *hash = hsh->hash;
66 uchar_t *pwd = (uchar_t*)el->pwd;
67 ophstat_t *stat = el->stat;
68
69 int c;
70 int col = el->col;
71 int ncols = tbl->ncols;
72 int n_redux = col + tbl->idx * tbl->offset;
73
74 uchar_t tmp[16];
75
76 /* Hash and redux until the last column. */
77
78 nteightxl_mkredux(tbl, hash, pwd, n_redux);
79
80 for (c=1; c<ncols-col; ++c) {
81 ++n_redux;
82
83 nteightxl_mkhash(pwd, tmp);
84 nteightxl_mkredux(tbl, tmp, pwd, n_redux);
85 ++stat->hredux;
86 }
87
88 /* Compute the prefix and postfix. */
89
90 uint64_t binary = nteightxl_bin95(pwd, 8);
91 uint32_t prefix = (uint32_t)(binary >> 23);
92 uint16_t postfix = (uint16_t)(binary & 0xffff);
93
94 el->prefix = prefix;
95 el->postfix = postfix;
96 }
97 /*-------------------------------------------------------------------------*/
nteightxl_lookup_idx(void * hsh_,void * tbl_,void * el_)98 int nteightxl_lookup_idx(void *hsh_, void *tbl_, void *el_) {
99 table_t *tbl = tbl_;
100 ophel_t *el = el_;
101
102 uint32_t prefix = el->prefix;
103
104 ophstat_t *stat = el->stat;
105 ++stat->prefix;
106
107 el->low = 0;
108 el->high = 0;
109
110 /* If the .index file has been preloaded, then we look into the memory. */
111
112 if (tbl->idxmem) {
113 uchar_t *mem = (uchar_t*)(tbl->idxmem + 5*prefix);
114
115 memcpy(&(el->low), mem, 5);
116 memcpy(&(el->high), mem + 5, 5);
117 }
118
119 /* Otherwise, we access the disk. */
120
121 else {
122 FILE *idxfile = tbl->idxfile;
123
124 fseeko(idxfile, 5*prefix, SEEK_SET);
125 fread(&el->low, 5, 1, idxfile);
126 fread(&el->high, 5, 1, idxfile);
127 ++stat->fseek_idx;
128 }
129
130 /* Make sure that the bytes are in the correct order. */
131
132 el->low = ftohl64(el->low);
133 el->high = ftohl64(el->high);
134
135 assert(el->high >= el->low);
136
137 return 1;
138 }
139 /*-------------------------------------------------------------------------*/
nteightxl_lookup_end(void * hsh_,void * tbl_,void * el_)140 int nteightxl_lookup_end(void *hsh_, void *tbl_, void *el_) {
141 table_t *tbl = tbl_;
142 ophel_t *el = el_;
143 ophstat_t *stat = el->stat;
144
145 uint16_t postfix = el->postfix;
146 uint64_t low = el->low;
147 uint64_t high = el->high;
148 uint64_t n = high - low;
149 uint64_t i;
150 uint64_t offset = 2*low;
151
152 /* If the .bin file has been preloaded, then we look into the memory. */
153
154 if (tbl->endmem) {
155 uint16_t *mem = (uint16_t*)(tbl->endmem + offset);
156
157 for (i=0; i<n; ++i)
158 if (ftohs(mem[i]) == postfix) break;
159
160 }
161
162 /* Otherwise, we access the disk. */
163
164 else {
165 uint16_t pfix[512];
166 FILE *endfile = tbl->endfile;
167
168 fseeko(endfile, offset, SEEK_SET);
169 fread(pfix, sizeof(uint16_t), n, endfile);
170 ++stat->fseek_end;
171
172 for (i=0; i<n; ++i)
173 if (ftohs(pfix[i]) == postfix) break;
174
175 }
176
177 el->offset = 5 * (low+i);
178
179
180 if (i < n) ++stat->postfix;
181
182 return i == n ? 0 : 1;
183 }
184 /*-------------------------------------------------------------------------*/
nteightxl_lookup_srt(void * hsh_,void * tbl_,void * el_)185 int nteightxl_lookup_srt(void *hsh_, void *tbl_, void *el_) {
186 table_t *tbl = tbl_;
187 ophel_t *el = el_;
188
189 uint64_t offset = el->offset;
190 uint64_t start;
191
192 ophstat_t *stat = el->stat;
193 ++stat->start;
194
195 start = 0;
196
197 /* If the .start file has been preloaded, then we look into the memory. */
198
199 if (tbl->srtmem) {
200 uchar_t *mem = (uchar_t*)(tbl->srtmem + offset);
201
202 memcpy(&start, mem, 5);
203 }
204
205 /* Otherwise, we access the disk. */
206
207 else {
208 FILE *srtfile = tbl->srtfile;
209
210 fseeko(srtfile, offset, SEEK_SET);
211 fread(&start, 5, 1, srtfile);
212 ++stat->fseek_srt;
213 }
214
215 /* Make sure that start is in the correct byte order. */
216
217 start = ftohl64(start);
218
219 /* Convert it to a valid password. */
220
221 uchar_t *pwd = (uchar_t*)el->pwd;
222
223 pwd[6] = 0;
224 pwd[7] = 0;
225 pwd[8] = 0;
226 pwd[9] = 0;
227
228 nteightxl_unbin95(start, pwd, 6);
229
230 return 1;
231 }
232 /*-------------------------------------------------------------------------*/
nteightxl_check(void * hsh_,void * tbl_,void * el_)233 int nteightxl_check(void *hsh_, void *tbl_, void *el_) {
234 hash_t *hsh = hsh_;
235 table_t *tbl = tbl_;
236 ophel_t *el = el_;
237 uchar_t *hash = hsh->hash;
238 uchar_t *pwd = (uchar_t*)el->pwd;
239 ophstat_t *stat = el->stat;
240
241 int c;
242 int col = el->col;
243 int ncols = tbl->ncols;
244 int n_redux = tbl->idx * tbl->offset;
245
246 uchar_t tmp[16];
247
248 /* Hash and redux until the starting column. */
249
250 stat->falarm_hredux = 0;
251
252 for (c=ncols-col; c<ncols; ++c) {
253 nteightxl_mkhash(pwd, tmp);
254 nteightxl_mkredux(tbl, tmp, pwd, n_redux);
255
256 ++n_redux;
257 ++stat->hredux;
258 ++stat->falarm_hredux;
259 }
260
261 /* Check if we got the same hash. */
262
263 nteightxl_mkhash(pwd, tmp);
264
265 if (memcmp(tmp, hash, sizeof(tmp)) == 0) {
266 ++stat->match_table;
267 stat->falarm_hredux = 0;
268 return 1;
269 }
270
271 else {
272 ++stat->falarm;
273 return 0;
274 }
275 }
276 /*-------------------------------------------------------------------------*/
nteightxl_isvalid(void * hsh_,void * tbl_)277 int nteightxl_isvalid(void *hsh_, void *tbl_) {
278 hash_t *hsh = hsh_;
279
280 return hsh->kind == nt ? 1 : 0;
281 }
282 /*-------------------------------------------------------------------------*/
nteightxl_mkredux(table_t * tbl,uchar_t * hash,uchar_t * pwd,int n_redux)283 void nteightxl_mkredux(table_t *tbl, uchar_t *hash, uchar_t *pwd,
284 int n_redux) {
285
286 /* Convert the hash to four unsigned 32-bit integers. */
287
288 uint32_t idx[4];
289
290 idx[0] = ftohl(*(uint32_t*)hash) ^ n_redux;
291 idx[1] = ftohl(*(uint32_t*)(hash+4));
292 idx[2] = ftohl(*(uint32_t*)(hash+8));
293 idx[3] = ftohl(*(uint32_t*)(hash+12));
294
295 /* Compute the password */
296
297 idx[0] %= 9025;
298 idx[1] %= 9025;
299 idx[2] %= 9025;
300 idx[3] %= 9025;
301
302 pwd[0] = nteightxl_ext95[idx[0]/95];
303 pwd[1] = nteightxl_ext95[idx[0]%95];
304 pwd[2] = nteightxl_ext95[idx[1]/95];
305 pwd[3] = nteightxl_ext95[idx[1]%95];
306 pwd[4] = nteightxl_ext95[idx[2]/95];
307 pwd[5] = nteightxl_ext95[idx[2]%95];
308 pwd[6] = nteightxl_ext95[idx[3]/95];
309 pwd[7] = nteightxl_ext95[idx[3]%95];
310 pwd[8] = 0;
311
312 }
313 /*-------------------------------------------------------------------------*/
nteightxl_mkhash(uchar_t * pwd,uchar_t * hash)314 void nteightxl_mkhash(uchar_t *pwd, uchar_t *hash) {
315 make_nthash((char*)pwd, (char*)hash);
316 }
317 /*-------------------------------------------------------------------------*/
nteightxl_bin95(uchar_t * input,int length)318 uint64_t nteightxl_bin95(uchar_t *input, int length) {
319
320 uint64_t sum=0;
321 int i = 0;
322
323 for (i=0; i<length; i++) {
324 sum = sum*95 + (uint64_t) (strchr((char*)nteightxl_ext95,input[i]) - (char*)nteightxl_ext95);
325 }
326 return sum;
327 }
328 /*-------------------------------------------------------------------------*/
nteightxl_unbin95(uint64_t input,uchar_t * output,int length)329 int nteightxl_unbin95(uint64_t input, uchar_t *output, int length) {
330
331 int i = 0;
332
333 for (i=0; i<length; i++) {
334 output[i]=nteightxl_ext95[input%95];
335 input/=95;
336 }
337 return 1;
338 }
339