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 <config.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <math.h>
36 #ifdef __NetBSD__
37 #include <sys/param.h>
38 #endif
39 #ifdef WIN32
40 #define WINVER 0x0500
41 #include <windows.h>
42 #else
43 #if HAVE_STRUCT_SYSINFO
44 #include <sys/sysinfo.h>
45 #elif HAVE_SYS_SYSCTL_H
46 #include <sys/types.h>
47 #include <sys/sysctl.h>
48 #endif
49 #endif
50 #ifdef sun
51 #include <kstat.h>
52 #include <unistd.h>
53 #endif
54
55 #include "misc.h"
56 /*-------------------------------------------------------------------------*/
57 #if defined WIN32 || defined sun
strsep(char ** stringp,const char * delim)58 char *strsep(char** stringp, const char* delim) {
59 char *s;
60 const char *spanp;
61 int c, sc;
62 char *tok;
63
64 if ((s = *stringp) == NULL)
65 return (NULL);
66 for (tok = s;;) {
67 c = *s++;
68 spanp = delim;
69 do {
70 if ((sc = *spanp++) == c) {
71 if (c == 0)
72 s = NULL;
73 else
74 s[-1] = 0;
75 *stringp = s;
76 return (tok);
77 }
78 } while (sc != 0);
79 }
80 /* NOTREACHED */
81 }
82 #endif
83 /*-------------------------------------------------------------------------*/
find_freeram(void)84 uint64_t find_freeram(void) {
85 uint64_t freeram = 0;
86
87 #ifdef sun
88 static long pagesize=0;
89 static kstat_ctl_t *kc;
90 static kstat_t *sys_pagesp;
91 static size_t lotsfree;
92 kstat_named_t *kn;
93 size_t freemem;
94
95 if (pagesize == 0) {
96 /* Get the constant values (pagesize and lotsfree) once */
97 pagesize = sysconf(_SC_PAGESIZE);
98 if ((kc=kstat_open()) == 0) {
99 perror("kstat_open");
100 return 0;
101 };
102 if ((sys_pagesp=kstat_lookup(kc, "unix", 0, "system_pages")) == 0) {
103 perror("kstat_lookup(system_pages)");
104 return 0;
105 };
106 if (kstat_read(kc, sys_pagesp, 0) == -1) {
107 perror("kstat_read(syspages)");
108 return 0;
109 };
110 if ((kn=kstat_data_lookup(sys_pagesp, "lotsfree")) == 0) {
111 perror("kstat_data_lookup(lotsfree)");
112 return 0;
113 };
114 lotsfree = kn->value.ul;
115 }
116
117 if (kstat_read(kc, sys_pagesp, 0) == -1) {
118 perror("kstat_read(syspages)");
119 return 0;
120 };
121 if ((kn=kstat_data_lookup(sys_pagesp, "freemem")) == 0) {
122 perror("kstat_data_lookup(freemem)");
123 return 0;
124 };
125 freemem = kn->value.ul;
126 freeram = freemem-lotsfree < 0 ? 0 /* avoid paging */ : pagesize*(freemem-lotsfree);
127 #elif !defined WIN32
128 FILE *file = fopen("/proc/meminfo", "r");
129 char buff[STR_BUFF_SIZE];
130
131 /* Try to find the info we need from /proc/meminfo.
132 * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
133 */
134
135 if (file) {
136 while (1) {
137 char *r = fgets(buff, sizeof(buff), file);
138
139 if (r == NULL) break;
140
141 if (strncmp(buff, "MemFree", 7) == 0) {
142 char *from = strchr(buff, ':');
143 uint64_t mfree = 0;
144
145 sscanf(from+1, "%lu", &mfree);
146 freeram = mfree;
147 }
148 else if (strncmp(buff, "Cached", 6) == 0) {
149 char *from = strchr(buff, ':');
150 uint64_t mcached = 0;
151
152 sscanf(from+1, "%lu", &mcached);
153 freeram += mcached;
154
155 break;
156 }
157 else if (strncmp(buff, "MemAvailable", 12) == 0) {
158 char *from = strchr(buff, ':');
159 sscanf(from+1, "%lu", &freeram);
160 break;
161 }
162 }
163
164 fclose(file);
165 freeram = freeram << 10;
166 }
167
168 /* Otherwise, we try to guess. */
169 else {
170
171 #if HAVE_STRUCT_SYSINFO
172 struct sysinfo info;
173 sysinfo(&info);
174 freeram = (uint64_t)info.freeram;
175 #elif HAVE_SYS_SYSCTL_H
176 int mib[2] = {CTL_HW, HW_USERMEM}, mem;
177 size_t len;
178 len = sizeof(mem);
179 if (sysctl(mib, 2, &mem, &len, NULL, 0) == 0) {
180 freeram = mem;
181 } else {
182 return 0;
183 }
184 #else
185 /* unix system but we don't know how to get available RAM */
186 return 0;
187 #endif
188
189 }
190 #else
191 MEMORYSTATUSEX statex;
192 statex.dwLength = sizeof(statex);
193 GlobalMemoryStatusEx(&statex);
194 uint64_t freephysram = (uint64_t)statex.ullAvailPhys;
195 uint64_t freevirtram = (uint64_t)statex.ullAvailVirtual;
196 freeram = MY_MIN(freephysram, freevirtram);
197 #endif
198
199 /* Take 90% of the available free RAM and return the resulting value
200 in bytes (not kB). */
201 /* Ensure that at least 150M stay free */
202
203 if (freeram < 150*1024*1024)
204 return 0;
205
206 uint64_t ram = MY_MIN(floor(0.9 * freeram),
207 freeram - 150*1024*1024);
208
209 return ram;
210 }
211 /*-------------------------------------------------------------------------*/
convert_to_colon(uchar_t * input)212 void convert_to_colon(uchar_t *input) {
213 uchar_t *tmp;
214
215 for (tmp = input; (*tmp = (*tmp == 193U ? ':' : *tmp)); ++tmp);
216 }
217 /*-------------------------------------------------------------------------*/
convert_from_colon(uchar_t * input)218 void convert_from_colon(uchar_t *input) {
219 uchar_t *tmp;
220
221 for (tmp = input; (*tmp = (*tmp == ':' ? 193U : *tmp)); ++tmp);
222 }
223 /*-------------------------------------------------------------------------*/
wincp1252_to_ascii(uchar_t * str)224 void wincp1252_to_ascii(uchar_t *str) {
225 int len = strlen((char*)str);
226 int i;
227
228 for (i=0; i<len; i++)
229 if (str[i] >= 128)
230 switch (str[i]) {
231 case 0x8e: str[i] = 0xc4; break; // capital a umlaut
232 case 0x99: str[i] = 0xd6; break; // capital o umlaut
233 case 0x9a: str[i] = 0xdc; break; // capital u umlaut
234 case 0xe1: str[i] = 0xdf; break; // double s (sharp/german s)
235 case 0xa5: str[i] = 0xd1; break; // capital n tilda
236 case 0x90: str[i] = 0xc9; break; // capital e accute
237 case 0x80: str[i] = 0xc7; break; // capital c cedilla
238 }
239 }
240 /*-------------------------------------------------------------------------*/
fprintf_hex(FILE * file,char * str,int len)241 void fprintf_hex(FILE *file, char *str, int len) {
242 int i;
243
244 fprintf(file, "0x");
245
246 for (i=0; i<len; ++i)
247 fprintf(file, "%2x", str[i]);
248 }
249 /*-------------------------------------------------------------------------*/
categorize_password(char * pwd)250 int categorize_password(char *pwd) {
251 int i;
252 int category = 0;
253
254 for (i=0; i<strlen(pwd); i++) {
255 if (pwd[i] >= 'a' && pwd[i] <= 'z') category |= 1;
256 else if (pwd[i] >= 'A' && pwd[i] <= 'Z') category |= 2;
257 else if (pwd[i] >= '0' && pwd[i] <= '9') category |= 4;
258 else category |= 8;
259 }
260 return category;
261 }
262 /*-------------------------------------------------------------------------*/
category_string(int category)263 const char *category_string(int category) {
264 switch (category) {
265 case 0: return "empty";
266 case 1: return "lowalpha";
267 case 5: return "lowalphanum";
268 case 2: return "upalpha";
269 case 6: return "upalphanum";
270 case 3: return "mixedalpha";
271 case 7: return "mixedalphanum";
272 case 4: return "num";
273 case 8: return "special";
274 case 9: return "lowalpha+special";
275 case 13: return "lowalphanum+special";
276 case 10: return "upalpha+special";
277 case 14: return "upalphanum+special";
278 case 11: return "mixedalpha+special";
279 case 15: return "mixedalphanum+special";
280 case 12: return "num+special";
281 }
282
283 return "unknown";
284 }
285