]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/HashAlgorithm.cpp
remove old deprecated rcracki
[freerainbowtables] / Client Applications / rcracki_mt / HashAlgorithm.cpp
1 /*\r
2  * rcracki_mt is a multithreaded implementation and fork of the original \r
3  * RainbowCrack\r
4  *\r
5  * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
6  * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
7  * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
8  * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
9  *\r
10  * This file is part of racrcki_mt.\r
11  *\r
12  * rcracki_mt is free software: you can redistribute it and/or modify\r
13  * it under the terms of the GNU General Public License as published by\r
14  * the Free Software Foundation, either version 2 of the License, or\r
15  * (at your option) any later version.\r
16  *\r
17  * rcracki_mt is distributed in the hope that it will be useful,\r
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
20  * GNU General Public License for more details.\r
21  *\r
22  * You should have received a copy of the GNU General Public License\r
23  * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
24  *\r
25  * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci.\r
26  */\r
27 \r
28 #include "HashAlgorithm.h"\r
29 \r
30 #include "Public.h"\r
31 \r
32 #include <openssl/des.h>\r
33 //#include <openssl/md2.h>\r
34 #include <openssl/md4.h>\r
35 //#include <openssl/md5.h>\r
36 #include <openssl/sha.h>\r
37 //#include <openssl/ripemd.h>\r
38 #include "fast_md5.h"\r
39 #include "md4.h"\r
40 //#include "sha1.h"\r
41 #ifdef _WIN32\r
42         #pragma comment(lib, "libeay32.lib")\r
43 #endif\r
44 \r
45 #ifdef __NetBSD__\r
46         #include <des.h>\r
47 #endif\r
48 \r
49 #define MSCACHE_HASH_SIZE 16\r
50 void setup_des_key(unsigned char key_56[], des_key_schedule &ks)\r
51 {\r
52         des_cblock key;\r
53 \r
54         key[0] = key_56[0];\r
55         key[1] = (key_56[0] << 7) | (key_56[1] >> 1);\r
56         key[2] = (key_56[1] << 6) | (key_56[2] >> 2);\r
57         key[3] = (key_56[2] << 5) | (key_56[3] >> 3);\r
58         key[4] = (key_56[3] << 4) | (key_56[4] >> 4);\r
59         key[5] = (key_56[4] << 3) | (key_56[5] >> 5);\r
60         key[6] = (key_56[5] << 2) | (key_56[6] >> 6);\r
61         key[7] = (key_56[6] << 1);\r
62 \r
63         //des_set_odd_parity(&key);\r
64         des_set_key(&key, ks);\r
65 }\r
66 \r
67 void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
68 {\r
69         /*\r
70         unsigned char data[7] = {0};\r
71         memcpy(data, pPlain, nPlainLen > 7 ? 7 : nPlainLen);\r
72         */\r
73 \r
74         int i;\r
75         for (i = nPlainLen; i < 7; i++)\r
76                 pPlain[i] = 0;\r
77 \r
78         static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
79         des_key_schedule ks;\r
80         //setup_des_key(data, ks);\r
81         setup_des_key(pPlain, ks);\r
82         des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
83 }\r
84 \r
85 void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
86 {\r
87         unsigned char pass[14];\r
88         unsigned char pre_lmresp[21];\r
89         static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
90         static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; \r
91         des_key_schedule ks;\r
92 \r
93         memset (pass,0,sizeof(pass));\r
94         memset (pre_lmresp,0,sizeof(pre_lmresp));\r
95 \r
96         memcpy (pass,pPlain, nPlainLen);\r
97 \r
98         setup_des_key(pass, ks);\r
99         des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);\r
100 \r
101         setup_des_key(&pass[7], ks);\r
102         des_ecb_encrypt((des_cblock*)magic, (des_cblock*)&pre_lmresp[8], ks, DES_ENCRYPT);\r
103 \r
104         setup_des_key(pre_lmresp, ks);\r
105         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
106 \r
107         setup_des_key(&pre_lmresp[7], ks);\r
108         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);\r
109 \r
110         setup_des_key(&pre_lmresp[14], ks);\r
111         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);\r
112 \r
113\r
114 \r
115 void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
116 {       \r
117         unsigned char pre_lmresp[8];\r
118         static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
119         static unsigned char salt[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};\r
120 \r
121         des_key_schedule ks;\r
122         unsigned char plain[8] = {0};   \r
123         memcpy(plain, pPlain, nPlainLen);\r
124         setup_des_key(plain, ks);\r
125         des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);\r
126 \r
127         setup_des_key(pre_lmresp, ks);\r
128         des_ecb_encrypt((des_cblock*)salt, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
129\r
130 \r
131 \r
132 \r
133 void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
134 {\r
135         unsigned char UnicodePlain[MAX_PLAIN_LEN];\r
136         static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; \r
137         \r
138         int len = (nPlainLen < 127) ? nPlainLen : 127;\r
139         int i;\r
140         \r
141         for (i = 0; i < len; i++)\r
142         {\r
143         UnicodePlain[i * 2] = pPlain[i];\r
144         UnicodePlain[i * 2 + 1] = 0x00;\r
145         }\r
146         \r
147         des_key_schedule ks;\r
148         unsigned char lm[21];\r
149         \r
150         /*MD4_CTX ctx;\r
151         MD4_Init(&ctx);\r
152         MD4_Update(&ctx, UnicodePlain, len * 2);\r
153         MD4_Final(lm, &ctx);  */\r
154         MD4_NEW(UnicodePlain, len * 2, lm);\r
155         \r
156         //MD4(UnicodePlain, len * 2, lm);\r
157         lm[16] = lm[17] = lm[18] = lm[19] = lm[20] = 0;\r
158         \r
159         setup_des_key(lm, ks);\r
160         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
161         \r
162         setup_des_key(&lm[7], ks);\r
163         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);\r
164         \r
165         setup_des_key(&lm[14], ks);\r
166         des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);\r
167 }\r
168 \r
169 \r
170 void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
171 {\r
172         char ToEncrypt[256];\r
173         char temp[256];\r
174         char username[256];\r
175 \r
176         DES_cblock iv,iv2;\r
177         DES_key_schedule ks1,ks2;\r
178         unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};\r
179         int i,j;\r
180 \r
181         strcpy (username, "SYS");\r
182         int userlen = 3;\r
183         \r
184         strupr ((char*) pPlain);\r
185         memset (ToEncrypt,0,sizeof(ToEncrypt));\r
186 \r
187         for (i=1,j=0; j<userlen; i++,j++)\r
188         {\r
189                 ToEncrypt[i] = username[j];\r
190                 i++;\r
191         }\r
192 \r
193         for (j=0; j<nPlainLen; i++,j++)\r
194         {\r
195                 ToEncrypt[i] = pPlain[j];\r
196                 i++;\r
197         }\r
198 \r
199         i=i-1;\r
200         memset (iv,0,8);\r
201         memset (iv2,0,8);\r
202         DES_set_key((DES_cblock*) deskey_fixed, &ks1);\r
203         DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks1, &iv, DES_ENCRYPT);\r
204         DES_set_key((DES_cblock*) &iv, &ks2);\r
205         DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks2, &iv2, DES_ENCRYPT);\r
206         memcpy (pHash,iv2,8);\r
207 }\r
208 \r
209 void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
210 {\r
211         unsigned char UnicodePlain[MAX_PLAIN_LEN * 2];\r
212         int i;\r
213         for (i = 0; i < nPlainLen; i++)\r
214         {\r
215                 UnicodePlain[i * 2] = pPlain[i];\r
216                 UnicodePlain[i * 2 + 1] = 0x00;\r
217         }\r
218 \r
219         /*MD4_CTX ctx;\r
220         MD4_Init(&ctx);\r
221         MD4_Update(&ctx, UnicodePlain, nPlainLen * 2);\r
222         MD4_Final(pHash, &ctx);*/\r
223 \r
224         //MD4(UnicodePlain, nPlainLen * 2, pHash);\r
225         MD4_NEW(UnicodePlain, nPlainLen * 2, pHash);\r
226 }\r
227 \r
228 /*\r
229 void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
230 {\r
231         MD2_CTX ctx;\r
232         MD2_Init(&ctx);\r
233         MD2_Update(&ctx, pPlain, nPlainLen);\r
234         MD2_Final(pHash, &ctx);\r
235 \r
236         //MD2(pPlain, nPlainLen, pHash);\r
237 }\r
238 */\r
239 \r
240 void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
241 {\r
242         /*MD4_CTX ctx;\r
243         MD4_Init(&ctx);\r
244         MD4_Update(&ctx, pPlain, nPlainLen);\r
245         MD4_Final(pHash, &ctx);*/\r
246 \r
247         MD4_NEW(pPlain, nPlainLen, pHash);\r
248         //MD4(pPlain, nPlainLen, pHash);\r
249 }\r
250 \r
251 void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
252 {\r
253         fast_MD5(pPlain, nPlainLen, pHash);\r
254 }\r
255 void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
256 {\r
257         fast_MD5(pPlain, nPlainLen, pHash);\r
258         unsigned char hash[16];\r
259         memcpy(hash, pHash, 16);\r
260         fast_MD5(hash, 16, pHash);\r
261 }\r
262 \r
263 void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
264 {\r
265         SHA_CTX ctx;\r
266         SHA1_Init(&ctx);\r
267         SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);\r
268         SHA1_Final(pHash, &ctx);\r
269 }\r
270 \r
271 /*\r
272 void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
273 {\r
274         RIPEMD160_CTX ctx;\r
275         RIPEMD160_Init(&ctx);\r
276         RIPEMD160_Update(&ctx, pPlain, nPlainLen);\r
277         RIPEMD160_Final(pHash, &ctx);  \r
278 \r
279         //RIPEMD160(pPlain, nPlainLen, pHash);\r
280 }\r
281 */\r
282 \r
283 void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash)\r
284 {\r
285         char unicode_pwd[256];\r
286         char unicode_user[256];\r
287         static unsigned char username[] = "administrator";\r
288         static int userlen = 13;\r
289         unsigned char   final1[MD4_DIGEST_LENGTH];\r
290         MD4_CTX ctx;\r
291         int i;\r
292 \r
293 //      strcpy (username, "administrator");\r
294 //      userlen = 13;\r
295 \r
296         for (i=0; i<nPlainLen; i++)\r
297         {\r
298                 unicode_pwd[i*2] = pPlain[i];\r
299                 unicode_pwd[i*2+1] = 0x00;\r
300         }\r
301 \r
302         for (i=0; i<userlen; i++)\r
303         {\r
304                 unicode_user[i*2] = username[i];\r
305                 unicode_user[i*2+1] = 0x00;\r
306         }\r
307         /*\r
308         MD4_Init(&ctx);\r
309         MD4_Update(&ctx,unicode_pwd,nPlainLen*2);\r
310         MD4_Final(final1,&ctx);\r
311         */\r
312         MD4_NEW( (unsigned char*)unicode_pwd, nPlainLen*2, final1 );\r
313 \r
314         MD4_Init(&ctx);\r
315         MD4_Update(&ctx,final1,MD4_DIGEST_LENGTH);\r
316         MD4_Update(&ctx,(unsigned char*) unicode_user,userlen*2);\r
317         MD4_Final(pHash,&ctx);\r
318 \r
319         /*\r
320         unsigned char unicode_pwd[256];\r
321         for (int i=0; i<nPlainLen; i++)\r
322         {\r
323                 unicode_pwd[i*2] = pPlain[i];\r
324                 unicode_pwd[i*2+1] = 0x00;\r
325         }*/     \r
326         /*\r
327         unsigned char *buf = (unsigned char*)calloc(MSCACHE_HASH_SIZE + nSaltLength, sizeof(unsigned char));    \r
328         HashNTLM(pPlain, nPlainLen, buf, NULL);\r
329         //MD4(unicode_pwd, nPlainLen*2, buf);\r
330         memcpy(buf + MSCACHE_HASH_SIZE, pSalt, nSaltLength);\r
331         MD4(buf, MSCACHE_HASH_SIZE + nSaltLength, pHash); \r
332         free(buf);\r
333         */\r
334 }\r
335 \r
336 //*********************************************************************************\r
337 // Code for MySQL password hashing\r
338 //*********************************************************************************\r
339 \r
340 inline void mysql_hash_password_323(unsigned long *result, const char *password) \r
341 {\r
342         register unsigned long nr=1345345333L, add=7, nr2=0x12345671L;\r
343         unsigned long tmp;\r
344         for (; *password ; password++) \r
345         {\r
346                 if (*password == ' ' || *password == '\t') continue;\r
347                 tmp= (unsigned long) (unsigned char) *password;\r
348                 nr^= (((nr & 63)+add)*tmp)+ (nr << 8);\r
349                 nr2+=(nr2 << 8) ^ nr;\r
350                 add+=tmp;\r
351         }\r
352         result[0]=nr & (((unsigned long) 1L << 31) -1L); /* Don't use sign bit (str2int) */;\r
353         result[1]=nr2 & (((unsigned long) 1L << 31) -1L);\r
354         return;\r
355 }\r
356 \r
357 void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
358 {\r
359         unsigned long hash_pass[2];     \r
360         unsigned char* f = (unsigned char*) hash_pass;\r
361 \r
362         unsigned char* pass = (unsigned char*) calloc (nPlainLen+4,sizeof(unsigned char));\r
363         memcpy(pass,pPlain,nPlainLen);\r
364 \r
365         mysql_hash_password_323(hash_pass, (char*) pass);\r
366         pHash[0]=*(f+3); pHash[1]=*(f+2); pHash[2]=*(f+1); pHash[3]=*(f+0);\r
367         pHash[4]=*(f+7); pHash[5]=*(f+6); pHash[6]=*(f+5); pHash[7]=*(f+4);\r
368 \r
369         free (pass);\r
370 }\r
371 \r
372 void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
373 {\r
374         unsigned char hash_stage1[SHA_DIGEST_LENGTH];\r
375         SHA_CTX ctx;\r
376 \r
377         SHA1_Init(&ctx);\r
378         SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);\r
379         SHA1_Final(hash_stage1, &ctx);\r
380         SHA1_Init(&ctx);\r
381         SHA1_Update(&ctx, hash_stage1, SHA_DIGEST_LENGTH);\r
382         SHA1_Final(pHash, &ctx);\r
383 }\r
384 \r
385 //*********************************************************************************\r
386 // Code for PIX password hashing\r
387 //*********************************************************************************\r
388 static char itoa64[] =          /* 0 ... 63 => ascii - 64 */\r
389         "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";\r
390 \r
391 void _crypt_to64(char *s, unsigned long v, int n)\r
392 {\r
393         while (--n >= 0) {\r
394                 *s++ = itoa64[v&0x3f];\r
395                 v >>= 6;\r
396         }\r
397 }\r
398 \r
399 void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
400 {\r
401         char temp[MD5_DIGEST_LENGTH+1];\r
402         unsigned char final[MD5_DIGEST_LENGTH];\r
403         char* pass = (char*) calloc (nPlainLen+MD5_DIGEST_LENGTH,sizeof(char));\r
404 \r
405         memcpy (pass,pPlain,nPlainLen);\r
406 \r
407         /*MD5_CTX ctx;\r
408         MD5_Init(&ctx);\r
409         MD5_Update(&ctx, (unsigned char *) pass, MD5_DIGEST_LENGTH);\r
410         MD5_Final(final, &ctx);*/\r
411         fast_MD5((unsigned char *) pass, MD5_DIGEST_LENGTH, final);\r
412 \r
413         char* p = (char*) temp;\r
414         _crypt_to64(p,*(unsigned long*) (final+0),4); p += 4;\r
415         _crypt_to64(p,*(unsigned long*) (final+4),4); p += 4;\r
416         _crypt_to64(p,*(unsigned long*) (final+8),4); p += 4;\r
417         _crypt_to64(p,*(unsigned long*) (final+12),4); p += 4;\r
418         *p=0;\r
419 \r
420         memcpy(pHash,temp,MD5_DIGEST_LENGTH);\r
421 \r
422         free (pass);\r
423 }\r
424 \r
425 #if !defined(_WIN32) || defined(__GNUC__)\r
426 char *strupr(char *s1)\r
427 {\r
428         char *p = s1;\r
429         while(*p)\r
430         {\r
431                 *p = (char) toupper(*p);\r
432                 p++;\r
433         }\r
434         return s1;\r
435 }\r
436 #endif\r