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