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