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