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