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