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