Add hashcat command lines
[pwdhash.git] / salted.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <time.h>
4 #include <string.h>
5 #include <stdbool.h>
6
7 #include "md5-cl.h"
8 #include "b64-cl.h"
9
10 #include "hmacmd5.h"
11
12 #define SALT_MAX (5)
13 #define PASS_MAX (32)
14
15 //void mangle(char * password)
16 u32x mangle_md5 (u32x w0[4], u32x w1[4], const u32x in_len)
17 {
18 u32x out_len = in_len;
19 u32 i;
20
21 u32x digest[4];
22 u32x w0_t[4];
23 u32x w1_t[4];
24 u32x w2_t[4];
25 u32x w3_t[4];
26
27 append_0x80_2x4_VV (w0, w1, out_len);
28
29 w0_t[0] = w0[0];
30 w0_t[1] = w0[1];
31 w0_t[2] = w0[2];
32 w0_t[3] = w0[3];
33 w1_t[0] = w1[0];
34 w1_t[1] = w1[1];
35 w1_t[2] = w1[2];
36 w1_t[3] = w1[3];
37 w2_t[0] = 0;
38 w2_t[1] = 0;
39 w2_t[2] = 0;
40 w2_t[3] = 0;
41 w3_t[0] = 0;
42 w3_t[1] = 0;
43 w3_t[2] = (out_len) * 8;
44 w3_t[3] = 0;
45
46 digest[0] = MD5M_A;
47 digest[1] = MD5M_B;
48 digest[2] = MD5M_C;
49 digest[3] = MD5M_D;
50
51 md5_transform_cl (w0_t, w1_t, w2_t, w3_t, digest);
52
53 u8 b64encoded[16];
54
55 /*
56 ((u8 *)digest)[0] = 0x87;
57 ((u8 *)digest)[1] = 0x43;
58 ((u8 *)digest)[2] = 0xb5;
59 ((u8 *)digest)[3] = 0x20;
60 ((u8 *)digest)[4] = 0x63;
61 ((u8 *)digest)[5] = 0xcd;
62 */
63 out_len = b64_encode (b64encoded, 6, (u8 *)digest);
64
65 for (i = out_len; i < 16; i++) {
66 b64encoded[i] = 0;
67 }
68
69 /*
70 b64encoded[0] = 'h';
71 b64encoded[1] = '0';
72 b64encoded[2] = 'O';
73 b64encoded[3] = '1';
74 b64encoded[4] = 'I';
75 b64encoded[5] = 'G';
76 b64encoded[6] = 'P';
77 b64encoded[7] = 'N';
78 */
79
80
81 w0[0] = ((u32x *)b64encoded)[0];
82 w0[1] = ((u32x *)b64encoded)[1];
83 w0[2] = ((u32x *)b64encoded)[2];
84 w0[3] = ((u32x *)b64encoded)[3];
85 w1[0] = 0;
86 w1[1] = 0;
87 w1[2] = 0;
88 w1[3] = 0;
89
90 return (out_len);
91 }
92
93 u32x mangle_hmac (u32x w0[4], u32x w1[4], const u32x in_len)
94 {
95 u32x out_len = in_len;
96
97 u32 digest[4];
98 u32 data[8];
99 u32 i;
100
101 data[0] = w0[0];
102 data[1] = w0[1];
103 data[2] = w0[2];
104 data[3] = w0[3];
105 data[4] = w1[0];
106 data[5] = w1[1];
107 data[6] = w1[2];
108 data[7] = w1[3];
109
110 md5hmac_domain((u8 *)data, in_len, (u8 *)digest);
111
112 // printf("HMAC: ");
113 // for (i = 0; i < 16; i++) {
114 // printf("%x", ((u8 *)digest)[i]);
115 // }
116 // printf("\n");
117
118 w0[0] = digest[0];
119 w0[1] = digest[1];
120 w0[2] = digest[2];
121 w0[3] = digest[3];
122 w1[0] = 0;
123 w1[1] = 0;
124 w1[2] = 0;
125 w1[3] = 0;
126
127 out_len = b64_encode ((u8 *)data, 16, (u8 *)w0);
128 //out_len = 8;
129
130 for (i = out_len; i < 32; i++) {
131 ((u8 *)data)[i] = 0;
132 }
133
134 w0[0] = data[0];
135 w0[1] = data[1];
136 w0[2] = data[2];
137 w0[3] = data[3];
138 w1[0] = data[4];
139 w1[1] = data[5];
140 w1[2] = data[6];
141 w1[3] = data[7];
142
143 return (out_len);
144 }
145
146 bool containsnonalphanumeric (u8 * data, u32 length)
147 {
148 bool nonalphanumeric;
149 u32 pos;
150 char check;
151 u32 startingSize;
152
153 nonalphanumeric = false;
154 for (pos = 0; (pos < length) && !nonalphanumeric; pos++) {
155 check = data[pos];
156 if (!((check >= 'a') && (check <= 'z'))
157 && !((check >= 'A') && (check <= 'Z'))
158 && !((check >= '0') && (check <= '9'))
159 && !(check == '_')) {
160 nonalphanumeric = true;
161 }
162 }
163
164 return nonalphanumeric;
165 }
166
167 bool contains(u8 const * password, u32 length, u8 start, u8 end) {
168 bool doescontain = false;
169 u32 pos;
170
171 for (pos = 0; (pos < length) && (doescontain == false); pos++) {
172 if ((password[pos] >= start) && (password[pos] <= end)) {
173 doescontain = true;
174 }
175 }
176
177 return doescontain;
178 }
179
180 void rotate_string(u8 * torotate, u32 length, u32 steps) {
181 u8 scratch[RESULT_MAX];
182 u32 pos;
183
184 for (pos = 0; pos < length; pos++) {
185 scratch[pos] = torotate[(pos + steps) % length];
186 }
187
188 for (pos = 0; pos < length; pos++) {
189 torotate[pos] = scratch[pos];
190 }
191 }
192
193 u32x mangle_pwdhash (u32x w0[4], u32x w1[4], const u32x in_len)
194 {
195 u32x out_len = in_len;
196
197 u32 digest[4];
198 u32 data[8];
199 u32 hash[8];
200 u32 i;
201 u32 size;
202 u32 extrasize;
203 u32 startingsize;
204 bool nonalphanumeric;
205 u32 extrapos;
206 u8 next;
207
208 hash[0] = w0[0];
209 hash[1] = w0[1];
210 hash[2] = w0[2];
211 hash[3] = w0[3];
212 hash[4] = w1[0];
213 hash[5] = w1[1];
214 hash[6] = w1[2];
215 hash[7] = w1[3];
216
217 md5hmac_domain((u8 *)hash, in_len, (u8 *)digest);
218 nonalphanumeric = containsnonalphanumeric ((u8 *)hash, in_len);
219
220 w0[0] = digest[0];
221 w0[1] = digest[1];
222 w0[2] = digest[2];
223 w0[3] = digest[3];
224 w1[0] = 0;
225 w1[1] = 0;
226 w1[2] = 0;
227 w1[3] = 0;
228
229 out_len = b64_encode ((u8 *)hash, 16, (u8 *)w0);
230 out_len = 22; // b64 encoding will produce 24 bytes output, but last two will be "=="
231 extrasize = 22;
232 size = in_len + 2;
233
234 printf("Hash: %s\n", (u8 *)hash);
235
236 // for (i = out_len; i < 32; i++) {
237 // ((u8 *)hash)[i] = 0;
238 // }
239
240 startingsize = size - 4;
241 startingsize = (startingsize < extrasize) ? startingsize : extrasize;
242
243 for (i = 0; i < startingsize; i++) {
244 ((u8 *)data)[i] = ((u8 *)hash)[i];
245 }
246 for (i = startingsize; i < 32; i++) {
247 ((u8 *)data)[i] = 0;
248 }
249
250 extrapos = startingsize;
251
252 // Add the extras
253 // Capital letter
254 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
255 extrapos++;
256 if (!contains((u8 *)data, startingsize, 'A', 'Z')) {
257 next = 'A' + (next % ('Z' - 'A' + 1));
258 }
259 ((u8 *)data)[startingsize] = next;
260 startingsize++;
261
262 // Lower case letter
263 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
264 extrapos++;
265 if (!contains((u8 *)data, startingsize, 'a', 'z')) {
266 next = 'a' + (next % ('z' - 'a' + 1));
267 }
268 ((u8 *)data)[startingsize] = next;
269 startingsize++;
270
271 // Number
272 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
273 extrapos++;
274 if (!contains((u8 *)data, startingsize, '0', '9')) {
275 next = '0' + (next % ('9' - '0' + 1));
276 }
277 ((u8 *)data)[startingsize] = next;
278 startingsize++;
279
280 // Non alphanumeric
281 if (containsnonalphanumeric((u8 *)data, startingsize) && nonalphanumeric) {
282 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
283 extrapos++;
284 }
285 else {
286 next = '+';
287 }
288 ((u8 *)data)[startingsize] = next;
289 startingsize++;
290
291 if (!nonalphanumeric) {
292 for (i = 0; i < startingsize; i++) {
293 if (containsnonalphanumeric(((u8 *)data) + i, 1)) {
294 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
295 extrapos++;
296 next = 'A' + (next % ('Z' - 'A' + 1));
297 ((u8 *)data)[i] = next;
298 }
299 }
300 }
301
302 next = (extrapos < extrasize) ? ((u8 *)hash)[extrapos] : 0;
303 rotate_string((u8 *)data, startingsize, next);
304 ((u8 *)data)[startingsize] = 0;
305
306 out_len = startingsize;
307
308 w0[0] = data[0];
309 w0[1] = data[1];
310 w0[2] = data[2];
311 w0[3] = data[3];
312 w1[0] = data[4];
313 w1[1] = data[5];
314 w1[2] = data[6];
315 w1[3] = data[7];
316
317 return (out_len);
318 }
319
320 void writeHexByte(unsigned char byte, unsigned char * hex) {
321 static char number[] = "0123456789abcdef";
322
323 hex[0] = number[(byte >> 4)];
324 hex[1] = number[(byte % 16)];
325 }
326
327 int main(int argc, char * argv[]) {
328 unsigned char result[RESULT_MAX];
329 unsigned char salt[SALT_MAX];
330 unsigned char digest[DIGEST_SIZE];
331 unsigned char hash[DIGEST_SIZE * 2 + 1];
332 size_t size;
333 int pos;
334 char password[PASS_MAX];
335
336 for (pos = 0; pos < PASS_MAX; pos++) {
337 password[pos] = 0;
338 }
339
340 if (argc > 1) {
341 strncpy(password, argv[1], PASS_MAX);
342 }
343 else {
344 strncpy(password, "hashcat", PASS_MAX);
345 }
346 password[PASS_MAX - 1] = '\0';
347
348 if (argc > 2) {
349 strncpy(salt, argv[2], SALT_MAX);
350 }
351 else {
352 strncpy(salt, "1234", SALT_MAX);
353 }
354 salt[SALT_MAX - 1] = '\0';
355
356 //SPH_HashedPassowrd("hashcat", "flypig.co.uk", result);
357
358 //mangle(password);
359
360 size = mangle_pwdhash ((u32x *)password, (u32x *)(password + 16), strlen(password));
361
362 //md5hmac(salt, password, digest);
363
364 md5hmac_cl(salt, strlen(salt), password, size, digest);
365
366
367 for (pos = 0; pos < DIGEST_SIZE; pos++) {
368 writeHexByte(digest[pos], hash + (pos * 2));
369 }
370 hash[DIGEST_SIZE * 2] = '\0';
371
372 printf("(password, salt) = (\"%s\", \"%s\")\n", password, salt);
373 printf("Result: %s:%s\n", hash, salt);
374
375 return 0;
376 }
377