2 * rcracki_mt is a multithreaded implementation and fork of the original
\r
5 * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
\r
6 * Copyright 2009, 2010 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
10 * This file is part of rcracki_mt.
\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
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
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
25 * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci.
\r
28 #include "HashAlgorithm.h"
\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
40 #if defined(_WIN32) && !defined(__GNUC__)
\r
41 #pragma comment(lib, "libeay32.lib")
\r
48 #define MSCACHE_HASH_SIZE 16
\r
49 void setup_des_key(unsigned char key_56[], des_key_schedule &ks)
\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
62 //des_set_odd_parity(&key);
\r
63 des_set_key(&key, ks);
\r
66 void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
69 unsigned char data[7] = {0};
\r
70 memcpy(data, pPlain, nPlainLen > 7 ? 7 : nPlainLen);
\r
74 for (i = nPlainLen; i < 7; i++)
\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
84 void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\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
92 memset (pass,0,sizeof(pass));
\r
93 memset (pre_lmresp,0,sizeof(pre_lmresp));
\r
95 memcpy (pass,pPlain, nPlainLen);
\r
97 setup_des_key(pass, ks);
\r
98 des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);
\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
103 setup_des_key(pre_lmresp, ks);
\r
104 des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);
\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
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
114 void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\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
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
126 setup_des_key(pre_lmresp, ks);
\r
127 des_ecb_encrypt((des_cblock*)salt, (des_cblock*)pHash, ks, DES_ENCRYPT);
\r
132 void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
134 unsigned char UnicodePlain[MAX_PLAIN_LEN];
\r
135 static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
\r
137 int len = (nPlainLen < 127) ? nPlainLen : 127;
\r
140 for (i = 0; i < len; i++)
\r
142 UnicodePlain[i * 2] = pPlain[i];
\r
143 UnicodePlain[i * 2 + 1] = 0x00;
\r
146 des_key_schedule ks;
\r
147 unsigned char lm[21];
\r
151 MD4_Update(&ctx, UnicodePlain, len * 2);
\r
152 MD4_Final(lm, &ctx); */
\r
153 MD4_NEW(UnicodePlain, len * 2, lm);
\r
155 //MD4(UnicodePlain, len * 2, lm);
\r
156 lm[16] = lm[17] = lm[18] = lm[19] = lm[20] = 0;
\r
158 setup_des_key(lm, ks);
\r
159 des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);
\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
164 setup_des_key(&lm[14], ks);
\r
165 des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);
\r
168 void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
170 char ToEncrypt[256];
\r
172 char username[256];
\r
175 DES_key_schedule ks1,ks2;
\r
176 unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
\r
178 #if defined(_WIN32) && !defined(__GNUC__)
\r
179 strcpy_s(username, sizeof(username), "SYS");
\r
181 strcpy(username, "SYS");
\r
184 #if defined(_WIN32) && !defined(__GNUC__)
\r
185 _strupr((char*) pPlain);
\r
187 strupr((char*) pPlain);
\r
189 memset (ToEncrypt,0,sizeof(ToEncrypt));
\r
191 for (i=1,j=0; j<userlen; i++,j++)
\r
193 ToEncrypt[i] = username[j];
\r
197 for (j=0; j<nPlainLen; i++,j++)
\r
199 ToEncrypt[i] = pPlain[j];
\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
213 void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
215 unsigned char UnicodePlain[MAX_PLAIN_LEN * 2];
\r
217 for (i = 0; i < nPlainLen; i++)
\r
219 UnicodePlain[i * 2] = pPlain[i];
\r
220 UnicodePlain[i * 2 + 1] = 0x00;
\r
223 MD4_NEW(UnicodePlain, nPlainLen * 2, pHash);
\r
227 void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
231 MD2_Update(&ctx, pPlain, nPlainLen);
\r
232 MD2_Final(pHash, &ctx);
\r
234 //MD2(pPlain, nPlainLen, pHash);
\r
238 void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
240 MD4_NEW(pPlain, nPlainLen, pHash);
\r
243 void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
245 fast_MD5(pPlain, nPlainLen, pHash);
\r
247 void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\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
255 void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
259 SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);
\r
260 SHA1_Final(pHash, &ctx);
\r
264 void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
267 RIPEMD160_Init(&ctx);
\r
268 RIPEMD160_Update(&ctx, pPlain, nPlainLen);
\r
269 RIPEMD160_Final(pHash, &ctx);
\r
271 //RIPEMD160(pPlain, nPlainLen, pHash);
\r
275 void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash)
\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
285 // strcpy (username, "administrator");
\r
288 for (i=0; i<nPlainLen; i++)
\r
290 unicode_pwd[i*2] = pPlain[i];
\r
291 unicode_pwd[i*2+1] = 0x00;
\r
294 for (i=0; i<userlen; i++)
\r
296 unicode_user[i*2] = username[i];
\r
297 unicode_user[i*2+1] = 0x00;
\r
300 MD4_NEW( (unsigned char*)unicode_pwd, nPlainLen*2, final1 );
\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
308 unsigned char unicode_pwd[256];
\r
309 for (int i=0; i<nPlainLen; i++)
\r
311 unicode_pwd[i*2] = pPlain[i];
\r
312 unicode_pwd[i*2+1] = 0x00;
\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
324 //*********************************************************************************
\r
325 // Code for MySQL password hashing
\r
326 //*********************************************************************************
\r
328 inline void mysql_hash_password_323(unsigned long *result, const char *password)
\r
330 register unsigned long nr=1345345333L, add=7, nr2=0x12345671L;
\r
332 for (; *password ; password++)
\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
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
345 void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
347 unsigned long hash_pass[2];
\r
348 unsigned char* f = (unsigned char*) hash_pass;
\r
350 unsigned char* pass = (unsigned char*) calloc (nPlainLen+4,sizeof(unsigned char));
\r
351 memcpy(pass,pPlain,nPlainLen);
\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
360 void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\r
362 unsigned char hash_stage1[SHA_DIGEST_LENGTH];
\r
366 SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);
\r
367 SHA1_Final(hash_stage1, &ctx);
\r
369 SHA1_Update(&ctx, hash_stage1, SHA_DIGEST_LENGTH);
\r
370 SHA1_Final(pHash, &ctx);
\r
373 //*********************************************************************************
\r
374 // Code for PIX password hashing
\r
375 //*********************************************************************************
\r
376 static char itoa64[] = /* 0 ... 63 => ascii - 64 */
\r
377 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
\r
379 void _crypt_to64(char *s, unsigned long v, int n)
\r
382 *s++ = itoa64[v&0x3f];
\r
387 void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
\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
393 memcpy (pass,pPlain,nPlainLen);
\r
395 fast_MD5((unsigned char *) pass, MD5_DIGEST_LENGTH, final);
\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
404 memcpy(pHash,temp,MD5_DIGEST_LENGTH);
\r
409 #if !defined(_WIN32) || defined(__GNUC__)
\r
410 char *strupr(char *s1)
\r
415 *p = (char) toupper(*p);
\r