15 //void mangle(char * password)
16 u32x
mangle_md5 (u32x w0
[4], u32x w1
[4], const u32x in_len
)
18 u32x out_len
= in_len
;
27 append_0x80_2x4_VV (w0
, w1
, out_len
);
43 w3_t
[2] = (out_len
) * 8;
51 md5_transform_cl (w0_t
, w1_t
, w2_t
, w3_t
, digest
);
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;
63 out_len
= b64_encode (b64encoded
, 6, (u8
*)digest
);
65 for (i
= out_len
; i
< 16; i
++) {
81 w0
[0] = ((u32x
*)b64encoded
)[0];
82 w0
[1] = ((u32x
*)b64encoded
)[1];
83 w0
[2] = ((u32x
*)b64encoded
)[2];
84 w0
[3] = ((u32x
*)b64encoded
)[3];
93 u32x
mangle_hmac (u32x w0
[4], u32x w1
[4], const u32x in_len
)
95 u32x out_len
= in_len
;
110 md5hmac_domain((u8
*)data
, in_len
, (u8
*)digest
);
113 // for (i = 0; i < 16; i++) {
114 // printf("%x", ((u8 *)digest)[i]);
127 out_len
= b64_encode ((u8
*)data
, 16, (u8
*)w0
);
130 for (i
= out_len
; i
< 32; i
++) {
146 bool containsnonalphanumeric (u8
* data
, u32 length
)
148 bool nonalphanumeric
;
153 nonalphanumeric
= false;
154 for (pos
= 0; (pos
< length
) && !nonalphanumeric
; pos
++) {
156 if (!((check
>= 'a') && (check
<= 'z'))
157 && !((check
>= 'A') && (check
<= 'Z'))
158 && !((check
>= '0') && (check
<= '9'))
159 && !(check
== '_')) {
160 nonalphanumeric
= true;
164 return nonalphanumeric
;
167 bool contains(u8
const * password
, u32 length
, u8 start
, u8 end
) {
168 bool doescontain
= false;
171 for (pos
= 0; (pos
< length
) && (doescontain
== false); pos
++) {
172 if ((password
[pos
] >= start
) && (password
[pos
] <= end
)) {
180 void rotate_string(u8
* torotate
, u32 length
, u32 steps
) {
181 u8 scratch
[RESULT_MAX
];
184 for (pos
= 0; pos
< length
; pos
++) {
185 scratch
[pos
] = torotate
[(pos
+ steps
) % length
];
188 for (pos
= 0; pos
< length
; pos
++) {
189 torotate
[pos
] = scratch
[pos
];
193 u32x
mangle_pwdhash (u32x w0
[4], u32x w1
[4], const u32x in_len
)
195 u32x out_len
= in_len
;
204 bool nonalphanumeric
;
217 md5hmac_domain((u8
*)hash
, in_len
, (u8
*)digest
);
218 nonalphanumeric
= containsnonalphanumeric ((u8
*)hash
, in_len
);
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 "=="
234 printf("Hash: %s\n", (u8
*)hash
);
236 // for (i = out_len; i < 32; i++) {
237 // ((u8 *)hash)[i] = 0;
240 startingsize
= size
- 4;
241 startingsize
= (startingsize
< extrasize
) ? startingsize
: extrasize
;
243 for (i
= 0; i
< startingsize
; i
++) {
244 ((u8
*)data
)[i
] = ((u8
*)hash
)[i
];
246 for (i
= startingsize
; i
< 32; i
++) {
250 extrapos
= startingsize
;
254 next
= (extrapos
< extrasize
) ? ((u8
*)hash
)[extrapos
] : 0;
256 if (!contains((u8
*)data
, startingsize
, 'A', 'Z')) {
257 next
= 'A' + (next
% ('Z' - 'A' + 1));
259 ((u8
*)data
)[startingsize
] = next
;
263 next
= (extrapos
< extrasize
) ? ((u8
*)hash
)[extrapos
] : 0;
265 if (!contains((u8
*)data
, startingsize
, 'a', 'z')) {
266 next
= 'a' + (next
% ('z' - 'a' + 1));
268 ((u8
*)data
)[startingsize
] = next
;
272 next
= (extrapos
< extrasize
) ? ((u8
*)hash
)[extrapos
] : 0;
274 if (!contains((u8
*)data
, startingsize
, '0', '9')) {
275 next
= '0' + (next
% ('9' - '0' + 1));
277 ((u8
*)data
)[startingsize
] = next
;
281 if (containsnonalphanumeric((u8
*)data
, startingsize
) && nonalphanumeric
) {
282 next
= (extrapos
< extrasize
) ? ((u8
*)hash
)[extrapos
] : 0;
288 ((u8
*)data
)[startingsize
] = next
;
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;
296 next
= 'A' + (next
% ('Z' - 'A' + 1));
297 ((u8
*)data
)[i
] = next
;
302 next
= (extrapos
< extrasize
) ? ((u8
*)hash
)[extrapos
] : 0;
303 rotate_string((u8
*)data
, startingsize
, next
);
304 ((u8
*)data
)[startingsize
] = 0;
306 out_len
= startingsize
;
320 void writeHexByte(unsigned char byte
, unsigned char * hex
) {
321 static char number
[] = "0123456789abcdef";
323 hex
[0] = number
[(byte
>> 4)];
324 hex
[1] = number
[(byte
% 16)];
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];
334 char password
[PASS_MAX
];
336 for (pos
= 0; pos
< PASS_MAX
; pos
++) {
341 strncpy(password
, argv
[1], PASS_MAX
);
344 strncpy(password
, "hashcat", PASS_MAX
);
346 password
[PASS_MAX
- 1] = '\0';
349 strncpy(salt
, argv
[2], SALT_MAX
);
352 strncpy(salt
, "1234", SALT_MAX
);
354 salt
[SALT_MAX
- 1] = '\0';
356 //SPH_HashedPassowrd("hashcat", "flypig.co.uk", result);
360 size
= mangle_pwdhash ((u32x
*)password
, (u32x
*)(password
+ 16), strlen(password
));
362 //md5hmac(salt, password, digest);
364 md5hmac_cl(salt
, strlen(salt
), password
, size
, digest
);
367 for (pos
= 0; pos
< DIGEST_SIZE
; pos
++) {
368 writeHexByte(digest
[pos
], hash
+ (pos
* 2));
370 hash
[DIGEST_SIZE
* 2] = '\0';
372 printf("(password, salt) = (\"%s\", \"%s\")\n", password
, salt
);
373 printf("Result: %s:%s\n", hash
, salt
);