-m 13200 Fix test.pl split
[hashcat.git] / tools / test.pl
1 #!/usr/bin/env perl
2
3 ##
4 ## Author......: Jens Steube <jens.steube@gmail.com>
5 ## License.....: MIT
6 ##
7
8 use strict;
9 use warnings;
10 use Digest::MD4 qw (md4 md4_hex);
11 use Digest::MD5 qw (md5 md5_hex);
12 use Digest::SHA qw (sha1 sha256 sha384 sha512 sha1_hex sha256_hex sha384_hex sha512_hex);
13 use Digest::HMAC qw (hmac hmac_hex);
14 use Digest::Keccak qw (keccak_256_hex);
15 use Crypt::MySQL qw (password41);
16 use Digest::GOST qw (gost gost_hex);
17 use Digest::HMAC_MD5 qw (hmac_md5);
18 use Digest::CRC qw (crc32);
19 use Crypt::PBKDF2;
20 use Crypt::DES;
21 use Crypt::ECB qw (encrypt PADDING_AUTO PADDING_NONE);
22 use Crypt::CBC;
23 use Crypt::Eksblowfish::Bcrypt qw (bcrypt en_base64);
24 use Crypt::Digest::RIPEMD160 qw (ripemd160_hex);
25 use Crypt::Digest::Whirlpool qw (whirlpool_hex);
26 use Crypt::RC4;
27 use Crypt::ScryptKDF qw (scrypt_hash scrypt_b64);
28 use Crypt::Rijndael;
29 use Crypt::Mode::ECB;
30 use Crypt::UnixCrypt_XS qw (crypt_rounds fold_password base64_to_int24 block_to_base64 int24_to_base64);
31 use MIME::Base64;
32 use Authen::Passphrase::NTHash;
33 use Authen::Passphrase::MySQL323;
34 use Authen::Passphrase::PHPass;
35 use Authen::Passphrase::LANManager;
36 use Encode;
37 use POSIX qw (strftime);
38 use Net::DNS::SEC;
39 use Net::DNS::RR::NSEC3;
40 use Convert::EBCDIC qw (ascii2ebcdic);
41 use Digest::SipHash qw/siphash/;
42
43 my $hashcat = "./oclHashcat";
44
45 my $MAX_LEN = 55;
46
47 my @modes = (0, 10, 11, 12, 20, 21, 22, 23, 30, 40, 50, 60, 100, 101, 110, 111, 112, 120, 121, 122, 130, 131, 132, 140, 141, 150, 160, 190, 200, 300, 400, 500, 900, 1000, 1100, 1400, 1410, 1420, 1430, 1440, 1441, 1450, 1460, 1500, 1600, 1700, 1710, 1711, 1720, 1730, 1740, 1722, 1731, 1750, 1760, 1800, 2100, 2400, 2410, 2500, 2600, 2611, 2612, 2711, 2811, 3000, 3100, 3200, 3710, 3711, 3300, 3500, 3610, 3720, 3800, 3910, 4010, 4110, 4210, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5300, 5400, 5500, 5600, 5700, 5800, 6000, 6100, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7100, 7200, 7300, 7400, 7500, 7600, 7700, 7800, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8900, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900, 10000, 10100, 10200, 10300, 10400, 10500, 10600, 10700, 10800, 10900, 11000, 11100, 11200, 11300, 11400, 11500, 11600, 11900, 12000, 12100, 12200, 12300, 12400, 12600, 12700, 12800, 12900, 13000, 13100, 13200);
48
49 my %is_unicode = map { $_ => 1 } qw(30 40 130 131 132 140 141 1000 1100 1430 1440 1441 1730 1740 1731 5500 5600 8000 9400 9500 9600 9700 9800);
50 my %less_fifteen = map { $_ => 1 } qw(500 1600 1800 2400 2410 3200 6300 7400 10500 10700);
51 my %allow_long_salt = map { $_ => 1 } qw(2500 5500 5600 7100 7200 7300 9400 9500 9600 9700 9800 10400 10500 10600 10700 1100 11000 11200 11300 11400 11600 12600);
52
53 my @lotus_magic_table =
54 (
55 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a,
56 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0,
57 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b,
58 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a,
59 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda,
60 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36,
61 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8,
62 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c,
63 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17,
64 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60,
65 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72,
66 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa,
67 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd,
68 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e,
69 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b,
70 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf,
71 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77,
72 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6,
73 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3,
74 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3,
75 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e,
76 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c,
77 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d,
78 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2,
79 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46,
80 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5,
81 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97,
82 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5,
83 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef,
84 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f,
85 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf,
86 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab
87 );
88
89 my @pdf_padding =
90 (
91 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
92 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
93 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
94 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
95 );
96
97 my $CISCO_BASE64_MAPPING = {'A', '.', 'B', '/', 'C', '0', 'D', '1', 'E', '2', 'F', '3', 'G', '4', 'H', '5', 'I', '6', 'J', '7', 'K', '8', 'L', '9', 'M', 'A', 'N', 'B', 'O', 'C', 'P', 'D', 'Q', 'E', 'R', 'F', 'S', 'G', 'T', 'H', 'U', 'I', 'V', 'J', 'W', 'K', 'X', 'L', 'Y', 'M', 'Z', 'N', 'a', 'O', 'b', 'P', 'c', 'Q', 'd', 'R', 'e', 'S', 'f', 'T', 'g', 'U', 'h', 'V', 'i', 'W', 'j', 'X', 'k', 'Y', 'l', 'Z', 'm', 'a', 'n', 'b', 'o', 'c', 'p', 'd', 'q', 'e', 'r', 'f', 's', 'g', 't', 'h', 'u', 'i', 'v', 'j', 'w', 'k', 'x', 'l', 'y', 'm', 'z', 'n', '0', 'o', '1', 'p', '2', 'q', '3', 'r', '4', 's', '5', 't', '6', 'u', '7', 'v', '8', 'w', '9', 'x', '+', 'y', '/', 'z'};
98
99 if (scalar @ARGV < 1)
100 {
101 usage_die ();
102 }
103
104 my $type;
105 my $mode;
106 my $len;
107
108 $type = shift @ARGV;
109
110 if ($type ne "verify")
111 {
112 if (scalar @ARGV > 1)
113 {
114 $mode = shift @ARGV;
115 $len = shift @ARGV;
116 }
117 elsif (scalar @ARGV == 1)
118 {
119 $mode = shift @ARGV;
120 $len = 0;
121 }
122 else
123 {
124 $len = 0;
125 }
126
127 if ($type eq "single")
128 {
129 single ($mode);
130 }
131 elsif ($type eq "passthrough")
132 {
133 passthrough ($mode);
134 }
135 else
136 {
137 usage_die ();
138 }
139 }
140 else
141 {
142 if (scalar @ARGV != 4)
143 {
144 usage_die ();
145 }
146
147 my $mode = shift @ARGV;
148 my $hash_file = shift @ARGV;
149 my $in_file = shift @ARGV;
150 my $out_file = shift @ARGV;
151
152 my $db;
153
154 open (IN, "<", $hash_file) or die ("$hash_file: $!\n");
155
156 # clever ? the resulting database could be huge
157 # but we need some way to map lines in hashfile w/ cracks
158 # maybe rli2 way would be more clever (needs sorted input)
159
160 while (my $line = <IN>)
161 {
162 $line =~ s/[\n\r]*$//;
163
164 $db->{$line} = undef;
165 }
166
167 close (IN);
168
169 verify ($mode, $db, $in_file, $out_file);
170 }
171
172 sub verify
173 {
174 my $mode = shift;
175 my $db = shift;
176 my $in_file = shift;
177 my $out_file = shift;
178
179 my $hash_in;
180 my $hash_out;
181 my $iter;
182 my $salt;
183 my $word;
184 my $param;
185 my $param2;
186 my $param3;
187 my $param4;
188 my $param5;
189 my $param6;
190 my $param7;
191 my $param8;
192 my $param9;
193 my $param10;
194 my $param11;
195
196 open (IN, "<", $in_file) or die ("$in_file: $!\n");
197 open (OUT, ">", $out_file) or die ("$out_file: $!\n");
198
199 my $len;
200
201 my $base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
202 my $itoa64_1 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
203 my $itoa64_2 = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
204
205 while (my $line = <IN>)
206 {
207 chomp ($line);
208
209 $line =~ s/\n$//;
210 $line =~ s/\r$//;
211
212 # remember always do "exists ($db->{$hash_in})" checks as soon as possible and don't forget it
213
214 # unsalted
215 if ($mode == 0 || $mode == 100 || $mode == 101 || $mode == 190 || $mode == 200 || $mode == 300 || $mode == 900 || $mode == 1000 || $mode == 1400 || $mode == 1700 || $mode == 2400 || $mode == 2600 || $mode == 3000 || $mode == 3500 || $mode == 4300 || $mode == 4400 || $mode == 4500 || $mode == 4600 || $mode == 4700 || $mode == 5000 || $mode == 5100 || $mode == 5700 || $mode == 6000 || $mode == 6100 || $mode == 6900 || $mode == 8600 || $mode == 9900 || $mode == 10800 || $mode == 11500)
216 {
217 my $index = index ($line, ":");
218
219 next if $index < 1;
220
221 $hash_in = substr ($line, 0, $index);
222
223 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
224
225 $word = substr ($line, $index + 1);
226 }
227 # hash:salt
228 elsif ($mode == 10 || $mode == 11 || $mode == 12 || $mode == 20 || $mode == 21 || $mode == 22 || $mode == 23 || $mode == 30 || $mode == 40 || $mode == 50 || $mode == 60 || $mode == 110 || $mode == 112 || $mode == 120 || $mode == 121 || $mode == 130 || $mode == 140 || $mode == 150 || $mode == 160 || $mode == 1100 || $mode == 1410 || $mode == 1420 || $mode == 1430 || $mode == 1440 || $mode == 1450 || $mode == 1460 || $mode == 1710 || $mode == 1720 || $mode == 1730 || $mode == 1740 || $mode == 1750 || $mode == 1760 || $mode == 2410 || $mode == 2611 || $mode == 2711 || $mode == 2811 || $mode == 3100 || $mode == 3610 || $mode == 3710 || $mode == 3720 || $mode == 3800 || $mode == 3910 || $mode == 4010 || $mode == 4110 || $mode == 4210 || $mode == 4900 || $mode == 5800 || $mode == 7600 || $mode == 8400 || $mode == 11000 || $mode == 12600)
229 {
230 # get hash
231 my $index1 = index ($line, ":");
232
233 next if $index1 < 1;
234
235 $hash_in = substr ($line, 0, $index1);
236
237 # identify lenghts of both salt and plain
238
239 my $salt_plain = substr ($line, $index1 + 1);
240
241 my $num_cols = () = $salt_plain =~ /:/g;
242
243 my $index2;
244 my $matched = 0;
245 my $start = 0;
246
247 $word = undef;
248
249 # fuzzy
250 foreach (my $i = 0; $i < $num_cols; $i++)
251 {
252 $index2 = index ($salt_plain, ":", $start);
253
254 next if $index2 < 0;
255
256 $start = $index2 + 1;
257
258 $salt = substr ($salt_plain, 0, $index2);
259 $word = substr ($salt_plain, $index2 + 1);
260
261 # can't be true w/ wrong $hash:$salt, otherwise the
262 # algo must have many collisions
263
264 if (exists ($db->{$hash_in . ":" . $salt}))
265 {
266 $hash_in = $hash_in . ":" . $salt;
267 $matched = 1;
268 last;
269 }
270 }
271
272 next unless ($matched); # therefore: true == exists ($db->{$hash_in}
273 next unless (! defined ($db->{$hash_in}));
274 }
275 # dcc2
276 elsif ($mode == 2100)
277 {
278 # get hash
279 my $index1 = index ($line, "\$DCC2\$");
280
281 next if $index1 != 0;
282
283 # iterations
284 my $index2 = index ($line, "#", $index1 + 1);
285
286 next if $index2 < 1;
287
288 $iter = substr ($line, $index1 + 6, $index2 - $index1 - 6);
289
290 # get hash
291 $index1 = index ($line, "#");
292
293 next if $index1 < 1;
294
295 $hash_in = substr ($line, 0, $index1 + 1);
296
297 # identify lenghts of both salt and plain
298
299 my $salt_plain = substr ($line, $index2 + 1);
300
301 my $num_cols = () = $salt_plain =~ /:/g;
302
303 my $matched = 0;
304 my $start = 0;
305 my $index3 = 0;
306 my $raw_hash;
307
308 $word = undef;
309
310 # fuzzy
311 foreach (my $i = 0; $i < $num_cols; $i++)
312 {
313 $index2 = index ($salt_plain, ":", $start);
314
315 next if $index2 < 0;
316
317 $start = $index2 + 1;
318
319 $index3 = rindex ($salt_plain, "#", $index2);
320
321 $raw_hash = substr ($salt_plain, $index3 + 1, $index2 - $index3 - 1);
322 $salt = substr ($salt_plain, 0, $index3);
323 $word = substr ($salt_plain, $index2 + 1);
324
325 if (exists ($db->{$hash_in . $salt . "#" .$raw_hash}))
326 {
327 $hash_in = $hash_in . $salt . "#" . $raw_hash;
328 $matched = 1;
329 last;
330 }
331 }
332
333 next unless ($matched); # therefore: true == exists ($db->{$hash_in}
334 next unless (! defined ($db->{$hash_in}));
335 }
336 # salt:hash guaranteed only : because of hex salt
337 elsif ($mode == 7300)
338 {
339 # split hash and plain
340 my $index1 = index ($line, ":");
341
342 next if $index1 < 1;
343
344 $salt = substr ($line, 0, $index1);
345
346 $salt = pack ("H*", $salt);
347
348 my $rest = substr ($line, $index1 + 1);
349
350 my $index2 = index ($rest, ":");
351
352 next if $index2 < 1;
353
354 $hash_in = substr ($rest, 0, $index2);
355
356 $word = substr ($rest, $index2 + 1);
357
358 next unless (exists ($db->{$salt . ":" . $hash_in}) and (! defined ($db->{$hash_in})));
359 }
360 # 1salthash fixed
361 elsif ($mode == 8100)
362 {
363 # split hash and plain
364 $salt = substr ($line, 1, 8);
365
366 my $rest = substr ($line, 1 + 8);
367
368 my $index2 = index ($rest, ":");
369
370 next if $index2 < 1;
371
372 $hash_in = substr ($rest, 0, $index2);
373
374 $word = substr ($rest, $index2 + 1);
375
376 next unless (exists ($db->{"1" . $salt . $hash_in}) and (! defined ($db->{$hash_in})));
377 }
378 # base64 and salt embedded SSHA1, salt length = total lenght - 20
379 elsif ($mode == 111)
380 {
381 # split hash and plain
382 my $index = index ($line, ":");
383
384 next if $index < 1;
385
386 $hash_in = substr ($line, 0, $index);
387 $word = substr ($line, $index + 1);
388
389 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
390
391 # remove signature
392 my $plain_base64 = substr ($hash_in, 6);
393
394 # base64 decode to extract salt
395 my $decoded = decode_base64 ($plain_base64);
396
397 $salt = substr ($decoded, 20);
398 }
399 # base64 and salt embedded SSHA512, salt length = total length - 64
400 elsif ($mode == 1711)
401 {
402 # split hash and plain
403 my $index = index ($line, ":");
404
405 next if $index < 1;
406
407 $hash_in = substr ($line, 0, $index);
408 $word = substr ($line, $index + 1);
409
410 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
411
412 # remove signature
413 my $plain_base64 = substr ($hash_in, 9);
414
415 # base64 decode to extract salt
416 my $decoded = decode_base64 ($plain_base64);
417
418 $salt = substr ($decoded, 64);
419 }
420 # OSX (first 8 hex chars is salt)
421 elsif ($mode == 122 || $mode == 1722)
422 {
423 my $index = index ($line, ":");
424
425 next if $index < 1;
426
427 $hash_in = substr ($line, 0, $index);
428 $word = substr ($line, $index + 1);
429
430 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
431
432 $salt = substr ($hash_in, 0, 8);
433 }
434 # MSSQL (2000, 2005 AND 2012), salt after version number
435 elsif ($mode == 131 || $mode == 132 || $mode == 1731)
436 {
437 my $index = index ($line, ":");
438
439 next if $index < 1;
440
441 $hash_in = substr ($line, 0, $index);
442 $word = substr ($line, $index + 1);
443
444 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
445
446 $salt = substr ($hash_in, 6, 8);
447 }
448 # Sybase ASE
449 elsif ($mode == 8000)
450 {
451 my $index = index ($line, ":");
452
453 next if $index < 1;
454
455 $hash_in = substr ($line, 0, $index);
456 $word = substr ($line, $index + 1);
457
458 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
459
460 $salt = substr ($hash_in, 6, 16);
461 }
462 # episerver salts
463 elsif ($mode == 141 || $mode == 1441)
464 {
465 my $index1 = index ($line, ":");
466
467 next if $index1 < 1;
468
469 $hash_in = substr ($line, 0, $index1);
470 $word = substr ($line, $index1 + 1);
471
472 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
473
474 my $index2 = index ($line, "*", 14);
475
476 #extract salt from base64
477 my $plain_base64 = substr ($hash_in, 14, $index2 - 14);
478
479 $salt = decode_base64 ($plain_base64);
480 }
481 # phpass (first 8 after $P$/$H$ -- or $S$ with drupal7)
482 elsif ($mode == 400 || $mode == 7900)
483 {
484 my $index = index ($line, ":");
485
486 next if $index < 1;
487
488 $hash_in = substr ($line, 0, $index);
489 $word = substr ($line, $index + 1);
490
491 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
492
493 $salt = substr ($hash_in, 4, 8);
494
495 # iterations = 2 ^ cost (where cost == $iter)
496 $iter = index ($itoa64_1, substr ($hash_in, 3, 1));
497 }
498 # $something$[rounds=iter$]salt$ (get last $, then check iter)
499 elsif ($mode == 500 || $mode == 1600 || $mode == 1800 || $mode == 3300 || $mode == 7400)
500 {
501 my $index1 = index ($line, ":", 30);
502
503 next if $index1 < 1;
504
505 $hash_in = substr ($line, 0, $index1);
506 $word = substr ($line, $index1 + 1);
507
508 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
509
510 $index1 = index ($hash_in, ",", 1);
511 my $index2 = index ($hash_in, "\$", 1);
512
513 if ($index1 != -1)
514 {
515 if ($index1 < $index2)
516 {
517 $index2 = $index1;
518 }
519 }
520
521 $param = substr ($hash_in, $index2, 1);
522
523 $index2++;
524
525 # rounds= if available
526 $iter = 0;
527
528 if (substr ($hash_in, $index2, 7) eq "rounds=")
529 {
530 my $old_index = $index2;
531
532 $index2 = index ($hash_in, "\$", $index2 + 1);
533
534 next if $index2 < 1;
535
536 $iter = substr ($hash_in, $old_index + 7, $index2 - $old_index - 7);
537
538 $index2++;
539 }
540
541 # get salt
542 my $index3 = rindex ($hash_in, "\$");
543
544 next if $index3 < 1;
545
546 $salt = substr ($hash_in, $index2, $index3 - $index2);
547 }
548 # descrypt (salt in first 2 char)
549 elsif ($mode == 1500)
550 {
551 my $index = index ($line, ":");
552
553 next if $index < 1;
554
555 $hash_in = substr ($line, 0, $index);
556 $word = substr ($line, $index + 1);
557
558 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
559
560 $salt = substr ($hash_in, 0, 2);
561 }
562 # bcrypt $something$something$salt.hash
563 elsif ($mode == 3200)
564 {
565 my $index1 = index ($line, ":", 33);
566
567 next if $index1 < 1;
568
569 $hash_in = substr ($line, 0, $index1);
570 $word = substr ($line, $index1 + 1);
571
572 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
573
574 my $index2 = index ($hash_in, "\$", 4);
575
576 $iter = substr ($hash_in, 4, $index2 - 4);
577
578 my $plain_base64 = substr ($hash_in, $index2 + 1, 22);
579
580 # base64 mapping
581 my $encoded = "";
582
583 for (my $i = 0; $i < length ($plain_base64); $i++)
584 {
585 my $char = substr ($plain_base64, $i, 1);
586 $encoded .= substr ($base64, index ($itoa64_2, $char), 1);
587 }
588
589 $salt = decode_base64 ($encoded);
590 }
591 # md5 (chap)
592 elsif ($mode == 4800)
593 {
594 my $index1 = index ($line, ":");
595
596 next if $index1 < 1;
597
598 my $index2 = index ($line, ":", $index1 + 1);
599
600 next if $index2 < 1;
601
602 my $index3 = index ($line, ":", $index2 + 1);
603
604 next if $index3 < 1;
605
606 $salt = substr ($line, $index1 + 1, $index3 - $index1 - 1);
607
608 $word = substr ($line, $index3 + 1);
609
610 $hash_in = substr ($line, 0, $index3);
611 }
612 # IKE (md5 and sha1)
613 elsif ($mode == 5300 || $mode == 5400)
614 {
615 my $num_cols = () = $line =~ /:/g;
616
617 next unless ($num_cols >= 9);
618
619 my $index1 = -1;
620 my $failed = 0;
621
622 for (my $j = 0; $j < 9; $j++)
623 {
624 $index1 = index ($line, ":", $index1 + 1);
625
626 if ($index1 < 1)
627 {
628 $failed = 1;
629 last;
630 }
631 }
632
633 next if ($failed);
634
635 $word = substr ($line, $index1 + 1);
636
637 $hash_in = substr ($line, 0, $index1);
638
639 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
640
641 my $index2 = rindex ($line, ":", $index1 - 1);
642
643 $salt = substr ($line, 0, $index2);
644 }
645 # NetNTLMv1
646 elsif ($mode == 5500)
647 {
648 my $index1 = index ($line, "::");
649
650 next if $index1 < 1;
651
652 my $index2 = index ($line, ":", $index1 + 2);
653
654 next if $index2 < 1;
655
656 $index2 = index ($line, ":", $index2 + 1);
657
658 next if $index2 < 1;
659
660 $salt = substr ($line, 0, $index2);
661
662 $index2 = index ($line, ":", $index2 + 1);
663
664 next if $index2 < 1;
665
666 $salt .= substr ($line, $index2 + 1, 16);
667
668 $index2 = index ($line, ":", $index2 + 1);
669
670 next if $index2 < 1;
671
672 $hash_in = substr ($line, 0, $index2);
673
674 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
675
676 $word = substr ($line, $index2 + 1);
677 }
678 # NetNTLMv2
679 elsif ($mode == 5600)
680 {
681 my $index1 = index ($line, "::");
682
683 next if $index1 < 1;
684
685 my $index2 = index ($line, ":", $index1 + 2);
686
687 next if $index2 < 1;
688
689 $index2 = index ($line, ":", $index2 + 1);
690
691 next if $index2 < 1;
692
693 $salt = substr ($line, 0, $index2);
694
695 $index1 = index ($line, ":", $index2 + 1);
696
697 next if $index1 < 1;
698
699 $index2 = index ($line, ":", $index1 + 1);
700
701 next if $index2 < 1;
702
703 $salt .= substr ($line, $index1 + 1, $index2 - $index1 - 1);
704
705 $hash_in = substr ($line, 0, $index2);
706
707 # do it later on for this hash mode:
708 # next unless ((exists ($db->{$hash_in}) and (! defined ($db->{$hash_in}))) or (exists ($db->{$mod}) and (! defined ($db->{$mod}))));
709
710 $word = substr ($line, $index2 + 1);
711 }
712 # AIX smd5 something BRACE salt$
713 elsif ($mode == 6300)
714 {
715 my $index1 = index ($line, ":");
716
717 next if $index1 < 1;
718
719 $hash_in = substr ($line, 0, $index1);
720 $word = substr ($line, $index1 + 1);
721
722 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
723
724 my $index2 = index ($hash_in, "}");
725 my $index3 = rindex ($hash_in, "\$");
726
727 $salt = substr ($hash_in, $index2 + 1, $index3 - $index2 - 1);
728 }
729 # AIX: something$salt$ (no $ at position 1)
730 elsif ($mode == 6400 || $mode == 6500 || $mode == 6700)
731 {
732 my $index1 = index ($line, ":");
733
734 next if $index1 < 1;
735
736 $hash_in = substr ($line, 0, $index1);
737 $word = substr ($line, $index1 + 1);
738
739 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
740
741 my $index2 = index ($hash_in, "}");
742 my $index3 = index ($hash_in, "\$");
743 my $index4 = rindex ($hash_in, "\$");
744
745 $salt = substr ($hash_in, $index3 + 1, $index4 - $index3 - 1);
746
747 $iter = substr ($hash_in, $index2 + 1, $index3 - $index2 - 1);
748 }
749 # 1Password, agilekeychain
750 elsif ($mode == 6600)
751 {
752 my $num_cols = () = $line =~ /:/g;
753
754 next unless ($num_cols > 2);
755
756 my $index1 = index ($line, ":");
757
758 next if $index1 < 1;
759
760 $iter = substr ($line, 0, $index1);
761
762 my $index2 = index ($line, ":", $index1 + 1);
763
764 next if $index2 < 1;
765
766 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
767
768 $index1 = index ($line, ":", $index2 + 1);
769
770 next if $index1 < 1;
771
772 $salt .= substr ($line, $index2 + 1, $index1 - $index2 - 33);
773
774 $hash_in = substr ($line, 0, $index1);
775
776 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
777
778 $word = substr ($line, $index1 + 1);
779 }
780 # 1Password, cloudkeychain
781 elsif ($mode == 8200)
782 {
783 my @datas = split (":", $line);
784
785 next if scalar @datas < 4;
786
787 my $hash = shift @datas;
788 $salt = shift @datas;
789 $iter = shift @datas;
790 my $data = shift @datas;
791
792 $hash_in = $hash . ":" . $salt . ":" . $iter . ":" . $data;
793
794 $salt .= $data;
795
796 $word = join (":", @datas);
797
798 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
799 }
800 # lastpass (hash:iter:salt)
801 elsif ($mode == 6800)
802 {
803 my $index1 = index ($line, ":", 34);
804
805 next if $index1 < 1;
806
807 $hash_in = substr ($line, 0, $index1);
808
809 # identify lenghts of both salt and plain
810
811 my $salt_plain = substr ($line, $index1 + 1);
812
813 my $num_cols = () = $salt_plain =~ /:/g;
814
815 my $index2;
816 my $matched = 0;
817 my $start = 0;
818
819 $word = undef;
820
821 # fuzzy
822 foreach (my $i = 0; $i < $num_cols; $i++)
823 {
824 $index2 = index ($salt_plain, ":", $start);
825
826 next if $index2 < 1;
827
828 $start = $index2 + 1;
829
830 $salt = substr ($salt_plain, 0, $index2);
831 $word = substr ($salt_plain, $index2 + 1);
832
833 # can't be true w/ wrong $hash:$salt, otherwise the
834 # algo must have many collisions
835
836 if (exists ($db->{$hash_in . ":" . $salt}))
837 {
838 $hash_in = $hash_in . ":" . $salt;
839 $matched = 1;
840 last;
841 }
842 }
843
844 next unless ($matched); # therefore: true == exists ($db->{$hash_in}
845 next unless (! defined ($db->{$hash_in}));
846
847 $index1 = index ($hash_in, ":");
848 $index2 = index ($hash_in, ":", $index1 + 1);
849
850 $iter = substr ($hash_in, $index1 + 1, $index2 - $index1 - 1);
851 $salt = substr ($hash_in, $index2 + 1);
852 }
853 # OSX 10.* : $something$iter$salt$
854 elsif ($mode == 7100)
855 {
856 my $index1 = index ($line, ":");
857
858 next if $index1 < 1;
859
860 $hash_in = substr ($line, 0, $index1);
861 $word = substr ($line, $index1 + 1);
862
863 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
864
865 my $index2 = index ($hash_in, "\$", 5);
866
867 next if $index2 < 1;
868
869 my $index3 = index ($hash_in, "\$", $index2 + 1);
870
871 $salt = substr ($hash_in, $index2 + 1, $index3 - $index2 - 1);
872
873 $iter = substr ($hash_in, 4, $index2 - 4);
874
875 next if (int ($iter) < 1);
876 }
877 # grub: something1.something2.something3.iter.salt.
878 elsif ($mode == 7200)
879 {
880 my $index1 = index ($line, ":");
881
882 next if $index1 < 1;
883
884 $hash_in = substr ($line, 0, $index1);
885 $word = substr ($line, $index1 + 1);
886
887 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
888
889 my $index2 = index ($hash_in, ".", 19);
890
891 next if $index2 < 1;
892
893 my $index3 = index ($hash_in, ".", $index2 + 1);
894
895 $salt = substr ($hash_in, $index2 + 1, $index3 - $index2 - 1);
896
897 $iter = substr ($hash_in, 19, $index2 - 19);
898
899 next if (int ($iter) < 1);
900 }
901 # $something1$something2$something3$something4$salt$
902 elsif ($mode == 7500 )
903 {
904 my $index1 = index ($line, "\$", 11);
905
906 next if $index1 < 1;
907
908 my $index2 = index ($line, "\$", $index1 + 1);
909
910 next if $index2 < 1;
911
912 my $index3 = index ($line, "\$", $index2 + 1);
913
914 next if $index3 < 1;
915
916 $index2 = index ($line, ":", $index3 + 1);
917
918 next if $index2 < 1;
919
920 $hash_in = substr ($line, 0, $index2);
921 $word = substr ($line, $index2 + 1);
922
923 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
924
925 $salt = substr ($hash_in, 11, $index3 - 10);
926 $salt .= substr ($hash_in, $index2 - 32) . "\$\$";
927 $salt .= substr ($hash_in, $index3 + 1, $index2 - $index3 - 32 - 1);
928 }
929 # $salt$$hash
930 elsif ($mode == 7700 || $mode == 7800)
931 {
932 my $index1 = index ($line, ":");
933
934 next if $index1 < 1;
935
936 my @split1 = split (":", $line);
937
938 my @split2 = split ('\$', $split1[0]);
939
940 next unless scalar @split2 == 2;
941
942 $hash_in = $split1[0];
943
944 if (scalar @split1 > 1)
945 {
946 $word = $split1[1];
947 }
948 else
949 {
950 $word = "";
951 }
952
953 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
954
955 $salt = $split2[0];
956 }
957 # DNSSEC
958 elsif ($mode == 8300)
959 {
960 my @datas = split (":", $line);
961
962 next if scalar @datas != 5;
963
964 my $hash;
965 my $domain;
966
967 ($hash, $domain, $salt, $iter, $word) = @datas;
968
969 $hash_in = $hash . ":" . $domain . ":" . $salt . ":" . $iter;
970
971 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
972
973 $salt = $domain . ":" . $salt;
974 }
975 # RACF
976 elsif ($mode == 8500)
977 {
978 my @line_elements = split (":", $line);
979
980 next if scalar @line_elements < 2;
981
982 # get hash and word
983
984 $hash_in = shift @line_elements;
985
986 $word = join (":", @line_elements);
987
988 # get signature
989
990 my @hash_elements = split ('\*', $hash_in);
991
992 next unless ($hash_elements[0] eq '$racf$');
993
994 $salt = $hash_elements[1];
995
996 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
997 }
998 # DOMINO 6
999 elsif ($mode == 8700)
1000 {
1001 # split hash and plain
1002 my $index = index ($line, ":");
1003
1004 next if $index < 1;
1005
1006 $hash_in = substr ($line, 0, $index);
1007 $word = substr ($line, $index + 1);
1008
1009 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1010
1011 my $plain_base64 = substr ($hash_in, 2, -1);
1012
1013 ($_, $salt, $param) = domino_decode ($plain_base64);
1014 }
1015 # PHPS
1016 elsif ($mode == 2612)
1017 {
1018 next unless (substr ($line, 0, 6) eq '$PHPS$');
1019
1020 # get hash
1021 my $index1 = index ($line, "\$", 6);
1022
1023 next if $index1 < 1;
1024
1025 $salt = substr ($line, 6, $index1 - 6);
1026
1027 $salt = pack ("H*", $salt);
1028
1029 my $index2 = index ($line, "\:", $index1 + 1);
1030
1031 next if $index2 < 1;
1032
1033 $word = substr ($line, $index2 + 1);
1034
1035 $hash_in = substr ($line, 0, $index2);
1036
1037 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1038 }
1039 # Mediawiki B type
1040 elsif ($mode == 3711)
1041 {
1042 next unless (substr ($line, 0, 3) eq '$B$');
1043
1044 # get hash
1045 my $index1 = index ($line, "\$", 3);
1046
1047 next if $index1 < 1;
1048
1049 $salt = substr ($line, 3, $index1 - 3);
1050
1051 my $index2 = index ($line, ":", $index1 + 1);
1052
1053 next if $index2 < 1;
1054
1055 $word = substr ($line, $index2 + 1);
1056
1057 $hash_in = substr ($line, 0, $index2);
1058
1059 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1060 }
1061 # scrypt
1062 elsif ($mode == 8900)
1063 {
1064 next unless (substr ($line, 0, 7) eq 'SCRYPT:');
1065
1066 # get hash
1067 my $index1 = index ($line, ":", 7);
1068
1069 next if $index1 < 1;
1070
1071 # N
1072 my $N = substr ($line, 7, $index1 - 7);
1073
1074 my $index2 = index ($line, ":", $index1 + 1);
1075
1076 next if $index2 < 1;
1077
1078 # r
1079 my $r = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1080
1081 $index1 = index ($line, ":", $index2 + 1);
1082
1083 next if $index1 < 1;
1084
1085 # p
1086 my $p = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1087
1088 $param = $N;
1089 $param2 = $r;
1090 $param3 = $p;
1091
1092 $index2 = index ($line, ":", $index1 + 1);
1093
1094 next if $index2 < 1;
1095
1096 # salt
1097 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1098
1099 $salt = decode_base64 ($salt);
1100
1101 $index1 = index ($line, ":", $index2 + 1);
1102
1103 next if $index1 < 1;
1104
1105 # digest
1106
1107 $word = substr ($line, $index1 + 1);
1108 $hash_in = substr ($line, 0, $index1);
1109
1110 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1111 }
1112 # LOTUS 8
1113 elsif ($mode == 9100)
1114 {
1115 # split hash and plain
1116 my $index = index ($line, ":");
1117
1118 next if $index < 1;
1119
1120 $hash_in = substr ($line, 0, $index);
1121 $word = substr ($line, $index + 1);
1122
1123 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1124
1125 my $base64_part = substr ($hash_in, 2, -1);
1126
1127 ($_, $salt, $iter, $param) = domino_85x_decode ($base64_part);
1128
1129 next if ($iter < 1);
1130 }
1131 # Cisco $8$ - PBKDF2-HMAC-SHA256
1132 elsif ($mode == 9200)
1133 {
1134 next unless (substr ($line, 0, 3) eq '$8$');
1135
1136 # get hash
1137 my $index1 = index ($line, "\$", 3);
1138
1139 next if $index1 != 17;
1140
1141 my $index2 = index ($line, "\$", $index1 + 1);
1142
1143 # salt
1144 $salt = substr ($line, 3, $index1 - 3);
1145
1146 $index1 = index ($line, ":", $index1 + 1);
1147
1148 next if $index1 < 1;
1149
1150 # digest
1151
1152 $word = substr ($line, $index1 + 1);
1153 $hash_in = substr ($line, 0, $index1);
1154
1155 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1156 }
1157 # Cisco $9$ - scrypt
1158 elsif ($mode == 9300)
1159 {
1160 next unless (substr ($line, 0, 3) eq '$9$');
1161
1162 # get hash
1163 my $index1 = index ($line, "\$", 3);
1164
1165 next if $index1 != 17;
1166
1167 my $index2 = index ($line, "\$", $index1 + 1);
1168
1169 # salt
1170 $salt = substr ($line, 3, $index1 - 3);
1171
1172 $index1 = index ($line, ":", $index1 + 1);
1173
1174 next if $index1 < 1;
1175
1176 # digest
1177
1178 $word = substr ($line, $index1 + 1);
1179 $hash_in = substr ($line, 0, $index1);
1180
1181 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1182 }
1183 # Office 2007
1184 elsif ($mode == 9400)
1185 {
1186 ($hash_in, $word) = split ":", $line;
1187
1188 next unless defined $hash_in;
1189 next unless defined $word;
1190
1191 my @data = split /\*/, $hash_in;
1192
1193 next unless scalar @data == 8;
1194
1195 next unless (shift @data eq '$office$');
1196 next unless (shift @data eq '2007');
1197 next unless (shift @data eq '20');
1198
1199 my $aes_key_size = shift @data;
1200
1201 next unless (($aes_key_size eq '128') || ($aes_key_size eq '256'));
1202 next unless (shift @data eq '16');
1203
1204 next unless (length $data[0] == 32);
1205 next unless (length $data[1] == 32);
1206 next unless (length $data[2] == 40);
1207
1208 $salt = shift @data;
1209 $param = shift @data;
1210 $param2 = $aes_key_size;
1211
1212 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1213 }
1214 # Office 2010
1215 elsif ($mode == 9500)
1216 {
1217 ($hash_in, $word) = split ":", $line;
1218
1219 next unless defined $hash_in;
1220 next unless defined $word;
1221
1222 my @data = split /\*/, $hash_in;
1223
1224 next unless scalar @data == 8;
1225
1226 next unless (shift @data eq '$office$');
1227 next unless (shift @data eq '2010');
1228 next unless (shift @data eq '100000');
1229 next unless (shift @data eq '128');
1230 next unless (shift @data eq '16');
1231
1232 next unless (length $data[0] == 32);
1233 next unless (length $data[1] == 32);
1234 next unless (length $data[2] == 64);
1235
1236 $salt = shift @data;
1237 $param = shift @data;
1238
1239 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1240 }
1241 # Office 2013
1242 elsif ($mode == 9600)
1243 {
1244 ($hash_in, $word) = split ":", $line;
1245
1246 next unless defined $hash_in;
1247 next unless defined $word;
1248
1249 my @data = split /\*/, $hash_in;
1250
1251 next unless scalar @data == 8;
1252
1253 next unless (shift @data eq '$office$');
1254 next unless (shift @data eq '2013');
1255 next unless (shift @data eq '100000');
1256 next unless (shift @data eq '256');
1257 next unless (shift @data eq '16');
1258
1259 next unless (length $data[0] == 32);
1260 next unless (length $data[1] == 32);
1261 next unless (length $data[2] == 64);
1262
1263 $salt = shift @data;
1264 $param = shift @data;
1265
1266 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1267 }
1268 # Office Old $1 $2
1269 elsif ($mode == 9700)
1270 {
1271 ($hash_in, $word) = split ":", $line;
1272
1273 next unless defined $hash_in;
1274 next unless defined $word;
1275
1276 my @data = split /\*/, $hash_in;
1277
1278 next unless scalar @data == 4;
1279
1280 my $signature = shift @data;
1281
1282 next unless (($signature eq '$oldoffice$0') || ($signature eq '$oldoffice$1'));
1283
1284 next unless (length $data[0] == 32);
1285 next unless (length $data[1] == 32);
1286 next unless (length $data[2] == 32);
1287
1288 $salt = shift @data;
1289 $param = shift @data;
1290 $param2 = substr ($signature, 11, 1);
1291
1292 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1293 }
1294 # Office Old $3 $4
1295 elsif ($mode == 9800)
1296 {
1297 ($hash_in, $word) = split ":", $line;
1298
1299 next unless defined $hash_in;
1300 next unless defined $word;
1301
1302 my @data = split /\*/, $hash_in;
1303
1304 next unless scalar @data == 4;
1305
1306 my $signature = shift @data;
1307
1308 next unless (($signature eq '$oldoffice$3') || ($signature eq '$oldoffice$4'));
1309
1310 next unless (length $data[0] == 32);
1311 next unless (length $data[1] == 32);
1312 next unless (length $data[2] == 40);
1313
1314 $salt = shift @data;
1315 $param = shift @data;
1316 $param2 = substr ($signature, 11, 1);
1317
1318 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1319 }
1320 # Django (PBKDF2-SHA256)
1321 elsif ($mode == 10000)
1322 {
1323 next unless (substr ($line, 0, 14) eq 'pbkdf2_sha256$');
1324
1325 # get hash
1326 my $index1 = index ($line, "\$", 14);
1327
1328 next if $index1 < 1;
1329
1330 my $index2 = index ($line, "\$", $index1 + 1);
1331
1332 # iter
1333
1334 $iter = substr ($line, 14, $index1 - 14);
1335
1336
1337 # salt
1338 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1339
1340 # digest
1341
1342 $index1 = index ($line, ":", $index2 + 1);
1343
1344 next if $index1 < 1;
1345
1346 $word = substr ($line, $index1 + 1);
1347 $hash_in = substr ($line, 0, $index1);
1348
1349 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1350 }
1351 # SipHash
1352 elsif ($mode == 10100)
1353 {
1354 my $hash;
1355
1356 ($hash, undef, undef, $salt, $word) = split ":", $line;
1357
1358 next unless defined $hash;
1359 next unless defined $salt;
1360 next unless defined $word;
1361
1362 next unless (length $hash == 16);
1363 next unless (length $salt == 32);
1364
1365 my $hash_in = sprintf ("%s:2:4:%s", $hash, $salt);
1366
1367 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1368 }
1369 # Cram MD5
1370 elsif ($mode == 10200)
1371 {
1372 next unless (substr ($line, 0, 10) eq '$cram_md5$');
1373
1374 # get hash
1375 my $index1 = index ($line, "\$", 10);
1376
1377 next if $index1 < 1;
1378
1379 # challenge
1380
1381 my $challengeb64 = substr ($line, 10, $index1 - 10);
1382 $salt = decode_base64 ($challengeb64);
1383
1384 # response
1385
1386 my $index2 = index ($line, ":", $index1 + 1);
1387
1388 next if $index2 < 1;
1389
1390 my $responseb64 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1391 my $response = decode_base64 ($responseb64);
1392
1393 $param = substr ($response, 0, length ($response) - 32 - 1); # -1 is for space
1394
1395 $word = substr ($line, $index2 + 1);
1396 $hash_in = substr ($line, 0, $index2);
1397
1398 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1399 }
1400 # SAP CODVN H (PWDSALTEDHASH) iSSHA-1
1401 elsif ($mode == 10300)
1402 {
1403 next unless (substr ($line, 0, 10) eq '{x-issha, ');
1404
1405 # get iterations
1406
1407 my $index1 = index ($line, "}", 10);
1408
1409 next if $index1 < 1;
1410
1411 $iter = substr ($line, 10, $index1 - 10);
1412
1413 $iter = int ($iter);
1414
1415 # base64 substring
1416
1417 my $base64_encoded = substr ($line, $index1 + 1);
1418 my $base64_decoded = decode_base64 ($base64_encoded);
1419
1420 $salt = substr ($base64_decoded, 20);
1421
1422 my $index2 = index ($line, ":", $index1 + 1);
1423
1424 next if $index2 < 1;
1425
1426 $word = substr ($line, $index2 + 1);
1427 $hash_in = substr ($line, 0, $index2);
1428
1429 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1430 }
1431 # PDF 1.1 - 1.3 (Acrobat 2 - 4)
1432 elsif ($mode == 10400)
1433 {
1434 ($hash_in, $word) = split ":", $line;
1435
1436 next unless defined $hash_in;
1437 next unless defined $word;
1438
1439 my @data = split /\*/, $hash_in;
1440
1441 next unless scalar @data == 11;
1442
1443 next unless (shift @data eq '$pdf$1');
1444 next unless (shift @data eq '2');
1445 next unless (shift @data eq '40');
1446 my $P = shift @data;
1447 next unless (shift @data eq '0');
1448 next unless (shift @data eq '16');
1449 my $id = shift @data;
1450 next unless (shift @data eq '32');
1451 my $u = shift @data;
1452 next unless (shift @data eq '32');
1453 my $o = shift @data;
1454
1455 $salt = $id;
1456 $param = $u;
1457 $param2 = $o;
1458 $param3 = $P;
1459
1460 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1461 }
1462 # PDF 1.4 - 1.6 (Acrobat 5 - 8)
1463 elsif ($mode == 10500)
1464 {
1465 ($hash_in, $word) = split ":", $line;
1466
1467 next unless defined $hash_in;
1468 next unless defined $word;
1469
1470 my @data = split /\*/, $hash_in;
1471
1472 next unless scalar @data == 11;
1473
1474 my $V = shift @data; $V = substr ($V, 5, 1);
1475 my $R = shift @data;
1476 next unless (shift @data eq '128');
1477 my $P = shift @data;
1478 my $enc = shift @data;
1479 next unless (shift @data eq '16');
1480 my $id = shift @data;
1481 next unless (shift @data eq '32');
1482 my $u = shift @data;
1483 next unless (shift @data eq '32');
1484 my $o = shift @data;
1485
1486 $salt = $id;
1487 $param = $u;
1488 $param2 = $o;
1489 $param3 = $P;
1490 $param4 = $V;
1491 $param5 = $R;
1492 $param6 = $enc;
1493
1494 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1495 }
1496 # PDF 1.7 Level 3 (Acrobat 9)
1497 elsif ($mode == 10600)
1498 {
1499 ($hash_in, $word) = split ":", $line;
1500
1501 next unless defined $hash_in;
1502 next unless defined $word;
1503
1504 my @data = split /\*/, $hash_in;
1505
1506 next unless scalar @data >= 11;
1507
1508 next unless (shift @data eq '$pdf$5');
1509 next unless (shift @data eq '5');
1510 next unless (shift @data eq '256');
1511 next unless (shift @data eq '-1028');
1512 next unless (shift @data eq '1');
1513 next unless (shift @data eq '16');
1514 my $id = shift @data;
1515 my $rest = join "*", @data;
1516
1517 $salt = $id;
1518 $param = $rest;
1519
1520 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1521 }
1522 # PDF 1.7 Level 8 (Acrobat 10 - 11)
1523 elsif ($mode == 10700)
1524 {
1525 ($hash_in, $word) = split ":", $line;
1526
1527 next unless defined $hash_in;
1528 next unless defined $word;
1529
1530 my @data = split /\*/, $hash_in;
1531
1532 next unless scalar @data >= 11;
1533
1534 next unless (shift @data eq '$pdf$5');
1535 next unless (shift @data eq '6');
1536 next unless (shift @data eq '256');
1537 next unless (shift @data eq '-1028');
1538 next unless (shift @data eq '1');
1539 next unless (shift @data eq '16');
1540 my $id = shift @data;
1541 my $rest = join "*", @data;
1542
1543 $salt = $id;
1544 $param = $rest;
1545
1546 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1547 }
1548 # PBKDF2-HMAC-SHA256
1549 elsif ($mode == 10900)
1550 {
1551 next unless (substr ($line, 0, 7) eq 'sha256:');
1552
1553 # iterations
1554 my $index1 = index ($line, ":", 7);
1555
1556 next if $index1 < 1;
1557
1558 $iter = substr ($line, 7, $index1 - 7);
1559
1560 # salt
1561
1562 my $index2 = index ($line, ":", $index1 + 1);
1563
1564 next if $index2 < 1;
1565
1566 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1567
1568 $salt = decode_base64 ($salt);
1569
1570 # end of digest
1571
1572 $index1 = index ($line, ":", $index2 + 1);
1573
1574 next if $index1 < 1;
1575
1576 # additional param = output len of pbkdf2
1577
1578 my $digest64_encoded = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1579
1580 my $digest = decode_base64 ($digest64_encoded);
1581
1582 $param = length ($digest);
1583
1584 # word / hash
1585
1586 $word = substr ($line, $index1 + 1);
1587 $hash_in = substr ($line, 0, $index1);
1588
1589 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1590 }
1591 # PostgreSQL MD5 Authentication
1592 elsif ($mode == 11100)
1593 {
1594 next unless (substr ($line, 0, 10) eq '$postgres$');
1595
1596 my $index1 = index ($line, "*", 10);
1597
1598 next if $index1 < 1;
1599
1600 # the user name
1601
1602 $param = substr ($line, 10, $index1 - 10);
1603
1604 # get the 4 byte salt
1605
1606 my $index2 = index ($line, "*", $index1 + 1);
1607
1608 next if $index2 < 1;
1609
1610 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1611
1612 # word / hash
1613
1614 $index1 = index ($line, ":", $index2 + 1);
1615
1616 next if $index1 < 1;
1617
1618 $word = substr ($line, $index1 + 1);
1619 $hash_in = substr ($line, 0, $index1);
1620
1621 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1622 }
1623 # MySQL MD5 Authentication
1624 elsif ($mode == 11200)
1625 {
1626 next unless (substr ($line, 0, 9) eq '$mysqlna$');
1627
1628 my $index1 = index ($line, "*", 9);
1629
1630 next if $index1 < 1;
1631
1632 # salt
1633
1634 $salt = substr ($line, 9, $index1 - 9);
1635
1636 # word / hash
1637
1638 $index1 = index ($line, ":", $index1 + 1);
1639
1640 next if $index1 < 1;
1641
1642 $word = substr ($line, $index1 + 1);
1643 $hash_in = substr ($line, 0, $index1);
1644
1645 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1646 }
1647 # WPA/WPA2
1648 elsif ($mode == 2500)
1649 {
1650 print "ERROR: verify currently not supported for WPA/WPA2 (because of oclHashcat's output format)\n";
1651
1652 exit (1);
1653 }
1654 # Bitcoin/Litecoin wallet.dat
1655 elsif ($mode == 11300)
1656 {
1657 print "ERROR: verify currently not supported for Bitcoin/Litecoin wallet.dat because of unknown crypt data\n";
1658
1659 exit (1);
1660 }
1661 # SIP digest authentication (MD5)
1662 elsif ($mode == 11400)
1663 {
1664 next unless (substr ($line, 0, 6) eq '$sip$*');
1665
1666 # URI_server:
1667
1668 my $index1 = index ($line, "*", 6);
1669
1670 next if $index1 < 0;
1671
1672 $param10 = substr ($line, 6, $index1 - 6);
1673
1674 next if (length ($param10) > 32);
1675
1676 # URI_client:
1677
1678 my $index2 = index ($line, "*", $index1 + 1);
1679
1680 next if $index2 < 0;
1681
1682 $param11 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1683
1684 next if (length ($param11) > 32);
1685
1686 # user:
1687
1688 $index1 = index ($line, "*", $index2 + 1);
1689
1690 next if $index1 < 0;
1691
1692 $param = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1693
1694 next if (length ($param) > 12);
1695
1696 # realm:
1697
1698 $index2 = index ($line, "*", $index1 + 1);
1699
1700 next if $index2 < 0;
1701
1702 $param2 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1703
1704 next if (length ($param2) > 20);
1705
1706 # method:
1707
1708 $index1 = index ($line, "*", $index2 + 1);
1709
1710 next if $index1 < 0;
1711
1712 $param6 = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1713
1714 next if (length ($param6) > 24);
1715
1716 # URI_prefix:
1717
1718 $index2 = index ($line, "*", $index1 + 1);
1719
1720 next if $index2 < 0;
1721
1722 $param7 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1723
1724 next if (length ($param7) > 10);
1725
1726 # URI_resource:
1727
1728 $index1 = index ($line, "*", $index2 + 1);
1729
1730 next if $index1 < 0;
1731
1732 $param8 = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1733
1734 next if (length ($param8) > 32);
1735
1736 # URI_suffix:
1737
1738 $index2 = index ($line, "*", $index1 + 1);
1739
1740 next if $index2 < 0;
1741
1742 $param9 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1743
1744 next if (length ($param9) > 32);
1745
1746 # nonce:
1747
1748 $index1 = index ($line, "*", $index2 + 1);
1749
1750 next if $index1 < 0;
1751
1752 $salt = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1753
1754 next if (length ($salt) > 34);
1755
1756 # nonce_client:
1757
1758 $index2 = index ($line, "*", $index1 + 1);
1759
1760 next if $index2 < 0;
1761
1762 $param4 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1763
1764 next if (length ($param4) > 12);
1765
1766 # nonce_count:
1767
1768 $index1 = index ($line, "*", $index2 + 1);
1769
1770 next if $index1 < 0;
1771
1772 $param3 = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1773
1774 next if (length ($param3) > 10);
1775
1776 # qop:
1777
1778 $index2 = index ($line, "*", $index1 + 1);
1779
1780 next if $index2 < 0;
1781
1782 $param5 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1783
1784 next if (length ($param5) > 8);
1785
1786 # directive:
1787
1788 $index1 = index ($line, "*", $index2 + 1);
1789
1790 next if $index1 < 0;
1791
1792 my $directive = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1793
1794 next unless ($directive eq "MD5");
1795
1796 # hash_buf:
1797
1798 $index2 = index ($line, ":", $index1 + 1);
1799
1800 next if $index2 < 0;
1801
1802 my $hex_digest = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1803
1804 next unless (length ($hex_digest) == 32);
1805
1806 $word = substr ($line, $index2 + 1);
1807 $hash_in = substr ($line, 0, $index2);
1808
1809 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1810 }
1811 # 7-Zip
1812 elsif ($mode == 11600)
1813 {
1814 next unless (substr ($line, 0, 4) eq '$7z$');
1815
1816 # p
1817
1818 my $index1 = index ($line, '$', 4);
1819
1820 next if $index1 < 0;
1821
1822 my $p = substr ($line, 4, $index1 - 4);
1823
1824 next unless ($p eq "0");
1825
1826 # num cycle power
1827
1828 my $index2 = index ($line, '$', $index1 + 1);
1829
1830 next if $index2 < 0;
1831
1832 $iter = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1833
1834 # seven zip salt length
1835
1836 $index1 = index ($line, '$', $index2 + 1);
1837
1838 next if $index1 < 0;
1839
1840 $param = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1841
1842 # seven zip salt
1843
1844 $index2 = index ($line, '$', $index1 + 1);
1845
1846 next if $index2 < 0;
1847
1848 $param2 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1849
1850 # salt len
1851
1852 $index1 = index ($line, '$', $index2 + 1);
1853
1854 next if $index1 < 0;
1855
1856 $param3 = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1857
1858 # salt
1859
1860 $index2 = index ($line, '$', $index1 + 1);
1861
1862 next if $index2 < 0;
1863
1864 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1865
1866 $salt = pack ("H*", $salt);
1867
1868 # crc / hash
1869
1870 $index1 = index ($line, '$', $index2 + 1);
1871
1872 next if $index1 < 0;
1873
1874 my $crc = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1875
1876 # ignore this crc, we don't need to pass it to gen_hash ()
1877
1878 # data len
1879
1880 $index2 = index ($line, '$', $index1 + 1);
1881
1882 next if $index2 < 0;
1883
1884 $param4 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1885
1886 # unpack size
1887
1888 $index1 = index ($line, '$', $index2 + 1);
1889
1890 next if $index1 < 0;
1891
1892 $param5 = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1893
1894 # data
1895
1896 $index2 = index ($line, ':', $index1 + 1);
1897
1898 next if $index2 < 0;
1899
1900 $param6 = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1901 $param6 = pack ("H*", $param6);
1902
1903 $word = substr ($line, $index2 + 1);
1904 $hash_in = substr ($line, 0, $index2);
1905
1906 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1907 }
1908 # PBKDF2-HMAC-MD5
1909 elsif ($mode == 11900)
1910 {
1911 next unless (substr ($line, 0, 4) eq 'md5:');
1912
1913 # iterations
1914 my $index1 = index ($line, ":", 4);
1915
1916 next if $index1 < 1;
1917
1918 $iter = substr ($line, 4, $index1 - 4);
1919
1920 # salt
1921
1922 my $index2 = index ($line, ":", $index1 + 1);
1923
1924 next if $index2 < 1;
1925
1926 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1927
1928 $salt = decode_base64 ($salt);
1929
1930 # end of digest
1931
1932 $index1 = index ($line, ":", $index2 + 1);
1933
1934 next if $index1 < 1;
1935
1936 # additional param = output len of pbkdf2
1937
1938 my $digest64_encoded = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1939
1940 my $digest = decode_base64 ($digest64_encoded);
1941
1942 $param = length ($digest);
1943
1944 # word / hash
1945
1946 $word = substr ($line, $index1 + 1);
1947 $hash_in = substr ($line, 0, $index1);
1948
1949 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1950 }
1951 # PBKDF2-HMAC-SHA1
1952 elsif ($mode == 12000)
1953 {
1954 next unless (substr ($line, 0, 5) eq 'sha1:');
1955
1956 # iterations
1957 my $index1 = index ($line, ":", 5);
1958
1959 next if $index1 < 1;
1960
1961 $iter = substr ($line, 5, $index1 - 5);
1962
1963 # salt
1964
1965 my $index2 = index ($line, ":", $index1 + 1);
1966
1967 next if $index2 < 1;
1968
1969 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
1970
1971 $salt = decode_base64 ($salt);
1972
1973 # end of digest
1974
1975 $index1 = index ($line, ":", $index2 + 1);
1976
1977 next if $index1 < 1;
1978
1979 # additional param = output len of pbkdf2
1980
1981 my $digest64_encoded = substr ($line, $index2 + 1, $index1 - $index2 - 1);
1982
1983 my $digest = decode_base64 ($digest64_encoded);
1984
1985 $param = length ($digest);
1986
1987 # word / hash
1988
1989 $word = substr ($line, $index1 + 1);
1990 $hash_in = substr ($line, 0, $index1);
1991
1992 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
1993 }
1994 # PBKDF2-HMAC-SHA512
1995 elsif ($mode == 12100)
1996 {
1997 next unless (substr ($line, 0, 7) eq 'sha512:');
1998
1999 # iterations
2000 my $index1 = index ($line, ":", 7);
2001
2002 next if $index1 < 1;
2003
2004 $iter = substr ($line, 7, $index1 - 7);
2005
2006 # salt
2007
2008 my $index2 = index ($line, ":", $index1 + 1);
2009
2010 next if $index2 < 1;
2011
2012 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
2013
2014 $salt = decode_base64 ($salt);
2015
2016 # end of digest
2017
2018 $index1 = index ($line, ":", $index2 + 1);
2019
2020 next if $index1 < 1;
2021
2022 # additional param = output len of pbkdf2
2023
2024 my $digest64_encoded = substr ($line, $index2 + 1, $index1 - $index2 - 1);
2025
2026 my $digest = decode_base64 ($digest64_encoded);
2027
2028 $param = length ($digest);
2029
2030 # word / hash
2031
2032 $word = substr ($line, $index1 + 1);
2033 $hash_in = substr ($line, 0, $index1);
2034
2035 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2036 }
2037 # ecryptfs
2038 elsif ($mode == 12200)
2039 {
2040 next unless (substr ($line, 0, 12) eq '$ecryptfs$0$');
2041
2042 # check if default salt
2043
2044 $param = 1;
2045
2046 $param = 0 if (substr ($line, 12, 2) eq '1$');
2047
2048 # salt
2049
2050 $salt = "";
2051
2052 my $index1 = 12;
2053
2054 if ($param == 0) # we need to extract the salt
2055 {
2056 $index1 = index ($line, '$', $index1);
2057
2058 next if $index1 < 1;
2059
2060 my $index2 = index ($line, '$', $index1 + 1);
2061
2062 next if $index2 < 1;
2063
2064 $salt = substr ($line, $index1 + 1, $index2 - $index1 - 1);
2065
2066 $index1 = $index2;
2067 }
2068
2069 $index1 = index ($line, ':', $index1 + 1);
2070
2071 next if $index1 < 1;
2072
2073 # word / hash
2074
2075 $word = substr ($line, $index1 + 1);
2076 $hash_in = substr ($line, 0, $index1);
2077
2078 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2079 }
2080 # Oracle T: Type (Oracle 12+)
2081 elsif ($mode == 12300)
2082 {
2083 my $index1 = index ($line, ':');
2084
2085 next if ($index1 != 160);
2086
2087 # salt
2088
2089 $salt = substr ($line, 128, 32);
2090
2091 # word / hash
2092
2093 $word = substr ($line, $index1 + 1);
2094 $hash_in = substr ($line, 0, $index1);
2095
2096 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2097 }
2098 # BSDiCrypt, Extended DES
2099 elsif ($mode == 12400)
2100 {
2101 next unless (substr ($line, 0, 1) eq '_');
2102
2103 my $index1 = index ($line, ':', 20);
2104
2105 next if ($index1 != 20);
2106
2107 # iter
2108
2109 $iter = substr ($line, 1, 4);
2110
2111 $iter = base64_to_int24 ($iter);
2112
2113 # salt
2114
2115 $salt = substr ($line, 5, 4);
2116
2117 # word / hash
2118
2119 $word = substr ($line, $index1 + 1);
2120 $hash_in = substr ($line, 0, $index1);
2121
2122 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2123 }
2124 # Blockchain, My Wallet
2125 elsif ($mode == 12700)
2126 {
2127 my $index1 = index ($line, ':');
2128
2129 next if ($index1 < 0);
2130
2131 $hash_in = substr ($line, 0, $index1);
2132 $word = substr ($line, $index1 + 1);
2133
2134 my (undef, $signature, $data_len, $data_buf) = split '\$', $hash_in;
2135
2136 next unless ($signature eq "blockchain");
2137
2138 next unless (($data_len * 2) == length $data_buf);
2139
2140 $salt = substr ($data_buf, 0, 32);
2141 $param = substr ($data_buf, 32);
2142
2143 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2144 }
2145 elsif ($mode == 12800)
2146 {
2147 ($hash_in, $word) = split ":", $line;
2148
2149 next unless defined $hash_in;
2150 next unless defined $word;
2151
2152 my @data = split /\,/, $hash_in;
2153
2154 next unless scalar @data == 4;
2155
2156 next unless (shift @data eq 'v1;PPH1_MD4');
2157
2158 $salt = shift @data;
2159 $iter = shift @data;
2160
2161 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2162 }
2163 elsif ($mode == 12900)
2164 {
2165 ($hash_in, $word) = split ":", $line;
2166
2167 next unless defined $hash_in;
2168 next unless defined $word;
2169
2170 next unless length $hash_in == 160;
2171
2172 $param = substr ($hash_in, 0, 64);
2173 $salt = substr ($hash_in, 128, 32);
2174 $iter = 4096;
2175
2176 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2177 }
2178 elsif ($mode == 13000)
2179 {
2180 my $hash_line;
2181
2182 ($hash_line, $word) = split ":", $line;
2183
2184 next unless defined $hash_line;
2185 next unless defined $word;
2186
2187 my @data = split ('\$', $hash_line);
2188
2189 next unless scalar @data == 8;
2190
2191 shift @data;
2192
2193 my $signature = shift @data;
2194 my $salt_len = shift @data;
2195 my $salt_buf = shift @data;
2196 my $iterations = shift @data;
2197 my $iv = shift @data;
2198 my $pswcheck_len = shift @data;
2199 my $pswcheck = shift @data;
2200
2201 next unless ($signature eq "rar5");
2202 next unless ($salt_len == 16);
2203 next unless ($pswcheck_len == 8);
2204
2205 $salt = $salt_buf;
2206 $iter = $iterations;
2207 $hash_in = $pswcheck;
2208 $param = $iv;
2209
2210 next unless (exists ($db->{$hash_line}) and (! defined ($db->{$hash_line})));
2211 }
2212 elsif ($mode == 13100 )
2213 {
2214 ($hash_in, $word) = split ":", $line;
2215
2216 next unless defined $hash_in;
2217 next unless defined $word;
2218
2219 my @data = split ('\$', $hash_in);
2220
2221 next unless scalar @data == 8;
2222
2223 shift @data;
2224
2225 my $signature = shift @data;
2226 my $algorithm = shift @data;
2227 my $user = shift @data;
2228 $user = substr ($user, 1);
2229 my $realm = shift @data;
2230 my $spn = shift @data;
2231 $spn = substr ($spn, 0, length ($spn) - 1);
2232 my $checksum = shift @data;
2233 my $edata2 = shift @data;
2234
2235 next unless ($signature eq "krb5tgs");
2236 next unless (length ($checksum) == 32);
2237 next unless (length ($edata2) >= 64);
2238
2239 $salt = $user . '$' . $realm . '$' . $spn . '$' . substr ($edata2, 0, 16);
2240
2241 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2242 }
2243 elsif ($mode == 13200)
2244 {
2245 ($hash_in, $word) = split ":", $line;
2246
2247 next unless defined $hash_in;
2248 next unless defined $word;
2249
2250 my @data = split ('\*', $hash_in);
2251
2252 next unless scalar @data == 5;
2253
2254 shift @data;
2255
2256 my $signature = shift @data;
2257 my $version = shift @data;
2258 my $iteration = shift @data;
2259 my $mysalt = shift @data;
2260 my $digest = shift @data;
2261
2262 next unless ($signature eq '$axcrypt$');
2263 next unless (length ($mysalt) == 32);
2264 next unless (length ($digest) == 48);
2265
2266 $salt = $iteration . '*' . $mysalt;
2267
2268 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2269 }
2270 else
2271 {
2272 print "ERROR: hash mode is not supported\n";
2273
2274 exit (1);
2275 }
2276
2277 if ($word =~ m/^\$HEX\[[0-9a-fA-F]*\]$/)
2278 {
2279 $word = pack ("H*", substr ($word, 5, -1));
2280 }
2281
2282 # finally generate the hash
2283
2284 # special case:
2285 if ($mode == 6800)
2286 {
2287 # check both variations
2288 $hash_out = gen_hash ($mode, $word, $salt, $iter, 1);
2289
2290 $len = length $hash_out; # == length $alternative
2291
2292 if (substr ($line, 0, $len) ne $hash_out)
2293 {
2294 my $alternative = gen_hash ($mode, $word, $salt, $iter, 2);
2295
2296 return unless (substr ($line, 0, $len) eq $alternative);
2297 }
2298 }
2299 elsif ($mode == 8700)
2300 {
2301 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2302
2303 $len = length $hash_out;
2304
2305 return unless (substr ($line, 0, $len) eq $hash_out);
2306 }
2307 elsif ($mode == 8900)
2308 {
2309 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3);
2310
2311 $len = length $hash_out;
2312
2313 return unless (substr ($line, 0, $len) eq $hash_out);
2314 }
2315 elsif ($mode == 9100)
2316 {
2317 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2318
2319 $len = length $hash_out;
2320
2321 return unless (substr ($line, 0, $len) eq $hash_out);
2322 }
2323 elsif ($mode == 190)
2324 {
2325 $hash_out = gen_hash ($mode, $word, $salt, $iter, 0);
2326
2327 $len = length $hash_out; # == length $alternative
2328
2329 if (substr ($line, 0, $len) ne $hash_out)
2330 {
2331 my $alternative = gen_hash ($mode, $word, $salt, $iter, 1);
2332
2333 return unless (substr ($line, 0, $len) eq $alternative);
2334 }
2335 }
2336 elsif ($mode == 3300)
2337 {
2338 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2339
2340 $len = length $hash_out;
2341
2342 return unless (substr ($line, 0, $len) eq $hash_out);
2343 }
2344 elsif ($mode == 5100)
2345 {
2346 # check 3 variants (start, middle, end)
2347
2348 my $idx = 0;
2349
2350 $hash_out = gen_hash ($mode, $word, $salt, $iter, $idx++);
2351
2352 $len = length $hash_out; # == length $alternative
2353
2354 if (substr ($line, 0, $len) ne $hash_out)
2355 {
2356 my $alternative = gen_hash ($mode, $word, $salt, $iter, $idx++);
2357
2358 if (substr ($line, 0, $len) ne $alternative)
2359 {
2360 my $alternative = gen_hash ($mode, $word, $salt, $iter, $idx++);
2361
2362 return unless (substr ($line, 0, $len) eq $alternative);
2363 }
2364 }
2365 }
2366 elsif ($mode == 9400)
2367 {
2368 $hash_out = gen_hash ($mode, $word, $salt, 50000, $param, $param2);
2369
2370 $len = length $hash_out;
2371
2372 return unless (substr ($line, 0, $len) eq $hash_out);
2373 }
2374 elsif ($mode == 9500)
2375 {
2376 $hash_out = gen_hash ($mode, $word, $salt, 100000, $param);
2377
2378 $len = length $hash_out;
2379
2380 return unless (substr ($line, 0, $len) eq $hash_out);
2381 }
2382 elsif ($mode == 9600)
2383 {
2384 $hash_out = gen_hash ($mode, $word, $salt, 100000, $param);
2385
2386 $len = length $hash_out;
2387
2388 return unless (substr ($line, 0, $len) eq $hash_out);
2389 }
2390 elsif ($mode == 9700)
2391 {
2392 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2);
2393
2394 $len = length $hash_out;
2395
2396 return unless (substr ($line, 0, $len) eq $hash_out);
2397 }
2398 elsif ($mode == 9800)
2399 {
2400 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2);
2401
2402 $len = length $hash_out;
2403
2404 return unless (substr ($line, 0, $len) eq $hash_out);
2405 }
2406 elsif ($mode == 10400)
2407 {
2408 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3);
2409
2410 $len = length $hash_out;
2411
2412 return unless (substr ($line, 0, $len) eq $hash_out);
2413 }
2414 elsif ($mode == 10500)
2415 {
2416 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3, $param4, $param5, $param6);
2417
2418 $len = length $hash_out;
2419
2420 return unless (substr ($line, 0, $len) eq $hash_out);
2421 }
2422 elsif ($mode == 10600)
2423 {
2424 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2425
2426 $len = length $hash_out;
2427
2428 return unless (substr ($line, 0, $len) eq $hash_out);
2429 }
2430 elsif ($mode == 10700)
2431 {
2432 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2433
2434 $len = length $hash_out;
2435
2436 return unless (substr ($line, 0, $len) eq $hash_out);
2437 }
2438 elsif ($mode == 10900)
2439 {
2440 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2441
2442 $len = length $hash_out;
2443
2444 return unless (substr ($line, 0, $len) eq $hash_out);
2445 }
2446 elsif ($mode == 11100)
2447 {
2448 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2449
2450 $len = length $hash_out;
2451
2452 return unless (substr ($line, 0, $len) eq $hash_out);
2453 }
2454 elsif ($mode == 11400)
2455 {
2456 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param, $param2, $param3, $param4, $param5, $param6, $param7, $param8, $param9, $param10, $param11);
2457
2458 $len = length $hash_out;
2459
2460 return unless (substr ($line, 0, $len) eq $hash_out);
2461 }
2462 elsif ($mode == 11600)
2463 {
2464 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param, $param2, $param3, $param4, $param5, $param6);
2465
2466 $len = length $hash_out;
2467
2468 return unless (substr ($line, 0, $len) eq $hash_out);
2469 }
2470 elsif ($mode == 11900)
2471 {
2472 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2473
2474 $len = length $hash_out;
2475
2476 return unless (substr ($line, 0, $len) eq $hash_out);
2477 }
2478 elsif ($mode == 12000)
2479 {
2480 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2481
2482 $len = length $hash_out;
2483
2484 return unless (substr ($line, 0, $len) eq $hash_out);
2485 }
2486 elsif ($mode == 12100)
2487 {
2488 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2489
2490 $len = length $hash_out;
2491
2492 return unless (substr ($line, 0, $len) eq $hash_out);
2493 }
2494 elsif ($mode == 12200)
2495 {
2496 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2497
2498 $len = length $hash_out;
2499
2500 return unless (substr ($line, 0, $len) eq $hash_out);
2501 }
2502 elsif ($mode == 12700)
2503 {
2504 # this is very special, we can't call gen_hash () because the param part is not always the same
2505 # we only know that it should contain the letters "guid" at the beginning of the decryted string
2506
2507 my $pbkdf2 = Crypt::PBKDF2->new (
2508 hash_class => 'HMACSHA1',
2509 iterations => 10,
2510 output_len => 32
2511 );
2512
2513 my $salt_bin = pack ("H*", $salt);
2514
2515 my $key = $pbkdf2->PBKDF2 ($salt_bin, $word);
2516
2517 my $cipher = Crypt::CBC->new ({
2518 key => $key,
2519 cipher => "Crypt::Rijndael",
2520 iv => $salt_bin,
2521 literal_key => 1,
2522 header => "none",
2523 keysize => 32
2524 });
2525
2526 my $param_bin = pack ("H*", $param);
2527
2528 my $decrypted = $cipher->decrypt ($param_bin);
2529
2530 my $decrypted_part = substr ($decrypted, 1, 16);
2531
2532 return unless ($decrypted_part =~ /"guid"/);
2533
2534 $hash_out = $hash_in;
2535 }
2536 elsif ($mode == 12900)
2537 {
2538 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2539
2540 $len = length $hash_out;
2541
2542 return unless (substr ($line, 0, $len) eq $hash_out);
2543 }
2544 elsif ($mode == 13000)
2545 {
2546 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2547
2548 $len = length $hash_out;
2549
2550 return unless (substr ($line, 0, $len) eq $hash_out);
2551 }
2552 elsif ($mode == 13100)
2553 {
2554 $hash_out = gen_hash ($mode, $word, $salt);
2555
2556 $len = length $hash_out;
2557
2558 return unless (substr ($line, 0, $len) eq $hash_out);
2559 }
2560 elsif ($mode == 13200)
2561 {
2562 $hash_out = gen_hash ($mode, $word, $salt);
2563
2564 $len = length $hash_out;
2565
2566 return unless (substr ($line, 0, $len) eq $hash_out);
2567 }
2568 else
2569 {
2570 $hash_out = gen_hash ($mode, $word, $salt, $iter);
2571
2572 $len = length $hash_out;
2573
2574 # special cases:
2575 if ($mode == 400)
2576 {
2577 # allow $P$ and $H$ for -m 400
2578 next unless (substr ($line, 3, $len - 3) eq substr ($hash_out, 3));
2579 }
2580 elsif ($mode == 5600)
2581 {
2582 # oclHashcat outputs the user name always upper-case, we need
2583 next unless (substr ($line, 0, $len) eq $hash_out);
2584
2585 my $found = 0;
2586
2587 my $hash_out_lower = lc ($hash_out);
2588
2589 for my $key (keys %{$db})
2590 {
2591 if (lc ($key) eq $hash_out_lower)
2592 {
2593 $found = 1;
2594
2595 last;
2596 }
2597 }
2598
2599 next unless $found;
2600 }
2601 else
2602 {
2603 next unless (substr ($line, 0, $len) eq $hash_out);
2604 }
2605 }
2606
2607 # do not forget "exists ($db->$hash_out)" should be done above!
2608 $db->{$hash_out} = $word;
2609 print OUT $line . "\n";
2610 }
2611
2612 close (IN);
2613 close (OUT);
2614 }
2615
2616 sub passthrough
2617 {
2618 my $mode = shift || 0;
2619
2620 while (my $word_buf = <>)
2621 {
2622 chomp ($word_buf);
2623
2624 next if length ($word_buf) > 31;
2625
2626 ##
2627 ## gen salt
2628 ##
2629
2630 my @salt_arr;
2631
2632 for (my $i = 0; $i < 256; $i++)
2633 {
2634 my $c = get_random_chr (0x30, 0x39);
2635
2636 push (@salt_arr, $c);
2637 }
2638
2639 my $salt_buf = join ("", @salt_arr);
2640
2641 ##
2642 ## gen hash
2643 ##
2644
2645 my $tmp_hash;
2646
2647 if ($mode == 0 || $mode == 100 || $mode == 101 || $mode == 190 || $mode == 200 || $mode == 300 || $mode == 600 || $mode == 900 || $mode == 1000 || $mode == 1400 || $mode == 1700 || $mode == 2400 || $mode == 2600 || $mode == 3500 || $mode == 4300 || $mode == 4400 || $mode == 4500 || $mode == 4600 || $mode == 4700 || $mode == 5000 || $mode == 5100 || $mode == 6000 || $mode == 6100 || $mode == 6900 || $mode == 5700 || $mode == 9900 || $mode == 10800 || $mode == 11500)
2648 {
2649 $tmp_hash = gen_hash ($mode, $word_buf, "");
2650 }
2651 elsif ($mode == 10 || $mode == 20 || $mode == 23 || $mode == 30 || $mode == 40 || $mode == 50 || $mode == 60 || $mode == 110 || $mode == 120 || $mode == 130 || $mode == 140 || $mode == 150 || $mode == 160 || $mode == 1410 || $mode == 1420 || $mode == 1430 || $mode == 1440 || $mode == 1450 || $mode == 1460 || $mode == 1710 || $mode == 1711 || $mode == 1720 || $mode == 1730 || $mode == 1740 || $mode == 1750 || $mode == 1760 || $mode == 3610 || $mode == 3710 || $mode == 3711 || $mode == 3720 || $mode == 3800 || $mode == 3910 || $mode == 4010 || $mode == 4110 || $mode == 4210 || $mode == 4900 || $mode == 8900 || $mode == 10000 || $mode == 10200 || $mode == 10900 || $mode == 11900 || $mode == 12000 || $mode == 12100)
2652 {
2653 my $salt_len = get_random_num (1, 15);
2654
2655 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2656 }
2657 elsif ($mode == 11 || $mode == 12 || $mode == 7600 || $mode == 12300)
2658 {
2659 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2660 }
2661 elsif ($mode == 21)
2662 {
2663 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 2));
2664 }
2665 elsif ($mode == 22)
2666 {
2667 my $salt_len = get_random_num (1, 11);
2668
2669 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2670 }
2671 elsif ($mode == 111 || $mode == 122 || $mode == 131 || $mode == 132 || $mode == 400 || $mode == 500 || $mode == 1600 || $mode == 1722 || $mode == 1731 || $mode == 1800 || $mode == 6300 || $mode == 7900 || $mode == 8100 || $mode == 11100)
2672 {
2673 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 8));
2674 }
2675 elsif ($mode == 112)
2676 {
2677 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 20));
2678 }
2679 elsif ($mode == 121)
2680 {
2681 my $salt_len = get_random_num (1, 9);
2682
2683 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2684 }
2685 elsif ($mode == 141 || $mode == 1441)
2686 {
2687 my $salt_len = get_random_num (1, 15);
2688
2689 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2690 }
2691 elsif ($mode == 1100)
2692 {
2693 my $salt_len = get_random_num (1, 19);
2694
2695 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2696 }
2697 elsif ($mode == 1500)
2698 {
2699 next if length ($word_buf) > 8;
2700
2701 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 2));
2702 }
2703 elsif ($mode == 2100)
2704 {
2705 next if length ($word_buf) > 13;
2706
2707 my $salt_len = get_random_num (1, 19);
2708
2709 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2710 }
2711 elsif ($mode == 2410)
2712 {
2713 next if length ($word_buf) > 15;
2714
2715 my $salt_len = get_random_num (1, 15);
2716
2717 my $word_len = length ($word_buf);
2718
2719 $salt_len = min ($salt_len, 15 - $word_len);
2720
2721 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2722 }
2723 elsif ($mode == 2500)
2724 {
2725 next if length ($word_buf) < 8;
2726
2727 my $salt_len = get_random_num (0, 32);
2728
2729 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2730 }
2731 elsif ($mode == 2611)
2732 {
2733 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 3));
2734 }
2735 elsif ($mode == 2612)
2736 {
2737 my $salt_len = get_random_num (1, 22);
2738
2739 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2740 }
2741 elsif ($mode == 2711)
2742 {
2743 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 30));
2744 }
2745 elsif ($mode == 2811)
2746 {
2747 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 5));
2748 }
2749 elsif ($mode == 3000)
2750 {
2751 next if length ($word_buf) > 7;
2752
2753 $tmp_hash = gen_hash ($mode, $word_buf, "");
2754 }
2755 elsif ($mode == 3100)
2756 {
2757 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 10));
2758 }
2759 elsif ($mode == 3200 || $mode == 5800 || $mode == 6400 || $mode == 6500 || $mode == 6700 || $mode == 7400 || $mode == 3300 || $mode == 8000 || $mode == 9100 || $mode == 12200)
2760 {
2761 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 16));
2762 }
2763 elsif ($mode == 3800 || $mode == 4900)
2764 {
2765 my $salt_len = get_random_num (1, 11);
2766
2767 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2768 }
2769 elsif ($mode == 4800)
2770 {
2771 $salt_buf = get_random_md5chap_salt (substr ($salt_buf, 0, 16));
2772
2773 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2774 }
2775 elsif ($mode == 5300 || $mode == 5400)
2776 {
2777 $salt_buf = get_random_ike_salt ();
2778
2779 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2780 }
2781 elsif ($mode == 5500)
2782 {
2783 my $user_len = get_random_num (0, 15);
2784 my $domain_len = get_random_num (0, 15);
2785
2786 $salt_buf = get_random_netntlmv1_salt ($user_len, $domain_len);
2787
2788 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2789 }
2790 elsif ($mode == 5600)
2791 {
2792 my $user_len = get_random_num (0, 15);
2793 my $domain_len = get_random_num (0, 15);
2794
2795 $salt_buf = get_random_netntlmv2_salt ($user_len, $domain_len);
2796
2797 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2798 }
2799 elsif ($mode == 6600)
2800 {
2801 $salt_buf = get_random_agilekeychain_salt ();
2802
2803 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2804 }
2805 elsif ($mode == 6800)
2806 {
2807 my $email_len = get_random_num (1, 15);
2808
2809 my $email = "";
2810
2811 for (my $i = 0; $i < $email_len; $i++)
2812 {
2813 $email .= get_random_chr (0x61, 0x7a);
2814 }
2815
2816 $email .= '@trash-mail.com';
2817
2818 $tmp_hash = gen_hash ($mode, $word_buf, $email);
2819 }
2820 elsif ($mode == 7100)
2821 {
2822 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 64));
2823 }
2824 elsif ($mode == 7200)
2825 {
2826 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 128));
2827 }
2828 elsif ($mode == 7300)
2829 {
2830 my $salt_len = get_random_num (32, 256);
2831
2832 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2833 }
2834 elsif ($mode == 7500)
2835 {
2836 $salt_buf = get_random_kerberos5_salt (substr ($salt_buf, 0, 16));
2837
2838 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2839 }
2840 elsif ($mode == 7700)
2841 {
2842 next if length ($word_buf) > 8;
2843
2844 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 12));
2845 }
2846 elsif ($mode == 7800)
2847 {
2848 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 12));
2849 }
2850 elsif ($mode == 8200)
2851 {
2852 $salt_buf = get_random_cloudkeychain_salt ();
2853
2854 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2855 }
2856 elsif ($mode == 8300)
2857 {
2858 $salt_buf = get_random_dnssec_salt ();
2859
2860 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2861 }
2862 elsif ($mode == 8400 || $mode == 11200)
2863 {
2864 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 40));
2865 }
2866 elsif ($mode == 8500)
2867 {
2868 next if length ($word_buf) > 8;
2869
2870 my $salt_len = get_random_num (1, 9);
2871
2872 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2873 }
2874 elsif ($mode == 8600)
2875 {
2876 next if length ($word_buf) > 16;
2877
2878 $tmp_hash = gen_hash ($mode, $word_buf, "");
2879 }
2880 elsif ($mode == 8700)
2881 {
2882 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 5));
2883 }
2884 elsif ($mode == 9200 || $mode == 9300)
2885 {
2886 my $salt_len = 14;
2887
2888 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2889 }
2890 elsif ($mode == 9400 || $mode == 9500 || $mode == 9600 || $mode == 9700 || $mode == 9800)
2891 {
2892 next if length ($word_buf) > 19;
2893
2894 my $salt_len = 32;
2895
2896 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2897 }
2898 elsif ($mode == 10100)
2899 {
2900 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2901 }
2902 elsif ($mode == 10300)
2903 {
2904 my $salt_len = get_random_num (4, 15);
2905
2906 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2907 }
2908 elsif ($mode == 10400)
2909 {
2910 next if length ($word_buf) > 31;
2911
2912 my $salt_len = 32;
2913
2914 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2915 }
2916 elsif ($mode == 10500)
2917 {
2918 next if length ($word_buf) > 15;
2919
2920 my $salt_len = 32;
2921
2922 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2923 }
2924 elsif ($mode == 10600)
2925 {
2926 next if length ($word_buf) > 31;
2927
2928 my $salt_len = 32;
2929
2930 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2931 }
2932 elsif ($mode == 10700)
2933 {
2934 next if length ($word_buf) > 15;
2935
2936 my $salt_len = 32;
2937
2938 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2939 }
2940 elsif ($mode == 11000)
2941 {
2942 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 56));
2943 }
2944 elsif ($mode == 11300)
2945 {
2946 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 16));
2947 }
2948 elsif ($mode == 11400)
2949 {
2950 next if length ($word_buf) > 24;
2951
2952 my $salt_len = get_random_num (1, 15);
2953
2954 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2955 }
2956 elsif ($mode == 11600)
2957 {
2958 my $salt_len = get_random_num (0, 16);
2959
2960 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2961 }
2962 elsif ($mode == 12400)
2963 {
2964 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 4));
2965 }
2966 elsif ($mode == 12600)
2967 {
2968 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 64));
2969 }
2970 elsif ($mode == 12700)
2971 {
2972 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2973 }
2974 elsif ($mode == 12800)
2975 {
2976 next if length ($word_buf) > 24;
2977
2978 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 20));
2979 }
2980 elsif ($mode == 12900)
2981 {
2982 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2983 }
2984 elsif ($mode == 13000)
2985 {
2986 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2987 }
2988 elsif ($mode == 13100)
2989 {
2990 $salt_buf = get_random_kerberos5_tgs_salt ();
2991
2992 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2993 }
2994 elsif ($mode == 13200)
2995 {
2996 $salt_buf = get_random_axcrypt_salt ();
2997
2998 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2999 }
3000 else
3001 {
3002 print "ERROR: Unsupported hash type\n";
3003
3004 exit (1);
3005 }
3006
3007 print $tmp_hash, "\n";
3008 }
3009 }
3010
3011 sub single
3012 {
3013 my $mode = shift;
3014
3015 if (defined $mode)
3016 {
3017 @modes = ($mode);
3018 }
3019
3020 for (my $j = 0; $j < scalar @modes; $j++)
3021 {
3022 my $mode = $modes[$j];
3023
3024 if ($mode == 0 || $mode == 100 || $mode == 101 || $mode == 190 || $mode == 200 || $mode == 300 || $mode == 600 || $mode == 900 || $mode == 1000 || $mode == 1400 || $mode == 1700 || $mode == 2400 || $mode == 2600 || $mode == 3500 || $mode == 4300 || $mode == 4400 || $mode == 4500 || $mode == 4600 || $mode == 4700 || $mode == 5000 || $mode == 5100 || $mode == 5300 || $mode == 5400 || $mode == 6000 || $mode == 6100 || $mode == 6600 || $mode == 6900 || $mode == 5700 || $mode == 8200 || $mode == 8300 || $mode == 9900 || $mode == 10800 || $mode == 11500)
3025 {
3026 for (my $i = 1; $i < 32; $i++)
3027 {
3028 if ($len != 0)
3029 {
3030 rnd ($mode, $len, 0);
3031 }
3032 else
3033 {
3034 rnd ($mode, $i, 0);
3035 }
3036 }
3037 }
3038 elsif ($mode == 10 || $mode == 20 || $mode == 23 || $mode == 30 || $mode == 40 || $mode == 50 || $mode == 60 || $mode == 110 || $mode == 120 || $mode == 121 || $mode == 130 || $mode == 140 || $mode == 150 || $mode == 160 || $mode == 1410 || $mode == 1420 || $mode == 1430 || $mode == 1440 || $mode == 1450 || $mode == 1460 || $mode == 1710 || $mode == 1711 || $mode == 1720 || $mode == 1730 || $mode == 1740 || $mode == 1750 || $mode == 1760 || $mode == 2410 || $mode == 3610 || $mode == 3710 || $mode == 3711 || $mode == 3720 || $mode == 3910 || $mode == 4010 || $mode == 4110 || $mode == 4210 || $mode == 8900 || $mode == 10000 || $mode == 10200 || $mode == 10900 || $mode == 11900 || $mode == 12000 || $mode == 12100)
3039 {
3040 my $salt_len = get_random_num (1, 15);
3041
3042 for (my $i = 1; $i < 32; $i++)
3043 {
3044 if ($len != 0)
3045 {
3046 rnd ($mode, $len, $salt_len);
3047 }
3048 else
3049 {
3050 rnd ($mode, $i, $salt_len);
3051 }
3052 }
3053 }
3054 elsif ($mode == 11 || $mode == 12 || $mode == 7600 || $mode == 12300)
3055 {
3056 for (my $i = 1; $i < 32; $i++)
3057 {
3058 if ($len != 0)
3059 {
3060 rnd ($mode, $len, 32);
3061 }
3062 else
3063 {
3064 rnd ($mode, $i, 32);
3065 }
3066 }
3067 }
3068 elsif ($mode == 21 || $mode == 22)
3069 {
3070 for (my $i = 1; $i < 32; $i++)
3071 {
3072 if ($len != 0)
3073 {
3074 rnd ($mode, $len, 2);
3075 }
3076 else
3077 {
3078 rnd ($mode, $i, 2);
3079 }
3080 }
3081 }
3082 elsif ($mode == 111 || $mode == 122 || $mode == 131 || $mode == 132 || $mode == 400 || $mode == 500 || $mode == 1600 || $mode == 1722 || $mode == 1731 || $mode == 6300 || $mode == 7900 || $mode == 8100 || $mode == 11100)
3083 {
3084 for (my $i = 1; $i < 32; $i++)
3085 {
3086 if ($len != 0)
3087 {
3088 rnd ($mode, $len, 8);
3089 }
3090 else
3091 {
3092 rnd ($mode, $i, 8);
3093 }
3094 }
3095 }
3096 elsif ($mode == 112)
3097 {
3098 for (my $i = 1; $i < 32; $i++)
3099 {
3100 if ($len != 0)
3101 {
3102 rnd ($mode, $len, 20);
3103 }
3104 else
3105 {
3106 rnd ($mode, $i, 20);
3107 }
3108 }
3109 }
3110 elsif ($mode == 141 || $mode == 3300 || $mode == 1441 || $mode == 1800 || $mode == 3200 || $mode == 4800 || $mode == 6400 || $mode == 6500 || $mode == 6700 || $mode == 7400 || $mode == 8000 || $mode == 9100 || $mode == 12200)
3111 {
3112 for (my $i = 1; $i < 32; $i++)
3113 {
3114 if ($len != 0)
3115 {
3116 rnd ($mode, $len, 16);
3117 }
3118 else
3119 {
3120 rnd ($mode, $i, 16);
3121 }
3122 }
3123 }
3124 if ($mode == 1100)
3125 {
3126 my $salt_len = get_random_num (1, 19);
3127
3128 for (my $i = 1; $i < 32; $i++)
3129 {
3130 if ($len != 0)
3131 {
3132 rnd ($mode, $len, $salt_len);
3133 }
3134 else
3135 {
3136 rnd ($mode, $i, $salt_len);
3137 }
3138 }
3139 }
3140 elsif ($mode == 1500)
3141 {
3142 for (my $i = 1; $i < 9; $i++)
3143 {
3144 if ($len != 0)
3145 {
3146 rnd ($mode, $len, 2);
3147 }
3148 else
3149 {
3150 rnd ($mode, $i, 2);
3151 }
3152 }
3153 }
3154 elsif ($mode == 2100)
3155 {
3156 my $salt_len = get_random_num (1, 19);
3157
3158 for (my $i = 1; $i < 13; $i++)
3159 {
3160 if ($len != 0)
3161 {
3162 rnd ($mode, $len, $salt_len);
3163 }
3164 else
3165 {
3166 rnd ($mode, $i, $salt_len);
3167 }
3168 }
3169 }
3170 elsif ($mode == 2500)
3171 {
3172 my $salt_len = get_random_num (0, 32);
3173
3174 for (my $i = 8; $i < 16; $i++)
3175 {
3176 my $generate_from_len = 0;
3177
3178 if ($len != 0)
3179 {
3180 if ($len < 8)
3181 {
3182 $len += 7;
3183 }
3184
3185 rnd ($mode, $len, $salt_len);
3186 }
3187 else
3188 {
3189 rnd ($mode, $i, $salt_len);
3190 }
3191 }
3192 }
3193 elsif ($mode == 2611)
3194 {
3195 for (my $i = 1; $i < 32; $i++)
3196 {
3197 if ($len != 0)
3198 {
3199 rnd ($mode, $len, 3);
3200 }
3201 else
3202 {
3203 rnd ($mode, $i, 3);
3204 }
3205 }
3206 }
3207 elsif ($mode == 2612)
3208 {
3209 my $salt_len = get_random_num (1, 22);
3210
3211 for (my $i = 1; $i < 32; $i++)
3212 {
3213 if ($len != 0)
3214 {
3215 rnd ($mode, $len, $salt_len);
3216 }
3217 else
3218 {
3219 rnd ($mode, $i, $salt_len);
3220 }
3221 }
3222 }
3223 elsif ($mode == 2711)
3224 {
3225 for (my $i = 1; $i < 32; $i++)
3226 {
3227 if ($len != 0)
3228 {
3229 rnd ($mode, $len, 30);
3230 }
3231 else
3232 {
3233 rnd ($mode, $i, 30);
3234 }
3235 }
3236 }
3237 elsif ($mode == 2811)
3238 {
3239 for (my $i = 1; $i < 32; $i++)
3240 {
3241 if ($len != 0)
3242 {
3243 rnd ($mode, $len, 5);
3244 }
3245 else
3246 {
3247 rnd ($mode, $i, 5);
3248 }
3249 }
3250 }
3251 elsif ($mode == 3000)
3252 {
3253 for (my $i = 1; $i < 8; $i++)
3254 {
3255 if ($len != 0)
3256 {
3257 rnd ($mode, $len, 0);
3258 }
3259 else
3260 {
3261 rnd ($mode, $i, 0);
3262 }
3263 }
3264 }
3265 elsif ($mode == 3100)
3266 {
3267 for (my $i = 1; $i < 32; $i++)
3268 {
3269 if ($len != 0)
3270 {
3271 rnd ($mode, $len, 10);
3272 }
3273 else
3274 {
3275 rnd ($mode, $i, 10);
3276 }
3277 }
3278 }
3279 elsif ($mode == 3800 || $mode == 4900)
3280 {
3281 my $salt_len = get_random_num (1, 11);
3282
3283 for (my $i = 1; $i < 32; $i++)
3284 {
3285 if ($len != 0)
3286 {
3287 rnd ($mode, $len, $salt_len);
3288 }
3289 else
3290 {
3291 rnd ($mode, $i, $salt_len);
3292 }
3293 }
3294 }
3295 elsif ($mode == 5500 || $mode == 5600)
3296 {
3297 my $salt_len;
3298
3299 for (my $i = 1; $i < 27; $i++)
3300 {
3301 $salt_len = get_random_num (1, 15);
3302
3303 if ($len != 0)
3304 {
3305 rnd ($mode, $len, $salt_len);
3306 }
3307 else
3308 {
3309 rnd ($mode, $i, $salt_len);
3310 }
3311 }
3312 }
3313 elsif ($mode == 5800)
3314 {
3315 for (my $i = 1; $i < 14; $i++)
3316 {
3317 if ($len != 0)
3318 {
3319 rnd ($mode, $len, 16);
3320 }
3321 else
3322 {
3323 rnd ($mode, $i, 16);
3324 }
3325 }
3326 }
3327 elsif ($mode == 6800)
3328 {
3329 my $salt_len = get_random_num (8, 25);
3330
3331 for (my $i = 1; $i < 32; $i++)
3332 {
3333 if ($len != 0)
3334 {
3335 rnd ($mode, $len, $salt_len);
3336 }
3337 else
3338 {
3339 rnd ($mode, $i, $salt_len);
3340 }
3341 }
3342 }
3343 elsif ($mode == 7100)
3344 {
3345 for (my $i = 1; $i < 32; $i++)
3346 {
3347 if ($len != 0)
3348 {
3349 rnd ($mode, $len, 64);
3350 }
3351 else
3352 {
3353 rnd ($mode, $i, 64);
3354 }
3355 }
3356 }
3357 elsif ($mode == 7200)
3358 {
3359 for (my $i = 1; $i < 32; $i++)
3360 {
3361 if ($len != 0)
3362 {
3363 rnd ($mode, $len, 128);
3364 }
3365 else
3366 {
3367 rnd ($mode, $i, 128);
3368 }
3369 }
3370 }
3371 elsif ($mode == 7300)
3372 {
3373 my $salt_len = get_random_num (32, 255);
3374
3375 for (my $i = 1; $i < 32; $i++)
3376 {
3377 if ($len != 0)
3378 {
3379 rnd ($mode, $len, $salt_len);
3380 }
3381 else
3382 {
3383 rnd ($mode, $i, $salt_len);
3384 }
3385 }
3386 }
3387 elsif ($mode == 7500)
3388 {
3389 for (my $i = 1; $i < 27; $i++)
3390 {
3391 if ($len != 0)
3392 {
3393 rnd ($mode, $len, 16);
3394 }
3395 else
3396 {
3397 rnd ($mode, $i, 16);
3398 }
3399 }
3400 }
3401 elsif ($mode == 7700)
3402 {
3403 my $salt_len = get_random_num (1, 12);
3404
3405 for (my $i = 1; $i < 9; $i++)
3406 {
3407 if ($len != 0)
3408 {
3409 rnd ($mode, $len, $salt_len);
3410 }
3411 else
3412 {
3413 rnd ($mode, $i, $salt_len);
3414 }
3415 }
3416 }
3417 elsif ($mode == 7800)
3418 {
3419 my $salt_len = get_random_num (1, 12);
3420
3421 for (my $i = 1; $i < 32; $i++)
3422 {
3423 if ($len != 0)
3424 {
3425 rnd ($mode, $len, $salt_len);
3426 }
3427 else
3428 {
3429 rnd ($mode, $i, $salt_len);
3430 }
3431 }
3432 }
3433 elsif ($mode == 8400 || $mode == 11200)
3434 {
3435 for (my $i = 1; $i < 32; $i++)
3436 {
3437 if ($len != 0)
3438 {
3439 rnd ($mode, $len, 40);
3440 }
3441 else
3442 {
3443 rnd ($mode, $i, 40);
3444 }
3445 }
3446 }
3447 elsif ($mode == 8500)
3448 {
3449 my $salt_len = get_random_num (1, 8);
3450
3451 for (my $i = 1; $i < 9; $i++)
3452 {
3453 if ($len != 0)
3454 {
3455 rnd ($mode, $len, $salt_len);
3456 }
3457 else
3458 {
3459 rnd ($mode, $i, $salt_len);
3460 }
3461 }
3462 }
3463 elsif ($mode == 8600)
3464 {
3465 for (my $i = 1; $i < 17; $i++)
3466 {
3467 if ($len != 0)
3468 {
3469 rnd ($mode, $len, 0);
3470 }
3471 else
3472 {
3473 rnd ($mode, $i, 0);
3474 }
3475 }
3476 }
3477 elsif ($mode == 8700)
3478 {
3479 for (my $i = 1; $i < 32; $i++)
3480 {
3481 if ($len != 0)
3482 {
3483 rnd ($mode, $len, 5);
3484 }
3485 else
3486 {
3487 rnd ($mode, $i, 5);
3488 }
3489 }
3490 }
3491 elsif ($mode == 9200 || $mode == 9300)
3492 {
3493 my $salt_len = 14;
3494
3495 for (my $i = 1; $i < 32; $i++)
3496 {
3497 if ($len != 0)
3498 {
3499 rnd ($mode, $len, $salt_len);
3500 }
3501 else
3502 {
3503 rnd ($mode, $i, $salt_len);
3504 }
3505 }
3506 }
3507 elsif ($mode == 9400 || $mode == 9500 || $mode == 9600 || $mode == 9700 || $mode == 9800)
3508 {
3509 my $salt_len = 32;
3510
3511 for (my $i = 1; $i < 20; $i++)
3512 {
3513 if ($len != 0)
3514 {
3515 rnd ($mode, $len, $salt_len);
3516 }
3517 else
3518 {
3519 rnd ($mode, $i, $salt_len);
3520 }
3521 }
3522 }
3523 elsif ($mode == 10100)
3524 {
3525 for (my $i = 1; $i < 32; $i++)
3526 {
3527 if ($len != 0)
3528 {
3529 rnd ($mode, $len, 32);
3530 }
3531 else
3532 {
3533 rnd ($mode, $i, 32);
3534 }
3535 }
3536 }
3537 elsif ($mode == 10300)
3538 {
3539 my $salt_len = get_random_num (4, 15);
3540
3541 for (my $i = 1; $i < 32; $i++)
3542 {
3543 if ($len != 0)
3544 {
3545 rnd ($mode, $len, $salt_len);
3546 }
3547 else
3548 {
3549 rnd ($mode, $i, $salt_len);
3550 }
3551 }
3552 }
3553 elsif ($mode == 10400 || $mode == 10600)
3554 {
3555 my $salt_len = 32;
3556
3557 for (my $i = 1; $i < 32; $i++)
3558 {
3559 if ($len != 0)
3560 {
3561 rnd ($mode, $len, $salt_len);
3562 }
3563 else
3564 {
3565 rnd ($mode, $i, $salt_len);
3566 }
3567 }
3568 }
3569 elsif ($mode == 10500 || $mode == 10700)
3570 {
3571 my $salt_len = 32;
3572
3573 for (my $i = 1; $i < 16; $i++)
3574 {
3575 if ($len != 0)
3576 {
3577 rnd ($mode, $len, $salt_len);
3578 }
3579 else
3580 {
3581 rnd ($mode, $i, $salt_len);
3582 }
3583 }
3584 }
3585 elsif ($mode == 11000)
3586 {
3587 for (my $i = 1; $i < 32; $i++)
3588 {
3589 if ($len != 0)
3590 {
3591 rnd ($mode, $len, 56);
3592 }
3593 else
3594 {
3595 rnd ($mode, $i, 56);
3596 }
3597 }
3598 }
3599 elsif ($mode == 11300)
3600 {
3601 for (my $i = 1; $i < 32; $i++)
3602 {
3603 if ($len != 0)
3604 {
3605 rnd ($mode, $len, 16);
3606 }
3607 else
3608 {
3609 rnd ($mode, $i, 16);
3610 }
3611 }
3612 }
3613 elsif ($mode == 11400)
3614 {
3615 for (my $i = 1; $i < 24; $i++)
3616 {
3617 if ($len != 0)
3618 {
3619 rnd ($mode, $len, 16);
3620 }
3621 else
3622 {
3623 rnd ($mode, $i, 16);
3624 }
3625 }
3626 }
3627 elsif ($mode == 11600)
3628 {
3629 my $salt_len = get_random_num (0, 16);
3630
3631 for (my $i = 1; $i < 32; $i++)
3632 {
3633 if ($len != 0)
3634 {
3635 rnd ($mode, $len, $salt_len);
3636 }
3637 else
3638 {
3639 rnd ($mode, $i, $salt_len);
3640 }
3641 }
3642 }
3643 elsif ($mode == 12400)
3644 {
3645 for (my $i = 1; $i < 32; $i++)
3646 {
3647 if ($len != 0)
3648 {
3649 rnd ($mode, $len, 4);
3650 }
3651 else
3652 {
3653 rnd ($mode, $i, 4);
3654 }
3655 }
3656 }
3657 elsif ($mode == 12600)
3658 {
3659 for (my $i = 1; $i < 32; $i++)
3660 {
3661 if ($len != 0)
3662 {
3663 rnd ($mode, $len, 64);
3664 }
3665 else
3666 {
3667 rnd ($mode, $i, 64);
3668 }
3669 }
3670 }
3671 elsif ($mode == 12700)
3672 {
3673 for (my $i = 1; $i < 32; $i++)
3674 {
3675 if ($len != 0)
3676 {
3677 rnd ($mode, $len, 32);
3678 }
3679 else
3680 {
3681 rnd ($mode, $i, 32);
3682 }
3683 }
3684 }
3685 elsif ($mode == 12800)
3686 {
3687 for (my $i = 1; $i < 25; $i++)
3688 {
3689 if ($len != 0)
3690 {
3691 rnd ($mode, $len, 20);
3692 }
3693 else
3694 {
3695 rnd ($mode, $i, 20);
3696 }
3697 }
3698 }
3699 elsif ($mode == 12900)
3700 {
3701 for (my $i = 1; $i < 32; $i++)
3702 {
3703 if ($len != 0)
3704 {
3705 rnd ($mode, $len, 32);
3706 }
3707 else
3708 {
3709 rnd ($mode, $i, 32);
3710 }
3711 }
3712 }
3713 elsif ($mode == 13000)
3714 {
3715 for (my $i = 1; $i < 32; $i++)
3716 {
3717 if ($len != 0)
3718 {
3719 rnd ($mode, $len, 32);
3720 }
3721 else
3722 {
3723 rnd ($mode, $i, 32);
3724 }
3725 }
3726 }
3727 elsif ($mode == 13100)
3728 {
3729 for (my $i = 1; $i < 27; $i++)
3730 {
3731 if ($len != 0)
3732 {
3733 rnd ($mode, $len, 16);
3734 }
3735 else
3736 {
3737 rnd ($mode, $i, 16);
3738 }
3739 }
3740 }
3741 elsif ($mode == 13200)
3742 {
3743 for (my $i = 1; $i < 32; $i++)
3744 {
3745 if ($len != 0)
3746 {
3747 rnd ($mode, $len, 32);
3748 }
3749 else
3750 {
3751 rnd ($mode, $i, 32);
3752 }
3753 }
3754 }
3755 }
3756 }
3757
3758 exit;
3759
3760 sub gen_hash
3761 {
3762 my $mode = shift;
3763
3764 my $word_buf = shift;
3765
3766 my $salt_buf = shift;
3767
3768 my $iter = shift;
3769
3770 my $additional_param = shift;
3771
3772 my $additional_param2 = shift;
3773
3774 my $additional_param3 = shift;
3775
3776 my $additional_param4 = shift;
3777
3778 my $additional_param5 = shift;
3779
3780 my $additional_param6 = shift;
3781
3782 my $additional_param7 = shift;
3783
3784 my $additional_param8 = shift;
3785
3786 my $additional_param9 = shift;
3787
3788 my $additional_param10 = shift;
3789
3790 my $additional_param11 = shift;
3791
3792 ##
3793 ## gen hash
3794 ##
3795
3796 my $tmp_hash;
3797
3798 my $hash_buf;
3799
3800 if ($mode == 0)
3801 {
3802 $hash_buf = md5_hex ($word_buf);
3803
3804 $tmp_hash = sprintf ("%s", $hash_buf);
3805 }
3806 elsif ($mode == 10)
3807 {
3808 $hash_buf = md5_hex ($word_buf . $salt_buf);
3809
3810 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3811 }
3812 elsif ($mode == 11)
3813 {
3814 $hash_buf = md5_hex ($word_buf . $salt_buf);
3815
3816 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3817 }
3818 elsif ($mode == 12)
3819 {
3820 $hash_buf = md5_hex ($word_buf . $salt_buf);
3821
3822 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3823 }
3824 elsif ($mode == 20)
3825 {
3826 $hash_buf = md5_hex ($salt_buf . $word_buf);
3827
3828 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3829 }
3830 elsif ($mode == 21)
3831 {
3832 $hash_buf = md5_hex ($salt_buf . $word_buf);
3833
3834 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3835 }
3836 elsif ($mode == 22)
3837 {
3838 my $itoa64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3839 my $salt_suffix = "Administration Tools";
3840
3841 my $pass = sprintf ("%s:%s:%s", $salt_buf, $salt_suffix, $word_buf);
3842
3843 $hash_buf = md5 ($pass);
3844
3845 my $res = "";
3846
3847 for (my $pos = 0; $pos < 16; $pos += 2)
3848 {
3849 my $octet1 = ord (substr ($hash_buf, $pos + 0, 1));
3850 my $octet2 = ord (substr ($hash_buf, $pos + 1, 1));
3851
3852 my $num = ($octet1 <<8 & 0xff00) | ($octet2 & 0xff);
3853
3854 my $idx1 = $num >> 12 & 0x0f;
3855 my $idx2 = $num >> 6 & 0x3f;
3856 my $idx3 = $num & 0x3f;
3857
3858 $res = $res . substr ($itoa64, $idx1, 1) . substr ($itoa64, $idx2, 1) . substr ($itoa64, $idx3, 1);
3859 }
3860
3861 my $obfuscate_str = "nrcstn";
3862 my @obfuscate_pos = (0, 6, 12, 17, 23, 29);
3863
3864 foreach my $pos (keys @obfuscate_pos)
3865 {
3866 my $idx = $obfuscate_pos[$pos];
3867 my $before = substr ($res, 0, $idx);
3868 my $char = substr ($obfuscate_str, $pos, 1);
3869 my $after = substr ($res, $idx);
3870
3871 $res = sprintf ("%s%s%s", $before, $char, $after);
3872 }
3873
3874 $tmp_hash = sprintf ("%s:%s", $res, $salt_buf);
3875 }
3876 elsif ($mode == 23)
3877 {
3878 $hash_buf = md5_hex ($salt_buf . "\nskyper\n" . $word_buf);
3879
3880 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3881 }
3882 elsif ($mode == 30)
3883 {
3884 $hash_buf = md5_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
3885
3886 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3887 }
3888 elsif ($mode == 40)
3889 {
3890 $hash_buf = md5_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
3891
3892 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3893 }
3894 elsif ($mode == 50)
3895 {
3896 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&md5, 64);
3897
3898 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3899 }
3900 elsif ($mode == 60)
3901 {
3902 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&md5, 64);
3903
3904 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3905 }
3906 elsif ($mode == 100)
3907 {
3908 $hash_buf = sha1_hex ($word_buf);
3909
3910 $tmp_hash = sprintf ("%s", $hash_buf);
3911 }
3912 elsif ($mode == 101)
3913 {
3914 $hash_buf = sha1 ($word_buf);
3915
3916 my $base64_buf = encode_base64 ($hash_buf);
3917
3918 chomp ($base64_buf);
3919
3920 $tmp_hash = sprintf ("{SHA}%s", $base64_buf);
3921 }
3922 elsif ($mode == 110)
3923 {
3924 $hash_buf = sha1_hex ($word_buf . $salt_buf);
3925
3926 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3927 }
3928 elsif ($mode == 111)
3929 {
3930 $hash_buf = sha1 ($word_buf . $salt_buf);
3931
3932 my $base64_buf = encode_base64 ($hash_buf . $salt_buf);
3933
3934 chomp ($base64_buf);
3935
3936 $tmp_hash = sprintf ("{SSHA}%s", $base64_buf);
3937 }
3938 elsif ($mode == 112)
3939 {
3940 my $salt_buf_bin = pack ("H*", $salt_buf);
3941
3942 $hash_buf = sha1_hex ($word_buf . $salt_buf_bin);
3943
3944 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3945 }
3946 elsif ($mode == 120)
3947 {
3948 $hash_buf = sha1_hex ($salt_buf . $word_buf);
3949
3950 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3951 }
3952 elsif ($mode == 121)
3953 {
3954 $hash_buf = sha1_hex (lc ($salt_buf) . $word_buf);
3955
3956 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3957 }
3958 elsif ($mode == 122)
3959 {
3960 my $salt_buf_bin = pack ("H*", $salt_buf);
3961
3962 $hash_buf = sha1_hex ($salt_buf_bin . $word_buf);
3963
3964 $tmp_hash = sprintf ("%s%s", $salt_buf, $hash_buf);
3965 }
3966 elsif ($mode == 130)
3967 {
3968 $hash_buf = sha1_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
3969
3970 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3971 }
3972 elsif ($mode == 131)
3973 {
3974 my $salt_buf_bin = pack ("H*", $salt_buf);
3975
3976 $hash_buf = sha1_hex (encode ("UTF-16LE", uc ($word_buf)) . $salt_buf_bin);
3977
3978 $tmp_hash = sprintf ("0x0100%s%s%s", $salt_buf, "0" x 40, $hash_buf);
3979 }
3980 elsif ($mode == 132)
3981 {
3982 my $salt_buf_bin = pack ("H*", $salt_buf);
3983
3984 $hash_buf = sha1_hex (encode ("UTF-16LE", $word_buf) . $salt_buf_bin);
3985
3986 $tmp_hash = sprintf ("0x0100%s%s", $salt_buf, $hash_buf);
3987 }
3988 elsif ($mode == 140)
3989 {
3990 $hash_buf = sha1_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
3991
3992 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
3993 }
3994 elsif ($mode == 141)
3995 {
3996 $hash_buf = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
3997
3998 my $base64_salt_buf = encode_base64 ($salt_buf);
3999
4000 chomp ($base64_salt_buf);
4001
4002 my $base64_hash_buf = encode_base64 ($hash_buf);
4003
4004 $base64_hash_buf = substr ($base64_hash_buf, 0, 27);
4005
4006 $tmp_hash = sprintf ("\$episerver\$*0*%s*%s", $base64_salt_buf, $base64_hash_buf);
4007 }
4008 elsif ($mode == 150)
4009 {
4010 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha1, 64);
4011
4012 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4013 }
4014 elsif ($mode == 160)
4015 {
4016 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha1, 64);
4017
4018 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4019 }
4020 elsif ($mode == 190)
4021 {
4022 $hash_buf = sha1_hex ($word_buf);
4023
4024 my $variant = int (rand (2));
4025
4026 if (defined ($additional_param))
4027 {
4028 $variant = $additional_param;
4029 }
4030
4031 if ($variant == 1)
4032 {
4033 substr ($hash_buf, 0, 5) = "00000";
4034 }
4035
4036 $tmp_hash = sprintf ("%s", $hash_buf);
4037 }
4038 elsif ($mode == 200)
4039 {
4040 my $ppr = Authen::Passphrase::MySQL323->new (passphrase => $word_buf);
4041
4042 $hash_buf = $ppr->hash_hex;
4043
4044 $tmp_hash = sprintf ("%s", $hash_buf);
4045 }
4046 elsif ($mode == 300)
4047 {
4048 $hash_buf = substr (password41 ($word_buf), 1);
4049
4050 $hash_buf = lc ($hash_buf); # useful for 'not matched' check only
4051
4052 $tmp_hash = sprintf ("%s", $hash_buf);
4053 }
4054 elsif ($mode == 400)
4055 {
4056 my $cost = 11;
4057
4058 if (length ($iter))
4059 {
4060 $cost = $iter;
4061 }
4062
4063 my $ppr = Authen::Passphrase::PHPass->new
4064 (
4065 cost => $cost,
4066 salt => $salt_buf,
4067 passphrase => $word_buf,
4068 );
4069
4070 $hash_buf = $ppr->as_rfc2307;
4071
4072 $tmp_hash = sprintf ("%s", substr ($hash_buf, 7));
4073 }
4074 elsif ($mode == 500)
4075 {
4076 my $iterations = 1000;
4077
4078 if (defined ($iter))
4079 {
4080 if ($iter > 0)
4081 {
4082 $iterations = int ($iter);
4083 }
4084 }
4085
4086 $hash_buf = md5_crypt ('$1$', $iterations, $word_buf, $salt_buf);
4087
4088 $tmp_hash = sprintf ("%s", $hash_buf);
4089 }
4090 elsif ($mode == 900)
4091 {
4092 $hash_buf = md4_hex ($word_buf);
4093
4094 $tmp_hash = sprintf ("%s", $hash_buf);
4095 }
4096 elsif ($mode == 1000)
4097 {
4098 $hash_buf = md4_hex (encode ("UTF-16LE", $word_buf));
4099
4100 $tmp_hash = sprintf ("%s", $hash_buf);
4101 }
4102 elsif ($mode == 1100)
4103 {
4104 $hash_buf = md4_hex (md4 (encode ("UTF-16LE", $word_buf)) . encode ("UTF-16LE", lc ($salt_buf)));
4105
4106 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4107 }
4108 elsif ($mode == 1400)
4109 {
4110 $hash_buf = sha256_hex ($word_buf);
4111
4112 $tmp_hash = sprintf ("%s", $hash_buf);
4113 }
4114 elsif ($mode == 1410)
4115 {
4116 $hash_buf = sha256_hex ($word_buf . $salt_buf);
4117
4118 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4119 }
4120 elsif ($mode == 1420)
4121 {
4122 $hash_buf = sha256_hex ($salt_buf . $word_buf);
4123
4124 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4125 }
4126 elsif ($mode == 1430)
4127 {
4128 $hash_buf = sha256_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4129
4130 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4131 }
4132 elsif ($mode == 1440)
4133 {
4134 $hash_buf = sha256_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4135
4136 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4137 }
4138 elsif ($mode == 1441)
4139 {
4140 $hash_buf = sha256 ($salt_buf . encode ("UTF-16LE", $word_buf));
4141
4142 my $base64_salt_buf = encode_base64 ($salt_buf);
4143
4144 chomp ($base64_salt_buf);
4145
4146 my $base64_hash_buf = encode_base64 ($hash_buf);
4147
4148 chomp ($base64_hash_buf);
4149
4150 $base64_hash_buf = substr ($base64_hash_buf, 0, 43);
4151
4152 $tmp_hash = sprintf ("\$episerver\$*1*%s*%s", $base64_salt_buf, $base64_hash_buf);
4153 }
4154 elsif ($mode == 1450)
4155 {
4156 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha256, 64);
4157
4158 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4159 }
4160 elsif ($mode == 1460)
4161 {
4162 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha256, 64);
4163
4164 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4165 }
4166 elsif ($mode == 1500)
4167 {
4168 $hash_buf = crypt ($word_buf, $salt_buf);
4169
4170 $tmp_hash = sprintf ("%s", $hash_buf);
4171 }
4172 elsif ($mode == 1600)
4173 {
4174 my $iterations = 1000;
4175
4176 if (defined ($iter))
4177 {
4178 if ($iter > 0)
4179 {
4180 $iterations = int ($iter);
4181 }
4182 }
4183
4184 $hash_buf = md5_crypt ('$apr1$', $iterations, $word_buf, $salt_buf);
4185
4186 $tmp_hash = sprintf ("%s", $hash_buf);
4187 }
4188 elsif ($mode == 1700)
4189 {
4190 $hash_buf = sha512_hex ($word_buf);
4191
4192 $tmp_hash = sprintf ("%s", $hash_buf);
4193 }
4194 elsif ($mode == 1710)
4195 {
4196 $hash_buf = sha512_hex ($word_buf . $salt_buf);
4197
4198 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4199 }
4200 elsif ($mode == 1711)
4201 {
4202 $hash_buf = sha512_hex ($word_buf . $salt_buf);
4203
4204 my $base64_buf = encode_base64 (pack ("H*", $hash_buf) . $salt_buf);
4205
4206 $base64_buf =~ s/[ \n]//g;
4207
4208 $tmp_hash = sprintf ("{SSHA512}%s", $base64_buf);
4209 }
4210 elsif ($mode == 1720)
4211 {
4212 $hash_buf = sha512_hex ($salt_buf . $word_buf);
4213
4214 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4215 }
4216 elsif ($mode == 1730)
4217 {
4218 $hash_buf = sha512_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4219
4220 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4221 }
4222 elsif ($mode == 1740)
4223 {
4224 $hash_buf = sha512_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4225
4226 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4227 }
4228 elsif ($mode == 1722)
4229 {
4230 my $salt_buf_bin = pack ("H*", $salt_buf);
4231
4232 $hash_buf = sha512_hex ($salt_buf_bin . $word_buf);
4233
4234 $tmp_hash = sprintf ("%s%s", $salt_buf, $hash_buf);
4235 }
4236 elsif ($mode == 1731)
4237 {
4238 my $salt_buf_bin = pack ("H*", $salt_buf);
4239
4240 $hash_buf = sha512_hex (encode ("UTF-16LE", $word_buf) . $salt_buf_bin);
4241
4242 $tmp_hash = sprintf ("0x0200%s%s", $salt_buf, $hash_buf);
4243 }
4244 elsif ($mode == 1750)
4245 {
4246 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha512, 128);
4247
4248 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4249 }
4250 elsif ($mode == 1760)
4251 {
4252 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha512, 128);
4253
4254 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4255 }
4256 elsif ($mode == 1800)
4257 {
4258 my $iterations = 5000;
4259
4260 if (defined ($iter))
4261 {
4262 if ($iter > 0)
4263 {
4264 $iterations = int ($iter);
4265 }
4266 }
4267
4268 $hash_buf = sha512_crypt ($iterations, $word_buf, $salt_buf);
4269
4270 $tmp_hash = sprintf ("%s", $hash_buf);
4271 }
4272 elsif ($mode == 2100)
4273 {
4274 my $iterations = 10240;
4275
4276 if (length ($iter))
4277 {
4278 $iterations = int ($iter);
4279 }
4280
4281 my $salt = encode ("UTF-16LE", lc ($salt_buf));
4282
4283 my $pbkdf2 = Crypt::PBKDF2->new
4284 (
4285 hash_class => 'HMACSHA1',
4286 iterations => $iterations,
4287 output_len => 16,
4288 salt_len => length ($salt),
4289 );
4290
4291 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 ($salt, md4 (md4 (encode ("UTF-16LE", $word_buf)) . $salt)));
4292
4293 $tmp_hash = sprintf ("\$DCC2\$%i#%s#%s", $iterations, $salt_buf, $hash_buf);
4294 }
4295 elsif ($mode == 2400)
4296 {
4297 $tmp_hash = sprintf ("%s", pseudo_base64 (Digest::MD5::md5 ($word_buf . "\0" x (16 - length ($word_buf)))));
4298 }
4299 elsif ($mode == 2410)
4300 {
4301 my $salt_len = length ($salt_buf);
4302
4303 my $salt_len_max4 = ($salt_len < 4) ? $salt_len : 4;
4304
4305 my $hash_buf = pseudo_base64 (Digest::MD5::md5 ($word_buf . substr ($salt_buf, 0, $salt_len_max4) . "\0" x (16 - length ($word_buf) - $salt_len_max4)));
4306
4307 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4308 }
4309 elsif ($mode == 2500)
4310 {
4311 my ($bssid, $stmac, $snonce, $anonce, $eapol, $keyver, $eapol_size);
4312
4313 if (! defined ($additional_param))
4314 {
4315 # random stuff
4316
4317 $bssid = randbytes (6);
4318 $stmac = randbytes (6);
4319 $snonce = randbytes (32);
4320 $anonce = randbytes (32);
4321
4322 $keyver = get_random_num (1, 3); # 1 or 2
4323
4324 # eapol:
4325 # should be "validly" generated, but in theory could be anything for us also:
4326 # $eapol = "\x00" x 121; # works too, but let's generate it correctly
4327
4328 $eapol = gen_random_wpa_eapol ($keyver, $snonce);
4329 }
4330 else
4331 {
4332 $bssid = $additional_param;
4333 $stmac = $additional_param2;
4334 $snonce = $additional_param3;
4335 $anonce = $additional_param4;
4336 $keyver = $additional_param5;
4337 $eapol = $additional_param6;
4338 }
4339
4340 $eapol_size = length ($eapol);
4341
4342 # constants
4343
4344 my $iterations = 4096;
4345
4346 #
4347 # START
4348 #
4349
4350 # generate the Pairwise Master Key (PMK)
4351
4352 my $pbkdf2 = Crypt::PBKDF2->new
4353 (
4354 hash_class => 'HMACSHA1',
4355 iterations => $iterations,
4356 output_len => 32,
4357 );
4358
4359 my $pmk = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
4360
4361 # Pairwise Transient Key (PTK) transformation
4362
4363 my $ptk = wpa_prf_512 ($pmk, $stmac, $bssid, $snonce, $anonce);
4364
4365 # generate the Message Integrity Code (MIC)
4366
4367 my $mic = "";
4368
4369 if ($keyver == 1) # WPA1 => MD5
4370 {
4371 $mic = hmac ($eapol, $ptk, \&md5);
4372 }
4373 else # WPA2 => SHA1
4374 {
4375 $mic = hmac ($eapol, $ptk, \&sha1);
4376 }
4377
4378 $mic = substr ($mic, 0, 16);
4379
4380 #
4381 # format the binary output
4382 #
4383
4384 $hash_buf = "";
4385
4386 # first the essid (NULL-padded up to the first 36 bytes)
4387
4388 $hash_buf .= $salt_buf;
4389 $hash_buf .= "\x00" x (36 - length ($salt_buf));
4390
4391 # the 2 MAC addresses
4392
4393 $hash_buf .= $bssid;
4394 $hash_buf .= $stmac;
4395
4396 # nonces
4397
4398 $hash_buf .= $snonce;
4399 $hash_buf .= $anonce;
4400
4401 # eapol
4402
4403 $hash_buf .= $eapol;
4404 $hash_buf .= "\x00" x (256 - $eapol_size);
4405
4406 # eapol size
4407
4408 $hash_buf .= pack ("L*", $eapol_size);
4409
4410 # key version
4411
4412 $hash_buf .= pack ("L*", $keyver);
4413
4414 # and finally: the key mic
4415
4416 $hash_buf .= $mic;
4417
4418 # base64 encode the output
4419
4420 $tmp_hash = encode_base64 ($hash_buf, '');
4421 }
4422 elsif ($mode == 2600)
4423 {
4424 $hash_buf = md5_hex (md5_hex ($word_buf));
4425
4426 $tmp_hash = sprintf ("%s", $hash_buf);
4427 }
4428 elsif ($mode == 2611)
4429 {
4430 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4431
4432 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4433 }
4434 elsif ($mode == 2612)
4435 {
4436 my $salt_buf_hex = unpack ("H*", $salt_buf);
4437
4438 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4439
4440 $tmp_hash = sprintf ("\$PHPS\$%s\$%s", $salt_buf_hex, $hash_buf);
4441 }
4442 elsif ($mode == 2711)
4443 {
4444 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4445
4446 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4447 }
4448 elsif ($mode == 2811)
4449 {
4450 $hash_buf = md5_hex (md5_hex ($salt_buf) . md5_hex ($word_buf));
4451
4452 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4453 }
4454 elsif ($mode == 3000)
4455 {
4456 my $ppr = Authen::Passphrase::LANManager->new ("passphrase" => $word_buf);
4457
4458 $hash_buf = $ppr->hash_hex;
4459
4460 $tmp_hash = sprintf ("%s", substr ($hash_buf, 0, 16));
4461 }
4462 elsif ($mode == 3100)
4463 {
4464 $hash_buf = oracle_hash ($salt_buf, $word_buf);
4465
4466 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4467 }
4468 elsif ($mode == 3200)
4469 {
4470 my $cost = "05";
4471
4472 if (length ($iter))
4473 {
4474 $cost = $iter;
4475 }
4476
4477 $tmp_hash = bcrypt ($word_buf, sprintf ('$2a$%s$%s$', $cost, en_base64 ($salt_buf)));
4478 }
4479 elsif ($mode == 3300)
4480 {
4481 my $iterations = 904;
4482
4483 if (length ($iter))
4484 {
4485 $iterations = int ($iter);
4486 }
4487
4488 my $variant = "\$";
4489
4490 if (defined ($additional_param))
4491 {
4492 $variant = $additional_param;
4493 }
4494
4495 my $prefix = sprintf ("\$md5%srounds=%i\$%s", $variant, $iterations, $salt_buf);
4496
4497 $iterations += 4096;
4498
4499 $hash_buf = sun_md5 ($word_buf, $prefix, $iterations);
4500
4501 $tmp_hash = sprintf ("%s\$%s", $prefix, $hash_buf);
4502 }
4503 elsif ($mode == 3500)
4504 {
4505 $hash_buf = md5_hex (md5_hex (md5_hex ($word_buf)));
4506
4507 $tmp_hash = sprintf ("%s", $hash_buf);
4508 }
4509 elsif ($mode == 3610)
4510 {
4511 $hash_buf = md5_hex (md5_hex ($salt_buf) . $word_buf);
4512
4513 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4514 }
4515 elsif ($mode == 3710)
4516 {
4517 $hash_buf = md5_hex ($salt_buf . md5_hex ($word_buf));
4518
4519 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4520 }
4521 elsif ($mode == 3711)
4522 {
4523 $hash_buf = md5_hex ($salt_buf . "-" . md5_hex ($word_buf));
4524
4525 $tmp_hash = sprintf ("\$B\$%s\$%s", $salt_buf, $hash_buf);
4526 }
4527 elsif ($mode == 3720)
4528 {
4529 $hash_buf = md5_hex ($word_buf . md5_hex ($salt_buf));
4530
4531 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4532 }
4533 elsif ($mode == 3800)
4534 {
4535 $hash_buf = md5_hex ($salt_buf . $word_buf . $salt_buf);
4536
4537 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4538 }
4539 elsif ($mode == 3910)
4540 {
4541 $hash_buf = md5_hex (md5_hex ($word_buf) . md5_hex ($salt_buf));
4542
4543 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4544 }
4545 elsif ($mode == 4010)
4546 {
4547 $hash_buf = md5_hex ($salt_buf . md5_hex ($salt_buf . $word_buf));
4548
4549 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4550 }
4551 elsif ($mode == 4110)
4552 {
4553 $hash_buf = md5_hex ($salt_buf . md5_hex ($word_buf . $salt_buf));
4554
4555 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4556 }
4557 elsif ($mode == 4210)
4558 {
4559 $hash_buf = md5_hex ($salt_buf . "\x00" . $word_buf);
4560
4561 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4562 }
4563 elsif ($mode == 4300)
4564 {
4565 $hash_buf = md5_hex (uc (md5_hex ($word_buf)));
4566
4567 $tmp_hash = sprintf ("%s", $hash_buf);
4568 }
4569 elsif ($mode == 4400)
4570 {
4571 $hash_buf = md5_hex (sha1_hex ($word_buf));
4572
4573 $tmp_hash = sprintf ("%s", $hash_buf);
4574 }
4575 elsif ($mode == 4500)
4576 {
4577 $hash_buf = sha1_hex (sha1_hex ($word_buf));
4578
4579 $tmp_hash = sprintf ("%s", $hash_buf);
4580 }
4581 elsif ($mode == 4600)
4582 {
4583 $hash_buf = sha1_hex (sha1_hex (sha1_hex ($word_buf)));
4584
4585 $tmp_hash = sprintf ("%s", $hash_buf);
4586 }
4587 elsif ($mode == 4700)
4588 {
4589 $hash_buf = sha1_hex (md5_hex ($word_buf));
4590
4591 $tmp_hash = sprintf ("%s", $hash_buf);
4592 }
4593 elsif ($mode == 4800)
4594 {
4595 my $index = rindex ($salt_buf, ":");
4596
4597 my $salt = substr ($salt_buf, 0, $index);
4598 my $salt_bin = pack ("H*", $salt);
4599 my $chap_sign = substr ($salt_buf, $index + 1);
4600 my $chap_sign_bin = pack ("H*", $chap_sign);
4601
4602 $hash_buf = md5_hex ($chap_sign_bin . $word_buf . $salt_bin);
4603
4604 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4605 }
4606 elsif ($mode == 4900)
4607 {
4608 $hash_buf = sha1_hex ($salt_buf . $word_buf . $salt_buf);
4609
4610 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4611 }
4612 elsif ($mode == 5000)
4613 {
4614 $hash_buf = keccak_256_hex ($word_buf);
4615
4616 $tmp_hash = sprintf ("%s", $hash_buf);
4617 }
4618 elsif ($mode == 5100)
4619 {
4620 my $pos;
4621
4622 if (! defined ($additional_param))
4623 {
4624 $pos = 0;
4625 }
4626 else
4627 {
4628 $pos = $additional_param * 8 unless ($additional_param > 2);
4629 }
4630
4631 $hash_buf = md5_hex ($word_buf);
4632
4633 $tmp_hash = sprintf ("%s", substr ($hash_buf, $pos, 16));
4634 }
4635 elsif ($mode == 5300)
4636 {
4637 my @salt_arr = split (":", $salt_buf);
4638
4639 my $msg_buf = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]);
4640 my $nr_buf = pack ("H*", $salt_arr[6] . $salt_arr[7]);
4641
4642 my $hash_buf = hmac ($nr_buf , $word_buf, \&md5, 64);
4643 $hash_buf = hmac_hex ($msg_buf, $hash_buf, \&md5, 64);
4644
4645 $tmp_hash = sprintf ("%s:%s", $salt_buf, $hash_buf);
4646 }
4647 elsif ($mode == 5400)
4648 {
4649 my @salt_arr = split (":", $salt_buf);
4650
4651 my $msg_buf = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]);
4652 my $nr_buf = pack ("H*", $salt_arr[6] . $salt_arr[7]);
4653
4654 my $hash_buf = hmac ($nr_buf , $word_buf, \&sha1, 64);
4655 $hash_buf = hmac_hex ($msg_buf, $hash_buf, \&sha1, 64);
4656
4657 $tmp_hash = sprintf ("%s:%s", $salt_buf, $hash_buf);
4658 }
4659 elsif ($mode == 5500)
4660 {
4661 my $index1 = index ($salt_buf, "::");
4662 my $user = substr ($salt_buf, 0, $index1);
4663
4664 my $index2 = index ($salt_buf, ":", $index1 + 2);
4665 my $domain = substr ($salt_buf, $index1 + 2, $index2 - $index1 - 2);
4666
4667 my $len = length (substr ($salt_buf, $index2 + 1));
4668
4669 my $c_challenge_hex;
4670
4671 if ($len > 32)
4672 {
4673 $c_challenge_hex = substr ($salt_buf, $index2 + 1, 48);
4674 $index2 += 32;
4675 }
4676 else
4677 {
4678 $c_challenge_hex = substr ($salt_buf, $index2 + 1, 16);
4679 $c_challenge_hex .= 00 x 32;
4680 }
4681
4682 my $c_challenge = pack ("H*", substr ($c_challenge_hex, 0, 16));
4683 my $s_challenge_hex = substr ($salt_buf, $index2 + 17, 16);
4684 my $s_challenge = pack ("H*", $s_challenge_hex);
4685
4686 my $challenge = substr (md5 ($s_challenge . $c_challenge), 0, 8);
4687
4688 my $ntresp;
4689
4690 my $nthash = Authen::Passphrase::NTHash->new (passphrase => $word_buf)->hash . "\x00" x 5;
4691
4692 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 0, 7)), "DES", $challenge, PADDING_NONE);
4693 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 7, 7)), "DES", $challenge, PADDING_NONE);
4694 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 14, 7)), "DES", $challenge, PADDING_NONE);
4695
4696 $tmp_hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $c_challenge_hex, unpack ("H*", $ntresp), $s_challenge_hex);
4697 }
4698 elsif ($mode == 5600)
4699 {
4700 my $index1 = index ($salt_buf, "::");
4701 my $user = substr ($salt_buf, 0, $index1);
4702
4703 my $index2 = index ($salt_buf, ":", $index1 + 2);
4704 my $domain = substr ($salt_buf, $index1 + 2, $index2 - $index1 - 2);
4705
4706 my $s_challenge_hex = substr ($salt_buf, $index2 + 1, 16);
4707 my $s_challenge = pack ("H*", $s_challenge_hex);
4708
4709 my $temp_hex = substr ($salt_buf, $index2 + 17);
4710 my $temp = pack ("H*", $temp_hex);
4711
4712 my $nthash = Authen::Passphrase::NTHash->new (passphrase => $word_buf)->hash;
4713 my $identity = Encode::encode ("UTF-16LE", uc ($user) . $domain);
4714
4715 $hash_buf = hmac_hex ($s_challenge . $temp, hmac ($identity, $nthash, \&md5, 64), \&md5, 64);
4716
4717 $tmp_hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $s_challenge_hex, $hash_buf, $temp_hex);
4718 }
4719 elsif ($mode == 5700)
4720 {
4721 $hash_buf = sha256 ($word_buf);
4722
4723 my $base64_buf = encode_base64 ($hash_buf);
4724
4725 $tmp_hash = "";
4726
4727 for (my $i = 0; $i < 43; $i++)
4728 {
4729 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($base64_buf, $i, 1)};
4730 }
4731 }
4732 elsif ($mode == 5800)
4733 {
4734 $hash_buf = androidpin_hash ($word_buf, $salt_buf);
4735
4736 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4737 }
4738 elsif ($mode == 6000)
4739 {
4740 $hash_buf = ripemd160_hex ($word_buf);
4741
4742 $tmp_hash = sprintf ("%s", $hash_buf);
4743 }
4744 elsif ($mode == 6100)
4745 {
4746 $hash_buf = whirlpool_hex ($word_buf);
4747
4748 $tmp_hash = sprintf ("%s", $hash_buf);
4749 }
4750 elsif ($mode == 6300)
4751 {
4752 my $iterations = 1000; # hard coded by the AIX format
4753
4754 $hash_buf = md5_crypt ('', $iterations, $word_buf, $salt_buf);
4755
4756 $tmp_hash = sprintf ("{smd5}%s", $hash_buf);
4757 }
4758 elsif ($mode == 6400)
4759 {
4760 my $iterations = 64;
4761
4762 if (length ($iter))
4763 {
4764 $iterations = 1 << int ($iter);
4765 }
4766
4767 $hash_buf = aix_ssha256_pbkdf2 ($word_buf, $salt_buf, $iterations);
4768
4769 $tmp_hash = sprintf ("{ssha256}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
4770 }
4771 elsif ($mode == 6500)
4772 {
4773 my $iterations = 64;
4774
4775 if (length ($iter))
4776 {
4777 $iterations = 1 << int ($iter);
4778 }
4779
4780 $hash_buf = aix_ssha512_pbkdf2 ($word_buf, $salt_buf, $iterations);
4781
4782 $tmp_hash = sprintf ("{ssha512}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
4783 }
4784 elsif ($mode == 6600)
4785 {
4786 my $iterations = 1000;
4787
4788 if (length ($iter))
4789 {
4790 $iterations = int ($iter);
4791 }
4792
4793 my $salt_hex = substr ($salt_buf, 0, 16);
4794 my $salt = pack ("H*", $salt_hex);
4795
4796 my $prefix = substr ($salt_buf, 16, 2016);
4797
4798 my $iv_hex = substr ($salt_buf, 2032);
4799 my $iv = pack ("H*", $iv_hex);
4800
4801 my $data = pack ("H*", "10101010101010101010101010101010");
4802
4803 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
4804
4805 my $pbkdf2 = Crypt::PBKDF2->new (
4806 hasher => $hasher,
4807 iterations => $iterations,
4808 output_len => 16
4809 );
4810
4811 my $key = $pbkdf2->PBKDF2 ($salt, $word_buf);
4812
4813 my $cipher = Crypt::CBC->new ({
4814 key => $key,
4815 cipher => "Crypt::Rijndael",
4816 iv => $iv,
4817 literal_key => 1,
4818 header => "none",
4819 keysize => 16
4820 });
4821
4822 my $encrypted = unpack ("H*", $cipher->encrypt ($data));
4823
4824 $hash_buf = substr ($encrypted, 0, 32);
4825
4826 $tmp_hash = sprintf ("%i:%s:%s%s%s", $iterations, $salt_hex, $prefix, $iv_hex, $hash_buf);
4827 }
4828 elsif ($mode == 6700)
4829 {
4830 my $iterations = 64;
4831
4832 if (length ($iter))
4833 {
4834 $iterations = 1 << int ($iter);
4835 }
4836
4837 $hash_buf = aix_ssha1_pbkdf2 ($word_buf, $salt_buf, $iterations);
4838
4839 $tmp_hash = sprintf ("{ssha1}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
4840 }
4841 elsif ($mode == 6800)
4842 {
4843 my $variant = $additional_param;
4844
4845 if (! defined ($variant))
4846 {
4847 $variant = int (rand (2));
4848 }
4849
4850 my $iterations = 500;
4851
4852 if (length ($iter))
4853 {
4854 $iterations = int ($iter);
4855 }
4856
4857 my $iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
4858
4859 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256);
4860
4861 my $pbkdf2 = Crypt::PBKDF2->new (
4862 hasher => $hasher,
4863 iterations => $iterations,
4864 output_len => 32
4865 );
4866
4867 my $key = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
4868
4869 my $cipher = Crypt::CBC->new ({
4870 key => $key,
4871 cipher => "Crypt::Rijndael",
4872 iv => $iv,
4873 literal_key => 1,
4874 header => "none",
4875 keysize => 32
4876 });
4877
4878 if ($variant == 1)
4879 {
4880 my $encrypt = $cipher->encrypt (substr ($salt_buf, 0, 16));
4881
4882 $hash_buf = substr (unpack ("H*", $encrypt), 0, 32);
4883 }
4884 else
4885 {
4886 my $verifier = "lastpass rocks\x02\x02";
4887
4888 $hash_buf = unpack ("H*", substr ($cipher->encrypt ($verifier), 0, 16));
4889 }
4890
4891 $tmp_hash = sprintf ("%s:%i:%s", $hash_buf, $iterations, $salt_buf);
4892 }
4893 elsif ($mode == 6900)
4894 {
4895 $hash_buf = gost_hex ($word_buf);
4896
4897 $tmp_hash = sprintf ("%s", $hash_buf);
4898 }
4899 elsif ($mode == 7100)
4900 {
4901 my $iterations = 1024;
4902
4903 if (length ($iter))
4904 {
4905 $iterations = int ($iter);
4906 }
4907
4908 my $pbkdf2 = Crypt::PBKDF2->new
4909 (
4910 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
4911 iterations => $iterations
4912 );
4913
4914 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 (pack ("H*", $salt_buf), $word_buf));
4915
4916 $tmp_hash = sprintf ("\$ml\$%i\$%s\$%0128s", $iterations, $salt_buf, $hash_buf);
4917 }
4918 elsif ($mode == 7200)
4919 {
4920 my $iterations = 1024;
4921
4922 if (length ($iter))
4923 {
4924 $iterations = int ($iter);
4925 }
4926
4927 my $pbkdf2 = Crypt::PBKDF2->new (
4928 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
4929 iterations => $iterations
4930 );
4931
4932 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 (pack ("H*", $salt_buf), $word_buf));
4933
4934 $tmp_hash = sprintf ("grub.pbkdf2.sha512.%i.%s.%0128s", $iterations, $salt_buf, $hash_buf);
4935 }
4936 elsif ($mode == 7300)
4937 {
4938 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha1);
4939
4940 $tmp_hash = sprintf ("%s:%s", unpack ("H*", $salt_buf), $hash_buf);
4941 }
4942 elsif ($mode == 7400)
4943 {
4944 my $iterations = 5000;
4945
4946 if (defined ($iter))
4947 {
4948 if ($iter > 0)
4949 {
4950 $iterations = int ($iter);
4951 }
4952 }
4953
4954 $hash_buf = sha256_crypt ($iterations, $word_buf, $salt_buf);
4955
4956 $tmp_hash = sprintf ("%s", $hash_buf);
4957 }
4958 elsif ($mode == 7500)
4959 {
4960 my @salt_arr = split ("\\\$", $salt_buf);
4961
4962 my $user = $salt_arr[0];
4963
4964 my $realm = $salt_arr[1];
4965
4966 my $salt = $salt_arr[2];
4967
4968 my $hmac_salt = $salt_arr[3];
4969 my $hmac_salt_bin = pack ("H*", $hmac_salt);
4970
4971 my $clear_data = $salt_arr[4];
4972
4973 my $k = md4 (encode ("UTF-16LE", $word_buf));
4974
4975 my $k1 = hmac_md5 ("\x01\x00\x00\x00", $k);
4976
4977 my $k3 = hmac_md5 ($hmac_salt_bin, $k1);
4978
4979 if (length ($clear_data) > 1)
4980 {
4981 my $clear_data_bin = pack ("H*", $clear_data);
4982
4983 $hash_buf = RC4 ($k3, $clear_data_bin);
4984 }
4985 else
4986 {
4987 my $hash = $salt_arr[5];
4988
4989 my $hash_bin = pack ("H*", $hash);
4990
4991 my $clear_data = RC4 ($k3, $hash_bin);
4992
4993 my $timestamp = substr ($clear_data, 14, 14);
4994
4995 my $is_numeric = 1;
4996 my $num;
4997
4998 if ($timestamp !~ /^[[:digit:]]{14}$/)
4999 {
5000 $is_numeric = 0;
5001 }
5002
5003 if (! $is_numeric)
5004 {
5005 $hash_buf = "\x00" x 36;
5006
5007 if ($hash_buf eq $hash_bin)
5008 {
5009 $hash_buf = "\x01" x 36;
5010 }
5011 }
5012 else
5013 {
5014 $hash_buf = $hash_bin;
5015 }
5016 }
5017
5018 $tmp_hash = sprintf ("\$krb5pa\$23\$%s\$%s\$%s\$%s%s", $user, $realm, $salt, unpack ("H*", $hash_buf), $hmac_salt);
5019 }
5020 elsif ($mode == 7600)
5021 {
5022 $hash_buf = sha1_hex ($salt_buf . sha1_hex ($word_buf));
5023
5024 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
5025 }
5026 elsif ($mode == 7700)
5027 {
5028 $word_buf = uc $word_buf;
5029 $salt_buf = uc $salt_buf;
5030
5031 my $word_buf_t = sapb_transcode ($word_buf);
5032 my $salt_buf_t = sapb_transcode ($salt_buf);
5033
5034 my $digest1 = md5 ($word_buf_t . $salt_buf_t);
5035
5036 my $data = sapb_waldorf ($digest1, $word_buf_t, $salt_buf_t);
5037
5038 my $digest2 = md5 ($data);
5039
5040 my ($a, $b, $c, $d) = unpack ("N4", $digest2);
5041
5042 $a ^= $c;
5043 $b ^= $d;
5044
5045 $tmp_hash = sprintf ("%s\$%08X%08X", $salt_buf, $a, $b);
5046 }
5047 elsif ($mode == 7800)
5048 {
5049 my $theMagicArray_s =
5050 "\x91\xac\x51\x14\x9f\x67\x54\x43\x24\xe7\x3b\xe0\x28\x74\x7b\xc2" .
5051 "\x86\x33\x13\xeb\x5a\x4f\xcb\x5c\x08\x0a\x73\x37\x0e\x5d\x1c\x2f" .
5052 "\x33\x8f\xe6\xe5\xf8\x9b\xae\xdd\x16\xf2\x4b\x8d\x2c\xe1\xd4\xdc" .
5053 "\xb0\xcb\xdf\x9d\xd4\x70\x6d\x17\xf9\x4d\x42\x3f\x9b\x1b\x11\x94" .
5054 "\x9f\x5b\xc1\x9b\x06\x05\x9d\x03\x9d\x5e\x13\x8a\x1e\x9a\x6a\xe8" .
5055 "\xd9\x7c\x14\x17\x58\xc7\x2a\xf6\xa1\x99\x63\x0a\xd7\xfd\x70\xc3" .
5056 "\xf6\x5e\x74\x13\x03\xc9\x0b\x04\x26\x98\xf7\x26\x8a\x92\x93\x25" .
5057 "\xb0\xa2\x0d\x23\xed\x63\x79\x6d\x13\x32\xfa\x3c\x35\x02\x9a\xa3" .
5058 "\xb3\xdd\x8e\x0a\x24\xbf\x51\xc3\x7c\xcd\x55\x9f\x37\xaf\x94\x4c" .
5059 "\x29\x08\x52\x82\xb2\x3b\x4e\x37\x9f\x17\x07\x91\x11\x3b\xfd\xcd";
5060
5061 $salt_buf = uc $salt_buf;
5062
5063 my $digest = sha1 ($word_buf . $salt_buf);
5064
5065 my ($a, $b, $c, $d, $e) = unpack ("I*", $digest);
5066
5067 my $lengthMagicArray = 0x20;
5068 my $offsetMagicArray = 0;
5069
5070 $lengthMagicArray += (($a >> 0) & 0xff) % 6;
5071 $lengthMagicArray += (($a >> 8) & 0xff) % 6;
5072 $lengthMagicArray += (($a >> 16) & 0xff) % 6;
5073 $lengthMagicArray += (($a >> 24) & 0xff) % 6;
5074 $lengthMagicArray += (($b >> 0) & 0xff) % 6;
5075 $lengthMagicArray += (($b >> 8) & 0xff) % 6;
5076 $lengthMagicArray += (($b >> 16) & 0xff) % 6;
5077 $lengthMagicArray += (($b >> 24) & 0xff) % 6;
5078 $lengthMagicArray += (($c >> 0) & 0xff) % 6;
5079 $lengthMagicArray += (($c >> 8) & 0xff) % 6;
5080 $offsetMagicArray += (($c >> 16) & 0xff) % 8;
5081 $offsetMagicArray += (($c >> 24) & 0xff) % 8;
5082 $offsetMagicArray += (($d >> 0) & 0xff) % 8;
5083 $offsetMagicArray += (($d >> 8) & 0xff) % 8;
5084 $offsetMagicArray += (($d >> 16) & 0xff) % 8;
5085 $offsetMagicArray += (($d >> 24) & 0xff) % 8;
5086 $offsetMagicArray += (($e >> 0) & 0xff) % 8;
5087 $offsetMagicArray += (($e >> 8) & 0xff) % 8;
5088 $offsetMagicArray += (($e >> 16) & 0xff) % 8;
5089 $offsetMagicArray += (($e >> 24) & 0xff) % 8;
5090
5091 my $hash_buf = sha1_hex ($word_buf . substr ($theMagicArray_s, $offsetMagicArray, $lengthMagicArray) . $salt_buf);
5092
5093 $tmp_hash = sprintf ("%s\$%s", $salt_buf, uc $hash_buf);
5094 }
5095 elsif ($mode == 7900)
5096 {
5097 my $cost = 14;
5098
5099 if (length ($iter))
5100 {
5101 $cost = $iter;
5102 }
5103
5104 my $phpass_it = 1 << $cost;
5105
5106 $hash_buf = sha512 ($salt_buf . $word_buf);
5107
5108 for (my $i = 0; $i < $phpass_it; $i++)
5109 {
5110 $hash_buf = sha512 ($hash_buf . $word_buf);
5111 }
5112
5113 my $base64_buf = substr (Authen::Passphrase::PHPass::_en_base64 ($hash_buf), 0, 43);
5114
5115 my $base64_digits = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
5116
5117 my $cost_str = substr ($base64_digits , $cost, 1);
5118
5119 $tmp_hash = sprintf ('$S$%s%s%s', $cost_str, $salt_buf, $base64_buf);
5120 }
5121 elsif ($mode == 8000)
5122 {
5123 my $salt_buf_bin = pack ("H*", $salt_buf);
5124
5125 my $word_buf_utf = encode ("UTF-16BE", $word_buf);
5126
5127 $hash_buf = sha256_hex ($word_buf_utf . "\x00" x (510 - (length ($word_buf) * 2)) . $salt_buf_bin);
5128
5129 $tmp_hash = sprintf ("0xc007%s%s", $salt_buf, $hash_buf);
5130 }
5131 elsif ($mode == 8100)
5132 {
5133 $hash_buf = sha1_hex ($salt_buf . $word_buf . "\x00");
5134
5135 $tmp_hash = sprintf ("1%s%s", $salt_buf, $hash_buf);
5136 }
5137 elsif ($mode == 8200)
5138 {
5139 my $iterations = 40000;
5140
5141 if (defined ($iter))
5142 {
5143 $iterations = $iter;
5144 }
5145
5146 my $salt_hex = substr ($salt_buf, 0, 32);
5147 my $salt = pack ("H*", $salt_hex);
5148
5149 my $data_hex = substr ($salt_buf, 32);
5150 my $data = pack ("H*", $data_hex);
5151
5152 my $pbkdf2 = Crypt::PBKDF2->new
5153 (
5154 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
5155 iterations => int $iterations
5156 );
5157
5158 my $key = $pbkdf2->PBKDF2 ($salt, $word_buf);
5159
5160 $hash_buf = hmac_hex ($data, substr ($key, 32, 32), \&sha256, 64);
5161
5162 $tmp_hash = sprintf ("%s:%s:%d:%s", $hash_buf, $salt_hex, $iterations, $data_hex);
5163 }
5164 elsif ($mode == 8300)
5165 {
5166 my ($domain, $salt_hex) = split (":", $salt_buf);
5167
5168 my $hashalg = Net::DNS::SEC->digtype ("SHA1");
5169
5170 my $salt = pack ("H*", $salt_hex);
5171
5172 my $iterations = 1;
5173
5174 if (defined ($iter))
5175 {
5176 $iterations = $iter;
5177 }
5178
5179 my $name = lc ($word_buf . $domain);
5180
5181 my $hash_buf = Net::DNS::RR::NSEC3::name2hash ($hashalg, $name, $iterations, $salt);
5182
5183 $tmp_hash = sprintf ("%s:%s:%s:%d", $hash_buf, $domain, $salt_hex, $iterations);
5184 }
5185 elsif ($mode == 8400)
5186 {
5187 $hash_buf = sha1_hex ($salt_buf . sha1_hex ($salt_buf . sha1_hex ($word_buf)));
5188
5189 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
5190 }
5191 elsif ($mode == 8500)
5192 {
5193 $hash_buf = racf_hash (uc $salt_buf, $word_buf);
5194
5195 $tmp_hash = sprintf ('$racf$*%s*%s', uc $salt_buf, uc $hash_buf);
5196 }
5197 elsif ($mode == 8600)
5198 {
5199 my @saved_key = map { ord $_; } split "", $word_buf;
5200
5201 my $len = scalar @saved_key;
5202
5203 my @state = domino_big_md (\@saved_key, $len);
5204
5205 $tmp_hash = sprintf ('%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x',
5206 $state[ 0],
5207 $state[ 1],
5208 $state[ 2],
5209 $state[ 3],
5210 $state[ 4],
5211 $state[ 5],
5212 $state[ 6],
5213 $state[ 7],
5214 $state[ 8],
5215 $state[ 9],
5216 $state[10],
5217 $state[11],
5218 $state[12],
5219 $state[13],
5220 $state[14],
5221 $state[15],
5222 );
5223 }
5224 elsif ($mode == 8700)
5225 {
5226 my $domino_char = undef;
5227
5228 if (defined ($additional_param))
5229 {
5230 $domino_char = $additional_param;
5231 }
5232
5233 my @saved_key = map { ord $_; } split "", $word_buf;
5234
5235 my $len = scalar @saved_key;
5236
5237 my @state = domino_big_md (\@saved_key, $len);
5238
5239 my $str = "(" . unpack ("H*", join ("", (map { chr $_; } @state))) . ")";
5240
5241 @saved_key = map { ord $_; } split "", $salt_buf . uc $str;
5242
5243 @state = domino_big_md (\@saved_key, 34);
5244
5245 $hash_buf = join ("", (map { chr $_; } @state));
5246
5247 $tmp_hash = sprintf ('(G%s)', domino_encode ($salt_buf . $hash_buf, $domino_char));
5248 }
5249 elsif ($mode == 8900)
5250 {
5251 my $N = 1024;
5252 my $r = 1;
5253 my $p = 1;
5254
5255 if (defined ($additional_param))
5256 {
5257 $N = $additional_param;
5258 $r = $additional_param2;
5259 $p = $additional_param3;
5260 }
5261
5262 $hash_buf = scrypt_hash ($word_buf, $salt_buf, $N, $r, $p, 32);
5263
5264 $tmp_hash = sprintf ('%s', $hash_buf);
5265 }
5266 elsif ($mode == 9100)
5267 {
5268 my $iterations = 5000;
5269
5270 if (defined ($iter))
5271 {
5272 $iterations = $iter;
5273 }
5274
5275 my $domino_char = undef;
5276
5277 # domino 5 hash - SEC_pwddigest_V1 - -m 8600
5278
5279 my @saved_key = map { ord $_; } split "", $word_buf;
5280
5281 my $len = scalar @saved_key;
5282
5283 my @state = domino_big_md (\@saved_key, $len);
5284
5285
5286 # domino 6 hash - SEC_pwddigest_V2 - -m 8700
5287
5288 my $salt_part = substr ($salt_buf, 0, 5);
5289
5290 my $str = "(" . unpack ("H*", join ("", (map { chr $_; } @state))) . ")";
5291
5292 @saved_key = map { ord $_; } split "", $salt_part . uc $str;
5293
5294 @state = domino_big_md (\@saved_key, 34);
5295
5296 $hash_buf = join ("", (map { chr $_; } @state));
5297
5298 $tmp_hash = sprintf ('(G%s)', domino_encode ($salt_part . $hash_buf, $domino_char));
5299
5300
5301 # domino 8(.5.x) hash - SEC_pwddigest_V3 - -m 9100
5302
5303 my $pbkdf2 = Crypt::PBKDF2->new
5304 (
5305 hash_class => 'HMACSHA1',
5306 iterations => $iterations,
5307 output_len => 8,
5308 salt_len => 16,
5309 );
5310
5311 my $chars = "02";
5312
5313 if (defined ($additional_param))
5314 {
5315 $chars = $additional_param;
5316 }
5317
5318 my $digest_new = $pbkdf2->PBKDF2 ($salt_buf, $tmp_hash);
5319
5320 my $iteration_str = "" . $iterations;
5321
5322 for (my $i = length ($iterations); $i < 10; $i++)
5323 {
5324 $iterations = "0" . $iterations;
5325 }
5326
5327 $tmp_hash = sprintf ('(H%s)', domino_85x_encode ($salt_buf . $iterations . $chars . $digest_new, $domino_char));
5328 }
5329 elsif ($mode == 9200)
5330 {
5331 my $iterations = 20000;
5332
5333 my $pbkdf2 = Crypt::PBKDF2->new
5334 (
5335 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
5336 iterations => $iterations
5337 );
5338
5339 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
5340
5341 $tmp_hash = "";
5342
5343 for (my $i = 0; $i < 43; $i++)
5344 {
5345 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($hash_buf, $i, 1)};
5346 }
5347
5348 $tmp_hash = sprintf ("\$8\$%s\$%s", $salt_buf, $tmp_hash);
5349 }
5350 elsif ($mode == 9300)
5351 {
5352 my $N = 16384;
5353 my $r = 1;
5354 my $p = 1;
5355
5356 $hash_buf = scrypt_b64 ($word_buf, $salt_buf, $N, $r, $p, 32);
5357
5358 $tmp_hash = "";
5359
5360 for (my $i = 0; $i < 43; $i++)
5361 {
5362 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($hash_buf, $i, 1)};
5363 }
5364
5365 $tmp_hash = sprintf ('$9$%s$%s', $salt_buf, $tmp_hash);
5366 }
5367 elsif ($mode == 9400)
5368 {
5369 my $iterations = 50000;
5370
5371 if (length ($iter))
5372 {
5373 $iterations = int ($iter);
5374 }
5375
5376 my $aes_key_size = 128; # or 256
5377
5378 if (defined ($additional_param2))
5379 {
5380 $aes_key_size = $additional_param2;
5381 }
5382
5383 $salt_buf = pack ("H*", $salt_buf);
5384
5385 my $tmp = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
5386
5387 for (my $i = 0; $i < $iterations; $i++)
5388 {
5389 my $num32 = pack ("L", $i);
5390
5391 $tmp = sha1 ($num32 . $tmp);
5392 }
5393
5394 my $zero32 = pack ("L", 0x00);
5395
5396 my $derivation_array1 = pack ("C", 0x36) x 64;
5397 my $derivation_array2 = pack ("C", 0x5C) x 64;
5398
5399 $tmp = sha1 ($tmp . $zero32);
5400
5401 my $tmp2 = sha1 ($derivation_array1 ^ $tmp);
5402 my $tmp3 = sha1 ($derivation_array2 ^ $tmp);
5403
5404 my $key = substr ($tmp2 . $tmp3, 0, $aes_key_size / 8);
5405
5406 my $m = Crypt::Mode::ECB->new ('AES', 0);
5407
5408 my $encdata;
5409
5410 if (defined $additional_param)
5411 {
5412 $encdata = $m->decrypt (pack ("H*", $additional_param), $key);
5413 }
5414 else
5415 {
5416 $encdata = "A" x 16; ## can be anything
5417 }
5418
5419 my $data1_buf = $encdata;
5420 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5421
5422 $data1_buf = substr ($data1_buf . ("\x00" x 16), 0, 16);
5423 $data2_buf = substr ($data2_buf . ("\x00" x 16), 0, 32);
5424
5425 my $encrypted1 = unpack ("H*", $m->encrypt ($data1_buf, $key));
5426 my $encrypted2 = unpack ("H*", $m->encrypt ($data2_buf, $key));
5427
5428 $encrypted1 = substr ($encrypted1, 0, 32);
5429 $encrypted2 = substr ($encrypted2, 0, 40);
5430
5431 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2007, 20, $aes_key_size, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5432 }
5433 elsif ($mode == 9500)
5434 {
5435 my $iterations = 100000;
5436
5437 if (length ($iter))
5438 {
5439 $iterations = int ($iter);
5440 }
5441
5442 $salt_buf = pack ("H*", $salt_buf);
5443
5444 my $tmp = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
5445
5446 for (my $i = 0; $i < $iterations; $i++)
5447 {
5448 my $num32 = pack ("L", $i);
5449
5450 $tmp = sha1 ($num32 . $tmp);
5451 }
5452
5453 my $encryptedVerifierHashInputBlockKey = "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79";
5454 my $encryptedVerifierHashValueBlockKey = "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e";
5455
5456 my $final1 = sha1 ($tmp . $encryptedVerifierHashInputBlockKey);
5457 my $final2 = sha1 ($tmp . $encryptedVerifierHashValueBlockKey);
5458
5459 my $key1 = substr ($final1, 0, 16);
5460 my $key2 = substr ($final2, 0, 16);
5461
5462 my $cipher1 = Crypt::CBC->new ({
5463 key => $key1,
5464 cipher => "Crypt::Rijndael",
5465 iv => $salt_buf,
5466 literal_key => 1,
5467 header => "none",
5468 keysize => 16,
5469 padding => "null",
5470 });
5471
5472 my $cipher2 = Crypt::CBC->new ({
5473 key => $key2,
5474 cipher => "Crypt::Rijndael",
5475 iv => $salt_buf,
5476 literal_key => 1,
5477 header => "none",
5478 keysize => 16,
5479 padding => "null",
5480 });
5481
5482 my $encdata;
5483
5484 if (defined $additional_param)
5485 {
5486 $encdata = $cipher1->decrypt (pack ("H*", $additional_param));
5487 }
5488 else
5489 {
5490 $encdata = "A" x 16; ## can be anything
5491 }
5492
5493 my $data1_buf = $encdata;
5494 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5495
5496 my $encrypted1 = unpack ("H*", $cipher1->encrypt ($data1_buf));
5497 my $encrypted2 = unpack ("H*", $cipher2->encrypt ($data2_buf));
5498
5499 $encrypted2 = substr ($encrypted2, 0, 64);
5500
5501 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2010, 100000, 128, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5502 }
5503 elsif ($mode == 9600)
5504 {
5505 my $iterations = 100000;
5506
5507 if (length ($iter))
5508 {
5509 $iterations = int ($iter);
5510 }
5511
5512 $salt_buf = pack ("H*", $salt_buf);
5513
5514 my $tmp = sha512 ($salt_buf . encode ("UTF-16LE", $word_buf));
5515
5516 for (my $i = 0; $i < $iterations; $i++)
5517 {
5518 my $num32 = pack ("L", $i);
5519
5520 $tmp = sha512 ($num32 . $tmp);
5521 }
5522
5523 my $encryptedVerifierHashInputBlockKey = "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79";
5524 my $encryptedVerifierHashValueBlockKey = "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e";
5525
5526 my $final1 = sha512 ($tmp . $encryptedVerifierHashInputBlockKey);
5527 my $final2 = sha512 ($tmp . $encryptedVerifierHashValueBlockKey);
5528
5529 my $key1 = substr ($final1, 0, 32);
5530 my $key2 = substr ($final2, 0, 32);
5531
5532 my $cipher1 = Crypt::CBC->new ({
5533 key => $key1,
5534 cipher => "Crypt::Rijndael",
5535 iv => $salt_buf,
5536 literal_key => 1,
5537 header => "none",
5538 keysize => 32,
5539 padding => "null",
5540 });
5541
5542 my $cipher2 = Crypt::CBC->new ({
5543 key => $key2,
5544 cipher => "Crypt::Rijndael",
5545 iv => $salt_buf,
5546 literal_key => 1,
5547 header => "none",
5548 keysize => 32,
5549 padding => "null",
5550 });
5551
5552 my $encdata;
5553
5554 if (defined $additional_param)
5555 {
5556 $encdata = $cipher1->decrypt (pack ("H*", $additional_param));
5557 }
5558 else
5559 {
5560 $encdata = "A" x 16; ## can be anything
5561 }
5562
5563 my $data1_buf = $encdata;
5564 my $data2_buf = sha512 (substr ($data1_buf, 0, 16));
5565
5566 my $encrypted1 = unpack ("H*", $cipher1->encrypt ($data1_buf));
5567 my $encrypted2 = unpack ("H*", $cipher2->encrypt ($data2_buf));
5568
5569 $encrypted2 = substr ($encrypted2, 0, 64);
5570
5571 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2013, 100000, 256, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5572 }
5573 elsif ($mode == 9700)
5574 {
5575 $salt_buf = pack ("H*", $salt_buf);
5576
5577 my $tmp = md5 (encode ("UTF-16LE", $word_buf));
5578
5579 $tmp = substr ($tmp, 0, 5);
5580
5581 my $data;
5582
5583 for (my $i = 0; $i < 16; $i++)
5584 {
5585 $data .= $tmp;
5586 $data .= $salt_buf;
5587 }
5588
5589 $tmp = md5 ($data);
5590
5591 $tmp = substr ($tmp, 0, 5);
5592
5593 my $version;
5594
5595 if (defined $additional_param2)
5596 {
5597 $version = $additional_param2;
5598 }
5599 else
5600 {
5601 $version = (unpack ("L", $tmp) & 1) ? 0 : 1;
5602 }
5603
5604 my $rc4_key = md5 ($tmp . "\x00\x00\x00\x00");
5605
5606 my $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5607
5608 my $encdata;
5609
5610 if (defined $additional_param)
5611 {
5612 $encdata = $m->RC4 (pack ("H*", $additional_param));
5613 }
5614 else
5615 {
5616 $encdata = "A" x 16; ## can be anything
5617 }
5618
5619 my $data1_buf = $encdata;
5620 my $data2_buf = md5 (substr ($data1_buf, 0, 16));
5621
5622 $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5623
5624 my $encrypted1 = $m->RC4 ($data1_buf);
5625 my $encrypted2 = $m->RC4 ($data2_buf);
5626
5627 $tmp_hash = sprintf ("\$oldoffice\$%d*%s*%s*%s", $version, unpack ("H*", $salt_buf), unpack ("H*", $encrypted1), unpack ("H*", $encrypted2));
5628 }
5629 elsif ($mode == 9800)
5630 {
5631 $salt_buf = pack ("H*", $salt_buf);
5632
5633 my $tmp = sha1 ($salt_buf. encode ("UTF-16LE", $word_buf));
5634
5635 my $version;
5636
5637 if (defined $additional_param2)
5638 {
5639 $version = $additional_param2;
5640 }
5641 else
5642 {
5643 $version = (unpack ("L", $tmp) & 1) ? 3 : 4;
5644 }
5645
5646 my $rc4_key = sha1 ($tmp . "\x00\x00\x00\x00");
5647
5648 if ($version == 3)
5649 {
5650 $rc4_key = substr ($rc4_key, 0, 5) . "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
5651 }
5652
5653 my $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5654
5655 my $encdata;
5656
5657 if (defined $additional_param)
5658 {
5659 $encdata = $m->RC4 (pack ("H*", $additional_param));
5660 }
5661 else
5662 {
5663 $encdata = "A" x 16; ## can be anything
5664 }
5665
5666 my $data1_buf = $encdata;
5667 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5668
5669 $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5670
5671 my $encrypted1 = $m->RC4 ($data1_buf);
5672 my $encrypted2 = $m->RC4 ($data2_buf);
5673
5674 $tmp_hash = sprintf ("\$oldoffice\$%d*%s*%s*%s", $version, unpack ("H*", $salt_buf), unpack ("H*", $encrypted1), unpack ("H*", $encrypted2));
5675 }
5676 elsif ($mode == 9900)
5677 {
5678 $tmp_hash = sprintf ("%s", md5_hex ($word_buf . "\0" x (100 - length ($word_buf))));
5679 }
5680 elsif ($mode == 10000)
5681 {
5682 my $iterations = 10000;
5683
5684 if (length ($iter))
5685 {
5686 $iterations = int ($iter);
5687 }
5688
5689 my $pbkdf2 = Crypt::PBKDF2->new
5690 (
5691 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
5692 iterations => $iterations
5693 );
5694
5695 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
5696 $hash_buf =~ s/[\r\n]//g;
5697
5698 $tmp_hash = sprintf ("pbkdf2_sha256\$%i\$%s\$%s", $iterations, $salt_buf, $hash_buf);
5699 }
5700 elsif ($mode == 10100)
5701 {
5702 my $seed = pack ("H*", $salt_buf);
5703
5704 my ($hi, $lo) = siphash ($word_buf, $seed);
5705
5706 my $hi_s = sprintf ("%08x", $hi);
5707 my $lo_s = sprintf ("%08x", $lo);
5708
5709 $hi_s =~ s/^(..)(..)(..)(..)$/$4$3$2$1/;
5710 $lo_s =~ s/^(..)(..)(..)(..)$/$4$3$2$1/;
5711
5712 $tmp_hash = sprintf ("%s%s:2:4:%s", $hi_s, $lo_s, $salt_buf);
5713 }
5714 elsif ($mode == 10200)
5715 {
5716 my $challengeb64 = encode_base64 ($salt_buf);
5717 $challengeb64 =~ s/[\r\n]//g;
5718
5719 my $username;
5720
5721 if (defined $additional_param)
5722 {
5723 $username = $additional_param;
5724 }
5725 else
5726 {
5727 $username = "user";
5728 }
5729
5730 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&md5);
5731
5732 my $responseb64 = encode_base64 ($username . " " . $hash_buf);
5733 $responseb64 =~ s/[\r\n]//g;
5734
5735 $tmp_hash = sprintf ('$cram_md5$%s$%s', $challengeb64, $responseb64);
5736 }
5737 elsif ($mode == 10300)
5738 {
5739 my $iterations = 1024;
5740
5741 if (length ($iter))
5742 {
5743 $iterations = int ($iter);
5744 }
5745
5746 my $hash_buf = $salt_buf;
5747
5748 for (my $pos = 0; $pos < $iterations; $pos++)
5749 {
5750 $hash_buf = sha1 ($word_buf . $hash_buf);
5751 }
5752
5753 $hash_buf = encode_base64 ($hash_buf . $salt_buf);
5754 $hash_buf =~ s/[\r\n]//g;
5755
5756 $tmp_hash = sprintf ("{x-issha, %i}%s", $iterations, $hash_buf);
5757 }
5758 elsif ($mode == 10400)
5759 {
5760 my $id = $salt_buf;
5761 my $u = $additional_param;
5762 my $o = $additional_param2;
5763 my $P = $additional_param3;
5764
5765 if (defined $u == 0)
5766 {
5767 $u = "0" x 64;
5768 }
5769
5770 if (defined $o == 0)
5771 {
5772 $o = "0" x 64;
5773 }
5774
5775 if (defined $P == 0)
5776 {
5777 $P = -1;
5778 }
5779
5780 my $padding;
5781
5782 for (my $i = 0; $i < 32; $i++)
5783 {
5784 $padding .= pack ("C", $pdf_padding[$i]);
5785 }
5786
5787 my $res = pdf_compute_encryption_key ($word_buf, $padding, $id, $u, $o, $P, 1, 2, 0);
5788
5789 my $m = Crypt::RC4->new (substr ($res, 0, 5));
5790
5791 $u = $m->RC4 ($padding);
5792
5793 $tmp_hash = sprintf ('$pdf$%d*%d*40*%d*%d*16*%s*32*%s*32*%s', 1, 2, $P, 0, $id, unpack ("H*", $u), $o);
5794 }
5795 elsif ($mode == 10500)
5796 {
5797 my $id = $salt_buf;
5798 my $u = $additional_param;
5799 my $o = $additional_param2;
5800 my $P = $additional_param3;
5801 my $V = $additional_param4;
5802 my $R = $additional_param5;
5803 my $enc = $additional_param6;
5804
5805 if (defined $u == 0)
5806 {
5807 $u = "0" x 64;
5808 }
5809
5810 my $u_save = $u;
5811
5812 if (defined $o == 0)
5813 {
5814 $o = "0" x 64;
5815 }
5816
5817 if (defined $R == 0)
5818 {
5819 $R = get_random_num (3, 5);
5820 }
5821
5822 if (defined $V == 0)
5823 {
5824 $V = ($R == 3) ? 2 : 4;
5825 }
5826
5827 if (defined $P == 0)
5828 {
5829 $P = ($R == 3) ? -4 : -1028;
5830 }
5831
5832 if (defined $enc == 0)
5833 {
5834 $enc = ($R == 3) ? 1 : get_random_num (0, 2);
5835 }
5836
5837 my $padding;
5838
5839 for (my $i = 0; $i < 32; $i++)
5840 {
5841 $padding .= pack ("C", $pdf_padding[$i]);
5842 }
5843
5844 my $res = pdf_compute_encryption_key ($word_buf, $padding, $id, $u, $o, $P, $V, $R, $enc);
5845
5846 my $digest = md5 ($padding . pack ("H*", $id));
5847
5848 my $m = Crypt::RC4->new ($res);
5849
5850 $u = $m->RC4 ($digest);
5851
5852 my @ress = split "", $res;
5853
5854 for (my $x = 1; $x <= 19; $x++)
5855 {
5856 my @xor;
5857
5858 for (my $i = 0; $i < 16; $i++)
5859 {
5860 $xor[$i] = chr (ord ($ress[$i]) ^ $x);
5861 }
5862
5863 my $s = join ("", @xor);
5864
5865 my $m2 = Crypt::RC4->new ($s);
5866
5867 $u = $m2->RC4 ($u);
5868 }
5869
5870 $u .= substr (pack ("H*", $u_save), 16, 16);
5871
5872 $tmp_hash = sprintf ('$pdf$%d*%d*128*%d*%d*16*%s*32*%s*32*%s', $V, $R, $P, $enc, $id, unpack ("H*", $u), $o);
5873 }
5874 elsif ($mode == 10600)
5875 {
5876 my $id = $salt_buf;
5877 my $rest = $additional_param;
5878
5879 if (defined $id == 0)
5880 {
5881 $id = "0" x 32;
5882 }
5883
5884 if (defined $rest == 0)
5885 {
5886 $rest = "127*";
5887 $rest .= "0" x 64;
5888 $rest .= $id;
5889 $rest .= "0" x 158;
5890 $rest .= "*127*00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000";
5891 }
5892
5893 my @data = split /\*/, $rest;
5894
5895 my $u = pack ("H*", $data[1]);
5896
5897 my $h = sha256 ($word_buf . substr ($u, 32, 8));
5898
5899 $data[1] = unpack ("H*", $h . substr ($u, 32));
5900
5901 $rest = join ("*", @data);
5902
5903 $tmp_hash = sprintf ('$pdf$5*5*256*-1028*1*16*%s*%s', $id, $rest);
5904 }
5905 elsif ($mode == 10700)
5906 {
5907 my $id = $salt_buf;
5908 my $rest = $additional_param;
5909
5910 if (defined $id == 0)
5911 {
5912 $id = "0" x 32;
5913 }
5914
5915 if (defined $rest == 0)
5916 {
5917 $rest = "127*";
5918 $rest .= "0" x 64;
5919 $rest .= $id;
5920 $rest .= "0" x 158;
5921 $rest .= "*127*00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000";
5922 }
5923
5924 my @datax = split /\*/, $rest;
5925
5926 my $u = pack ("H*", $datax[1]);
5927
5928 my $block = sha256 ($word_buf . substr ($u, 32, 8));
5929
5930 my $block_size = 32;
5931
5932 my $data = 0x00 x 64;
5933
5934 my $data_len = 1;
5935
5936 my $data63 = 0;
5937
5938 for (my $i = 0; $i < 64 || $i < $data63 + 32; $i++)
5939 {
5940 $data = $word_buf . $block;
5941
5942 $data_len = length ($data);
5943
5944 for (my $k = 1; $k < 64; $k++)
5945 {
5946 $data .= $word_buf . $block;
5947 }
5948
5949 my $aes = Crypt::CBC->new ({
5950 key => substr ($block, 0, 16),
5951 cipher => "Crypt::Rijndael",
5952 iv => substr ($block, 16, 16),
5953 literal_key => 1,
5954 header => "none",
5955 keysize => 16,
5956 padding => "null",
5957 });
5958
5959 my $data = $aes->encrypt ($data);
5960
5961 my $sum = 0;
5962
5963 for (my $j = 0; $j < 16; $j++)
5964 {
5965 $sum += ord (substr ($data, $j, 1));
5966 }
5967
5968 $block_size = 32 + ($sum % 3) * 16;
5969
5970 if ($block_size == 32)
5971 {
5972 $block = sha256 (substr ($data, 0, $data_len * 64));
5973 }
5974 elsif ($block_size == 48)
5975 {
5976 $block = sha384 (substr ($data, 0, $data_len * 64));
5977 }
5978 elsif ($block_size == 64)
5979 {
5980 $block = sha512 (substr ($data, 0, $data_len * 64));
5981 }
5982
5983 $data63 = ord (substr ($data, $data_len * 64 - 1, 1));
5984 }
5985
5986 $datax[1] = unpack ("H*", substr ($block, 0, 32) . substr ($u, 32));
5987
5988 $rest = join ("*", @datax);
5989
5990 $tmp_hash = sprintf ('$pdf$5*6*256*-1028*1*16*%s*%s', $id, $rest);
5991 }
5992 elsif ($mode == 10800)
5993 {
5994 $hash_buf = sha384_hex ($word_buf);
5995
5996 $tmp_hash = sprintf ("%s", $hash_buf);
5997 }
5998 elsif ($mode == 10900)
5999 {
6000 my $iterations = 1000;
6001
6002 if (length ($iter))
6003 {
6004 $iterations = int ($iter);
6005 }
6006
6007 my $out_len = 24;
6008
6009 if (defined $additional_param)
6010 {
6011 $out_len = $additional_param;
6012 }
6013
6014 my $pbkdf2 = Crypt::PBKDF2->new
6015 (
6016 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6017 iterations => $iterations,
6018 output_len => $out_len
6019 );
6020
6021 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6022 $hash_buf =~ s/[\r\n]//g;
6023
6024 my $base64_salt_buf = encode_base64 ($salt_buf);
6025
6026 chomp ($base64_salt_buf);
6027
6028 $tmp_hash = sprintf ("sha256:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6029 }
6030 elsif ($mode == 11000)
6031 {
6032 $hash_buf = md5_hex ($salt_buf . $word_buf);
6033
6034 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
6035 }
6036 elsif ($mode == 11100)
6037 {
6038 my $user = "postgres";
6039
6040 if (defined $additional_param)
6041 {
6042 $user = $additional_param;
6043 }
6044
6045 $hash_buf = md5_hex (md5_hex ($word_buf . $user) . pack ("H*", $salt_buf));
6046
6047 $tmp_hash = sprintf ("\$postgres\$%s*%s*%s", $user, $salt_buf, $hash_buf);
6048 }
6049 elsif ($mode == 11200)
6050 {
6051 my $sha1_pass = sha1 ($word_buf);
6052 my $double_sha1 = sha1 ($sha1_pass);
6053
6054 my $xor_part1 = $sha1_pass;
6055 my $xor_part2 = sha1 (pack ("H*", $salt_buf) . $double_sha1);
6056
6057 my $hash_buf = "";
6058
6059 for (my $i = 0; $i < 20; $i++)
6060 {
6061 my $first_byte = substr ($xor_part1, $i, 1);
6062 my $second_byte = substr ($xor_part2, $i, 1);
6063
6064 my $xor_result = $first_byte ^ $second_byte;
6065
6066 $hash_buf .= unpack ("H*", $xor_result);
6067 }
6068
6069 $tmp_hash = sprintf ("\$mysqlna\$%s*%s", $salt_buf, $hash_buf);
6070 }
6071 elsif ($mode == 11300)
6072 {
6073 my $ckey_buf = get_random_string (96);
6074
6075 if (length ($additional_param))
6076 {
6077 $ckey_buf = $additional_param;
6078 }
6079
6080 my $public_key_buf = get_random_string (66);
6081
6082 if (length ($additional_param2))
6083 {
6084 $public_key_buf = $additional_param2;
6085 }
6086
6087 my $salt_iter = get_random_num (150000, 250000);
6088
6089 if (length ($iter))
6090 {
6091 $salt_iter = int ($iter);
6092 }
6093
6094 my $hash_buf = sha512 ($word_buf . pack ("H*", $salt_buf));
6095
6096 for (my $i = 1; $i < $salt_iter; $i++)
6097 {
6098 $hash_buf = sha512 ($hash_buf);
6099 }
6100
6101 my $data = get_random_string (32);
6102
6103 my $aes = Crypt::CBC->new ({
6104 key => substr ($hash_buf, 0, 32),
6105 cipher => "Crypt::Rijndael",
6106 iv => substr ($hash_buf, 32, 16),
6107 literal_key => 1,
6108 header => "none",
6109 keysize => 32,
6110 padding => "standard",
6111 });
6112
6113 my $cry_master_buf = (unpack ("H*", $aes->encrypt ($data)));
6114
6115 $tmp_hash = sprintf ('$bitcoin$%d$%s$%d$%s$%d$%d$%s$%d$%s',
6116 length ($cry_master_buf),
6117 $cry_master_buf,
6118 length ($salt_buf),
6119 $salt_buf,
6120 $salt_iter,
6121 length ($ckey_buf),
6122 $ckey_buf,
6123 length ($public_key_buf),
6124 $public_key_buf);
6125 }
6126 elsif ($mode == 11400)
6127 {
6128 my ($directive, $URI_server, $URI_client, $user, $realm, $nonce, $nonce_count, $nonce_client, $qop, $method, $URI, $URI_prefix, $URI_resource, $URI_suffix);
6129
6130 $directive = "MD5"; # only directive currently supported
6131
6132 if (defined ($additional_param))
6133 {
6134 $user = $additional_param;
6135 $realm = $additional_param2;
6136 $nonce = $salt_buf;
6137 $nonce_count = $additional_param3;
6138 $nonce_client = $additional_param4;
6139 $qop = $additional_param5;
6140 $method = $additional_param6;
6141
6142 $URI_prefix = $additional_param7;
6143 $URI_resource = $additional_param8;
6144 $URI_suffix = $additional_param9;
6145
6146 # not needed information
6147
6148 $URI_server = $additional_param10;
6149 $URI_client = $additional_param11;
6150 }
6151 else
6152 {
6153 $user = get_random_string (get_random_num (0, 12 + 1));
6154
6155 # special limit: (user_len + 1 + realm_len + 1 + word_buf_len) < 56
6156 my $realm_max_len = 55 - length ($user) - 1 - length ($word_buf) - 1;
6157
6158 if ($realm_max_len < 1) # should never happen
6159 {
6160 $realm_max_len = 1;
6161 }
6162
6163 $realm_max_len = min (20, $realm_max_len);
6164
6165 $realm = get_random_string (get_random_num (0, $realm_max_len + 1));
6166
6167 $nonce = $salt_buf;
6168
6169 if (get_random_num (0, 1 + 1) == 1)
6170 {
6171 $qop = "auth";
6172
6173 $nonce_count = get_random_string (get_random_num (0, 10 + 1));
6174 $nonce_client = get_random_string (get_random_num (0, 12 + 1));
6175 }
6176 else
6177 {
6178 $qop = "";
6179
6180 $nonce_count = "";
6181 $nonce_client = "";
6182 }
6183
6184 $method = get_random_string (get_random_num (0, 24 + 1));
6185
6186 $URI_prefix = get_random_string (get_random_num (0, 10 + 1));
6187 $URI_resource = get_random_string (get_random_num (1, 32 + 1));
6188 $URI_suffix = get_random_string (get_random_num (0, 32 + 1));
6189
6190 # not needed information
6191
6192 $URI_server = get_random_string (get_random_num (0, 32 + 1));
6193 $URI_client = $URI_resource; # simplification
6194 }
6195
6196 # start
6197
6198 $URI = "";
6199
6200 if (length ($URI_prefix) > 0)
6201 {
6202 $URI = $URI_prefix . ":";
6203 }
6204
6205 $URI .= $URI_resource;
6206
6207 if (length ($URI_suffix) > 0)
6208 {
6209 $URI .= ":" . $URI_suffix;
6210 }
6211
6212 my $HA2 = md5_hex ($method . ":" . $URI);
6213
6214 my $HA1 = md5_hex ($user . ":" . $realm . ":" . $word_buf);
6215
6216 my $tmp_buf;
6217
6218 if (($qop eq "auth") || ($qop eq "auth-int"))
6219 {
6220 $tmp_buf = $nonce . ":" . $nonce_count . ":" . $nonce_client . ":" . $qop;
6221 }
6222 else
6223 {
6224 $tmp_buf = $nonce;
6225 }
6226
6227 my $hash_buf = md5_hex ($HA1 . ":" . $tmp_buf . ":" . $HA2);
6228
6229 $tmp_hash = sprintf ("\$sip\$*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s", $URI_server, $URI_resource, $user, $realm, $method, $URI_prefix, $URI_resource, $URI_suffix, $nonce, $nonce_client, $nonce_count, $qop, $directive, $hash_buf);
6230 }
6231 elsif ($mode == 11500)
6232 {
6233 $hash_buf = crc32 ($word_buf);
6234
6235 $tmp_hash = sprintf ("%08x:00000000", $hash_buf);
6236 }
6237 elsif ($mode == 11600)
6238 {
6239 my ($p, $num_cycle_power, $seven_zip_salt_len, $seven_zip_salt_buf, $salt_len, $data_len, $unpack_size, $data_buf);
6240
6241 $p = 0; # is fixed
6242
6243 my $validation_only = 0;
6244
6245 $validation_only = 1 if (defined ($additional_param));
6246
6247 if ($validation_only == 1)
6248 {
6249 $num_cycle_power = int ($iter);
6250 $seven_zip_salt_len = $additional_param;
6251 $seven_zip_salt_buf = $additional_param2;
6252 $salt_len = $additional_param3;
6253 # $salt_buf set in parser
6254 # $hash_buf (resulting crc)
6255 $data_len = $additional_param4;
6256 $unpack_size = $additional_param5;
6257 $data_buf = $additional_param6;
6258 }
6259 else
6260 {
6261 $num_cycle_power = 14; # by default it is 19
6262 $seven_zip_salt_len = 0;
6263 $seven_zip_salt_buf = "";
6264 $salt_len = length ($salt_buf);
6265 # $salt_buf set automatically
6266 # $hash_buf (resulting crc)
6267 # $data_len will be set when encrypting
6268 $unpack_size = get_random_num (1, 32 + 1);
6269 $data_buf = get_random_string ($unpack_size);
6270 }
6271
6272 #
6273 # 2 ^ NumCyclesPower "iterations" of SHA256 (only one final SHA256)
6274 #
6275
6276 $word_buf = encode ("UTF-16LE", $word_buf);
6277
6278 my $rounds = 1 << $num_cycle_power;
6279
6280 my $pass_buf = "";
6281
6282 for (my $i = 0; $i < $rounds; $i++)
6283 {
6284 my $num_buf = "";
6285
6286 $num_buf .= pack ("V", $i);
6287 $num_buf .= "\x00" x 4;
6288
6289 # this would be better but only works on 64-bit systems:
6290 # $num_buf = pack ("q", $i);
6291
6292 $pass_buf .= sprintf ("%s%s", $word_buf, $num_buf);
6293 }
6294
6295 my $key = sha256 ($pass_buf);
6296
6297 # the salt_buf is our IV for AES CBC
6298 # pad the salt_buf
6299
6300 my $salt_buf_len = length ($salt_buf);
6301 my $salt_padding_len = 0;
6302
6303 if ($salt_buf_len < 16)
6304 {
6305 $salt_padding_len = 16 - $salt_buf_len;
6306 }
6307
6308 $salt_buf .= "\x00" x $salt_padding_len;
6309
6310 my $aes = Crypt::CBC->new ({
6311 cipher => "Crypt::Rijndael",
6312 key => $key,
6313 keysize => 32,
6314 literal_key => 1,
6315 iv => $salt_buf,
6316 header => "none",
6317 });
6318
6319 if ($validation_only == 1)
6320 {
6321 # decrypt
6322
6323 my $decrypted_data = $aes->decrypt ($data_buf);
6324
6325 $decrypted_data = substr ($decrypted_data, 0, $unpack_size);
6326
6327 $hash_buf = crc32 ($decrypted_data);
6328 }
6329 else
6330 {
6331 # encrypt
6332
6333 $hash_buf = crc32 ($data_buf);
6334
6335 $data_buf = $aes->encrypt ($data_buf);
6336
6337 $data_len = length ($data_buf);
6338 }
6339
6340 $tmp_hash = sprintf ("\$7z\$%i\$%i\$%i\$%s\$%i\$%08s\$%u\$%u\$%u\$%s", $p, $num_cycle_power, $seven_zip_salt_len, $seven_zip_salt_buf, $salt_len, unpack ("H*", $salt_buf), $hash_buf, $data_len, $unpack_size, unpack ("H*", $data_buf));
6341 }
6342 elsif ($mode == 11900)
6343 {
6344 my $iterations = 1000;
6345
6346 if (length ($iter))
6347 {
6348 $iterations = int ($iter);
6349 }
6350
6351 my $out_len = 32;
6352
6353 if (defined $additional_param)
6354 {
6355 $out_len = $additional_param;
6356 }
6357
6358 #
6359 # call PHP here - WTF
6360 #
6361
6362 # sanitize $word_buf and $salt_buf:
6363
6364 my $word_buf_base64 = encode_base64 ($word_buf);
6365 $word_buf_base64 =~ s/[\r\n]//g;
6366
6367 my $salt_buf_base64 = encode_base64 ($salt_buf);
6368 $salt_buf_base64 =~ s/[\r\n]//g;
6369
6370 # sanitize lenghs
6371
6372 $out_len = int ($out_len);
6373
6374 # output is in hex encoding, otherwise it could be screwed (but shouldn't)
6375
6376 my $php_code = <<'END_CODE';
6377
6378 function pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
6379 {
6380 $algorithm = strtolower ($algorithm);
6381
6382 if (! in_array ($algorithm, hash_algos (), true))
6383 {
6384 trigger_error ("PBKDF2 ERROR: Invalid hash algorithm.", E_USER_ERROR);
6385 }
6386
6387 if ($count <= 0 || $key_length <= 0)
6388 {
6389 trigger_error ("PBKDF2 ERROR: Invalid parameters.", E_USER_ERROR);
6390 }
6391
6392 if (function_exists ("hash_pbkdf2"))
6393 {
6394 if (!$raw_output)
6395 {
6396 $key_length = $key_length * 2;
6397 }
6398
6399 return hash_pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output);
6400 }
6401
6402 $hash_length = strlen (hash ($algorithm, "", true));
6403 $block_count = ceil ($key_length / $hash_length);
6404
6405 $output = "";
6406
6407 for ($i = 1; $i <= $block_count; $i++)
6408 {
6409 $last = $salt . pack ("N", $i);
6410
6411 $last = $xorsum = hash_hmac ($algorithm, $last, $password, true);
6412
6413 for ($j = 1; $j < $count; $j++)
6414 {
6415 $xorsum ^= ($last = hash_hmac ($algorithm, $last, $password, true));
6416 }
6417
6418 $output .= $xorsum;
6419 }
6420
6421 if ($raw_output)
6422 {
6423 return substr ($output, 0, $key_length);
6424 }
6425 else
6426 {
6427 return bin2hex (substr ($output, 0, $key_length));
6428 }
6429 }
6430
6431 print pbkdf2 ("md5", base64_decode ("$word_buf_base64"), base64_decode ("$salt_buf_base64"), $iterations, $out_len, False);
6432
6433 END_CODE
6434
6435 # replace with these command line arguments
6436
6437 $php_code =~ s/\$word_buf_base64/$word_buf_base64/;
6438 $php_code =~ s/\$salt_buf_base64/$salt_buf_base64/;
6439 $php_code =~ s/\$iterations/$iterations/;
6440 $php_code =~ s/\$out_len/$out_len/;
6441
6442 my $php_output = `php -r '$php_code'`;
6443
6444 $hash_buf = pack ("H*", $php_output);
6445
6446 $hash_buf = encode_base64 ($hash_buf);
6447 $hash_buf =~ s/[\r\n]//g;
6448
6449 my $base64_salt_buf = encode_base64 ($salt_buf);
6450
6451 chomp ($base64_salt_buf);
6452
6453 $tmp_hash = sprintf ("md5:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6454 }
6455 elsif ($mode == 12000)
6456 {
6457 my $iterations = 1000;
6458
6459 if (length ($iter))
6460 {
6461 $iterations = int ($iter);
6462 }
6463
6464 my $out_len = 16;
6465
6466 if (defined $additional_param)
6467 {
6468 $out_len = $additional_param;
6469 }
6470
6471 my $pbkdf2 = Crypt::PBKDF2->new
6472 (
6473 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1'),
6474 iterations => $iterations,
6475 output_len => $out_len
6476 );
6477
6478 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6479 $hash_buf =~ s/[\r\n]//g;
6480
6481 my $base64_salt_buf = encode_base64 ($salt_buf);
6482
6483 chomp ($base64_salt_buf);
6484
6485 $tmp_hash = sprintf ("sha1:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6486 }
6487 elsif ($mode == 12100)
6488 {
6489 my $iterations = 1000;
6490
6491 if (length ($iter))
6492 {
6493 $iterations = int ($iter);
6494 }
6495
6496 my $out_len = 16;
6497
6498 if (defined $additional_param)
6499 {
6500 $out_len = $additional_param;
6501 }
6502
6503 my $pbkdf2 = Crypt::PBKDF2->new
6504 (
6505 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
6506 iterations => $iterations,
6507 output_len => $out_len
6508 );
6509
6510 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6511 $hash_buf =~ s/[\r\n]//g;
6512
6513 my $base64_salt_buf = encode_base64 ($salt_buf);
6514
6515 chomp ($base64_salt_buf);
6516
6517 $tmp_hash = sprintf ("sha512:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6518 }
6519 elsif ($mode == 12200)
6520 {
6521 my $iterations = 65536;
6522
6523 my $default_salt = 0;
6524
6525 if (defined $additional_param)
6526 {
6527 $default_salt = int ($additional_param);
6528 }
6529
6530 if ($default_salt == 1)
6531 {
6532 $salt_buf = "0011223344556677";
6533 }
6534
6535 $hash_buf = sha512 (pack ("H*", $salt_buf) . $word_buf);
6536
6537 for (my $i = 0; $i < $iterations; $i++)
6538 {
6539 $hash_buf = sha512 ($hash_buf);
6540 }
6541
6542 $hash_buf = unpack ("H*", $hash_buf);
6543 $hash_buf = substr ($hash_buf, 0, 16);
6544
6545 if ($default_salt == 0)
6546 {
6547 $tmp_hash = sprintf ("\$ecryptfs\$0\$1\$%s\$%s", $salt_buf, $hash_buf);
6548 }
6549 else
6550 {
6551 $tmp_hash = sprintf ("\$ecryptfs\$0\$%s", $hash_buf);
6552 }
6553 }
6554 elsif ($mode == 12300)
6555 {
6556 my $iterations = 4096;
6557
6558 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512);
6559
6560 my $pbkdf2 = Crypt::PBKDF2->new (
6561 hasher => $hasher,
6562 iterations => $iterations,
6563 output_len => 64
6564 );
6565
6566 my $salt_bin = pack ("H*", $salt_buf);
6567
6568 my $key = $pbkdf2->PBKDF2 ($salt_bin. "AUTH_PBKDF2_SPEEDY_KEY", $word_buf);
6569
6570 $hash_buf = sha512_hex ($key . $salt_bin);
6571
6572 $tmp_hash = sprintf ("%s%s", uc ($hash_buf), uc ($salt_buf));
6573 }
6574 elsif ($mode == 12400)
6575 {
6576 my $iterations;
6577
6578 if (length ($iter))
6579 {
6580 $iterations = int ($iter);
6581 }
6582 else
6583 {
6584 $iterations = get_random_num (1, 5001 + 1);
6585 }
6586
6587 my $key_value = fold_password ($word_buf);
6588
6589 my $data = "\x00\x00\x00\x00\x00\x00\x00\x00";
6590 my $salt_value = base64_to_int24 ($salt_buf);
6591
6592 $hash_buf = crypt_rounds ($key_value, $iterations, $salt_value, $data);
6593
6594 $tmp_hash = sprintf ("_%s%s%s", int24_to_base64 ($iterations), $salt_buf, block_to_base64 ($hash_buf));
6595 }
6596 elsif ($mode == 12600)
6597 {
6598 $hash_buf = sha1_hex ($word_buf);
6599
6600 $hash_buf = sha256_hex ($salt_buf . uc $hash_buf);
6601
6602 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
6603 }
6604 elsif ($mode == 12700)
6605 {
6606 my $iterations = 10;
6607
6608 my $data = qq|{
6609 "guid" : "00000000-0000-0000-0000-000000000000",
6610 "sharedKey" : "00000000-0000-0000-0000-000000000000",
6611 "options" : {"pbkdf2_iterations":10,"fee_policy":0,"html5_notifications":false,"logout_time":600000,"tx_display":0,"always_keep_local_backup":false}|;
6612
6613 my $salt_buf_bin = pack ("H*", $salt_buf);
6614
6615 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
6616
6617 my $pbkdf2 = Crypt::PBKDF2->new (
6618 hasher => $hasher,
6619 iterations => $iterations,
6620 output_len => 32
6621 );
6622
6623 my $key = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6624
6625 my $cipher = Crypt::CBC->new ({
6626 key => $key,
6627 cipher => "Crypt::Rijndael",
6628 iv => $salt_buf_bin,
6629 literal_key => 1,
6630 header => "none",
6631 keysize => 32
6632 });
6633
6634 my $encrypted = unpack ("H*", $cipher->encrypt ($data));
6635
6636 $tmp_hash = sprintf ("\$blockchain\$%s\$%s", length ($salt_buf . $encrypted) / 2, $salt_buf . $encrypted);
6637 }
6638 elsif ($mode == 12800)
6639 {
6640 my $iterations = 100;
6641
6642 if (length ($iter))
6643 {
6644 $iterations = int ($iter);
6645 }
6646
6647 my $nt = md4_hex (encode ("UTF-16LE", $word_buf));
6648
6649 my $pbkdf2 = Crypt::PBKDF2->new
6650 (
6651 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6652 iterations => $iterations,
6653 output_len => 32
6654 );
6655
6656 my $salt_buf_bin = pack ("H*", $salt_buf);
6657
6658 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, uc (encode ("UTF-16LE", $nt)));
6659
6660 $tmp_hash = sprintf ("v1;PPH1_MD4,%s,%d,%s", $salt_buf, $iterations, unpack ("H*", $hash));
6661 }
6662 elsif ($mode == 12900)
6663 {
6664 my $iterations = 4096;
6665
6666 if (length ($iter))
6667 {
6668 $iterations = int ($iter);
6669 }
6670
6671 my $salt2 = $salt_buf . $salt_buf;
6672
6673 if (defined $additional_param)
6674 {
6675 $salt2 = $additional_param;
6676 }
6677
6678 my $pbkdf2 = Crypt::PBKDF2->new
6679 (
6680 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6681 iterations => $iterations,
6682 output_len => 32
6683 );
6684
6685 my $salt_buf_bin = pack ("H*", $salt_buf);
6686
6687 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6688
6689 my $salt2_bin = pack ("H*", $salt2);
6690
6691 my $hash_hmac = hmac_hex ($salt2_bin, $hash, \&sha256, 64);
6692
6693 $tmp_hash = sprintf ("%s%s%s", $salt2, $hash_hmac, $salt_buf);
6694 }
6695 elsif ($mode == 13000)
6696 {
6697 my $iterations = 15;
6698
6699 if (length ($iter))
6700 {
6701 $iterations = int ($iter);
6702 }
6703
6704 my $iv = "0" x 32;
6705
6706 if (defined $additional_param)
6707 {
6708 $iv = $additional_param;
6709 }
6710
6711 my $pbkdf2 = Crypt::PBKDF2->new
6712 (
6713 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6714 iterations => (1 << $iterations) + 32,
6715 output_len => 32
6716 );
6717
6718 my $salt_buf_bin = pack ("H*", $salt_buf);
6719
6720 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6721
6722 my $hash_final = substr ($hash, 0, 8)
6723 ^ substr ($hash, 8, 8)
6724 ^ substr ($hash, 16, 8)
6725 ^ substr ($hash, 24, 8);
6726
6727 $tmp_hash = sprintf ('$rar5$16$%s$%d$%s$8$%s', $salt_buf, $iterations, $iv, unpack ("H*", $hash_final));
6728 }
6729 elsif ($mode == 13100)
6730 {
6731 my @salt_arr = split ('\$', $salt_buf);
6732
6733 my $user = $salt_arr[0];
6734
6735 my $realm = $salt_arr[1];
6736
6737 my $spn = $salt_arr[2];
6738
6739 my $nonce = $salt_arr[3];
6740
6741 my $cleartext_ticket = '6381b03081ada00703050050a00000a11b3019a003020117a1'.
6742 '12041058e0d77776e8b8e03991f2966939222aa2171b154d594b5242544553542e434f4e5'.
6743 '44f534f2e434f4da3133011a003020102a10a30081b067472616e6365a40b3009a0030201'.
6744 '01a1020400a511180f32303136303231353134343735305aa611180f32303136303231353'.
6745 '134343735305aa711180f32303136303231363030343735305aa811180f32303136303232'.
6746 '323134343735305a';
6747
6748 $cleartext_ticket = $nonce . $cleartext_ticket;
6749
6750 my $k = md4 (encode ("UTF-16LE", $word_buf));
6751
6752 my $k1 = hmac_md5 ("\x02\x00\x00\x00", $k);
6753
6754 my $checksum = hmac_md5 (pack ("H*", $cleartext_ticket), $k1);
6755
6756 my $k3 = hmac_md5 ($checksum, $k1);
6757
6758 my $cipher = Crypt::RC4->new ($k3);
6759
6760 my $edata2 = $cipher->RC4 (pack ("H*", $cleartext_ticket));
6761
6762 $tmp_hash = sprintf ('$krb5tgs$23$*%s$%s$%s*$%s$%s', $user, $realm, $spn, unpack ("H*", $checksum), unpack ("H*", $edata2));
6763 }
6764 elsif ($mode == 13200)
6765 {
6766 my @salt_arr = split ('\*', $salt_buf);
6767
6768 my $iteration = $salt_arr[0];
6769
6770 my $mysalt = $salt_arr[1];
6771
6772 $mysalt = pack ("H*", $mysalt);
6773
6774 my $DEK = randbytes (16);
6775
6776 my $iv = "a6a6a6a6a6a6a6a6";
6777
6778 my $KEK = sha1($word_buf);
6779
6780 $KEK = substr ($KEK ^ $mysalt, 0, 16);
6781
6782 my $aes = Crypt::Mode::ECB->new ('AES');
6783
6784 my @R = ('', substr(pack ("H*",$DEK),0,8), substr(pack ("H*",$DEK),8,16));
6785
6786 my $B;
6787
6788 my $A = pack ("H*", $iv);
6789
6790 for (my $j = 0; $j < $iteration; $j++)
6791 {
6792 $B = $aes->encrypt ($A . $R[1], $KEK);
6793
6794 $A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 1));
6795
6796 $R[1] = substr ($B, 8, 16);
6797
6798 $B = $aes->encrypt ($A . $R[2], $KEK);
6799
6800 $A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 2));
6801
6802 $R[2] = substr ($B, 8, 16);
6803 }
6804
6805 my $wrapped_key = unpack ("H*", $A . substr ($R[1], 0 ,8) . substr ($R[2], 0 ,8));
6806
6807 $mysalt = unpack ("H*", $mysalt);
6808
6809 $tmp_hash = sprintf ('$axcrypt$*1*%s*%s*%s', $iteration, $mysalt, $wrapped_key);
6810 }
6811
6812 return ($tmp_hash);
6813 }
6814
6815 sub rnd
6816 {
6817 my $mode = shift;
6818
6819 my $word_len = shift;
6820
6821 my $salt_len = shift;
6822
6823 my $max = $MAX_LEN;
6824
6825 $max = 15 if ($mode == 2410);
6826
6827 if ($is_unicode{$mode})
6828 {
6829 if (! $allow_long_salt{$mode})
6830 {
6831 $word_len = min ($word_len, int ($max / 2) - $salt_len);
6832 }
6833 else
6834 {
6835 $word_len = min ($word_len, int ($max / 2));
6836 }
6837 }
6838 elsif ($less_fifteen{$mode})
6839 {
6840 $word_len = min ($word_len, 15);
6841
6842 if ($mode == 2410)
6843 {
6844 $salt_len = min ($salt_len, 15 - $word_len);
6845 }
6846 }
6847 else
6848 {
6849 if (! $allow_long_salt{$mode})
6850 {
6851 $word_len = min ($word_len, $max - $salt_len);
6852 }
6853 }
6854
6855 if ($word_len < 1)
6856 {
6857 $word_len = 1;
6858 }
6859
6860 ##
6861 ## gen salt
6862 ##
6863
6864 my $salt_buf;
6865
6866 if ($mode == 4800)
6867 {
6868 my @salt_arr;
6869
6870 for (my $i = 0; $i < $salt_len; $i++)
6871 {
6872 my $c = get_random_chr (0x30, 0x39);
6873
6874 push (@salt_arr, $c);
6875 }
6876
6877 $salt_buf = join ("", @salt_arr);
6878
6879 $salt_buf = get_random_md5chap_salt ($salt_buf);
6880 }
6881 elsif ($mode == 5300 || $mode == 5400)
6882 {
6883 $salt_buf = get_random_ike_salt ();
6884 }
6885 elsif ($mode == 5500)
6886 {
6887 $salt_buf = get_random_netntlmv1_salt ($salt_len, $salt_len);
6888 }
6889 elsif ($mode == 5600)
6890 {
6891 $salt_buf = get_random_netntlmv2_salt ($salt_len, $salt_len);
6892 }
6893 elsif ($mode == 6600)
6894 {
6895 $salt_buf = get_random_agilekeychain_salt ();
6896 }
6897 elsif ($mode == 8200)
6898 {
6899 $salt_buf = get_random_cloudkeychain_salt ();
6900 }
6901 elsif ($mode == 8300)
6902 {
6903 $salt_buf = get_random_dnssec_salt ();
6904 }
6905 elsif ($mode == 13100)
6906 {
6907 $salt_buf = get_random_kerberos5_tgs_salt ();
6908 }
6909 elsif ($mode == 13200)
6910 {
6911 $salt_buf = get_random_axcrypt_salt ();
6912 }
6913 else
6914 {
6915 my @salt_arr;
6916
6917 for (my $i = 0; $i < $salt_len; $i++)
6918 {
6919 my $c = get_random_chr (0x30, 0x39);
6920
6921 push (@salt_arr, $c);
6922 }
6923
6924 $salt_buf = join ("", @salt_arr);
6925
6926 if ($mode == 7500)
6927 {
6928 $salt_buf = get_random_kerberos5_salt ($salt_buf);
6929 }
6930 }
6931
6932 ##
6933 ## gen plain
6934 ##
6935
6936 my @word_arr;
6937
6938 for (my $i = 0; $i < $word_len; $i++)
6939 {
6940 my $c = get_random_chr (0x30, 0x39);
6941
6942 push (@word_arr, $c);
6943 }
6944
6945 my $word_buf = join ("", @word_arr);
6946
6947 ##
6948 ## gen hash
6949 ##
6950
6951 my $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
6952
6953 ##
6954 ## run
6955 ##
6956
6957 my @cmd =
6958 (
6959 $hashcat,
6960 "-a 0 -m", $mode,
6961 $tmp_hash
6962 );
6963
6964 print sprintf ("echo -n %-20s | %s \${OPTS} %s %4d '%s'\n", $word_buf, @cmd);
6965 }
6966
6967 ##
6968 ## subs
6969 ##
6970
6971 sub min
6972 {
6973 $_[$_[0] > $_[1]];
6974 }
6975
6976 sub get_random_string
6977 {
6978 my $len = shift;
6979
6980 my @arr;
6981
6982 for (my $i = 0; $i < $len; $i++)
6983 {
6984 my $c = get_random_chr (0x30, 0x39);
6985
6986 push (@arr, $c);
6987 }
6988
6989 my $buf = join ("", @arr);
6990
6991 return $buf;
6992 }
6993
6994 sub get_random_num
6995 {
6996 my $min = shift;
6997 my $max = shift;
6998
6999 return int ((rand ($max - $min)) + $min);
7000 }
7001
7002 sub get_random_chr
7003 {
7004 return chr get_random_num (@_);
7005 }
7006
7007 sub domino_decode
7008 {
7009 my $str = shift;
7010
7011 my $decoded = "";
7012
7013 for (my $i = 0; $i < length ($str); $i += 4)
7014 {
7015 my $num = domino_base64_decode (substr ($str, $i, 4), 4);
7016
7017 $decoded .= chr (($num >> 16) & 0xff) . chr (($num >> 8) & 0xff) . chr ($num & 0xff);
7018 }
7019
7020 my $salt;
7021 my $digest;
7022 my $char;
7023
7024 $salt = substr ($decoded, 0, 5);
7025
7026 my $byte10 = (ord (substr ($salt, 3, 1)) - 4);
7027
7028 if ($byte10 < 0)
7029 {
7030 $byte10 = 256 + $byte10;
7031 }
7032
7033 substr ($salt, 3, 1) = chr ($byte10);
7034
7035 $digest = substr ($decoded, 5, 9);
7036 $char = substr ($str, 18, 1);
7037
7038 return ($digest, $salt, $char);
7039 }
7040
7041 sub domino_85x_decode
7042 {
7043 my $str = shift;
7044
7045 my $decoded = "";
7046
7047 for (my $i = 0; $i < length ($str); $i += 4)
7048 {
7049 my $num = domino_base64_decode (substr ($str, $i, 4), 4);
7050
7051 $decoded .= chr (($num >> 16) & 0xff) . chr (($num >> 8) & 0xff) . chr ($num & 0xff);
7052 }
7053
7054 my $digest;
7055 my $salt;
7056 my $iterations = -1;
7057 my $chars;
7058
7059 $salt = substr ($decoded, 0, 16); # longer than -m 8700 (5 vs 16 <- new)
7060
7061 my $byte10 = (ord (substr ($salt, 3, 1)) - 4);
7062
7063 if ($byte10 < 0)
7064 {
7065 $byte10 = 256 + $byte10;
7066 }
7067
7068 substr ($salt, 3, 1) = chr ($byte10);
7069
7070 $iterations = substr ($decoded, 16, 10);
7071
7072 if ($iterations =~ /^?d*$/)
7073 {
7074 # continue
7075
7076 $iterations = $iterations + 0; # hack: make sure it is an int now (atoi ())
7077 $chars = substr ($decoded, 26, 2); # in my example it is "02"
7078 $digest = substr ($decoded, 28, 8); # only of length of 8 vs 20 SHA1 bytes
7079 }
7080
7081 return ($digest, $salt, $iterations, $chars);
7082 }
7083
7084 sub domino_base64_decode
7085 {
7086 my $v = shift;
7087 my $n = shift;
7088
7089 my $itoa64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
7090
7091 my $ret = 0;
7092
7093 my $i = 1;
7094
7095 while ($i <= $n)
7096 {
7097 my $idx = (index ($itoa64, substr ($v, $n - $i, 1))) & 0x3f;
7098
7099 $ret += ($idx << (6 * ($i - 1)));
7100
7101 $i = $i + 1;
7102 }
7103
7104 return $ret
7105 }
7106
7107 sub domino_encode
7108 {
7109 my $final = shift;
7110 my $char = shift;
7111
7112 my $byte10 = (ord (substr ($final, 3, 1)) + 4);
7113
7114 if ($byte10 > 255)
7115 {
7116 $byte10 = $byte10 - 256;
7117 }
7118
7119 substr ($final, 3, 1) = chr ($byte10);
7120
7121 my $passwd = "";
7122
7123 $passwd .= domino_base64_encode ((int (ord (substr ($final, 0, 1))) << 16) | (int (ord (substr ($final, 1, 1))) << 8) | (int (ord (substr ($final, 2, 1)))), 4);
7124 $passwd .= domino_base64_encode ((int (ord (substr ($final, 3, 1))) << 16) | (int (ord (substr ($final, 4, 1))) << 8) | (int (ord (substr ($final, 5, 1)))), 4);
7125 $passwd .= domino_base64_encode ((int (ord (substr ($final, 6, 1))) << 16) | (int (ord (substr ($final, 7, 1))) << 8) | (int (ord (substr ($final, 8, 1)))), 4);
7126 $passwd .= domino_base64_encode ((int (ord (substr ($final, 9, 1))) << 16) | (int (ord (substr ($final, 10, 1))) << 8) | (int (ord (substr ($final, 11, 1)))), 4);
7127 $passwd .= domino_base64_encode ((int (ord (substr ($final, 12, 1))) << 16) | (int (ord (substr ($final, 13, 1))) << 8) | (int (ord (substr ($final, 14, 1)))), 4);
7128
7129 if (defined ($char))
7130 {
7131 substr ($passwd, 18, 1) = $char;
7132 }
7133 substr ($passwd, 19, 1) = "";
7134
7135 return $passwd;
7136 }
7137
7138 sub domino_85x_encode
7139 {
7140 my $final = shift;
7141 my $char = shift;
7142
7143 my $byte10 = (ord (substr ($final, 3, 1)) + 4);
7144
7145 if ($byte10 > 255)
7146 {
7147 $byte10 = $byte10 - 256;
7148 }
7149
7150 substr ($final, 3, 1) = chr ($byte10);
7151
7152 my $passwd = "";
7153
7154 $passwd .= domino_base64_encode ((int (ord (substr ($final, 0, 1))) << 16) | (int (ord (substr ($final, 1, 1))) << 8) | (int (ord (substr ($final, 2, 1)))), 4);
7155 $passwd .= domino_base64_encode ((int (ord (substr ($final, 3, 1))) << 16) | (int (ord (substr ($final, 4, 1))) << 8) | (int (ord (substr ($final, 5, 1)))), 4);
7156 $passwd .= domino_base64_encode ((int (ord (substr ($final, 6, 1))) << 16) | (int (ord (substr ($final, 7, 1))) << 8) | (int (ord (substr ($final, 8, 1)))), 4);
7157 $passwd .= domino_base64_encode ((int (ord (substr ($final, 9, 1))) << 16) | (int (ord (substr ($final, 10, 1))) << 8) | (int (ord (substr ($final, 11, 1)))), 4);
7158 $passwd .= domino_base64_encode ((int (ord (substr ($final, 12, 1))) << 16) | (int (ord (substr ($final, 13, 1))) << 8) | (int (ord (substr ($final, 14, 1)))), 4);
7159 $passwd .= domino_base64_encode ((int (ord (substr ($final, 15, 1))) << 16) | (int (ord (substr ($final, 16, 1))) << 8) | (int (ord (substr ($final, 17, 1)))), 4);
7160 $passwd .= domino_base64_encode ((int (ord (substr ($final, 18, 1))) << 16) | (int (ord (substr ($final, 19, 1))) << 8) | (int (ord (substr ($final, 20, 1)))), 4);
7161 $passwd .= domino_base64_encode ((int (ord (substr ($final, 21, 1))) << 16) | (int (ord (substr ($final, 22, 1))) << 8) | (int (ord (substr ($final, 23, 1)))), 4);
7162 $passwd .= domino_base64_encode ((int (ord (substr ($final, 24, 1))) << 16) | (int (ord (substr ($final, 25, 1))) << 8) | (int (ord (substr ($final, 26, 1)))), 4);
7163 $passwd .= domino_base64_encode ((int (ord (substr ($final, 27, 1))) << 16) | (int (ord (substr ($final, 28, 1))) << 8) | (int (ord (substr ($final, 29, 1)))), 4);
7164 $passwd .= domino_base64_encode ((int (ord (substr ($final, 30, 1))) << 16) | (int (ord (substr ($final, 31, 1))) << 8) | (int (ord (substr ($final, 32, 1)))), 4);
7165 $passwd .= domino_base64_encode ((int (ord (substr ($final, 33, 1))) << 16) | (int (ord (substr ($final, 34, 1))) << 8) | (int (ord (substr ($final, 35, 1)))), 4);
7166
7167 if (defined ($char))
7168 {
7169 substr ($passwd, 18, 1) = $char;
7170 }
7171
7172 return $passwd;
7173 }
7174
7175 sub domino_base64_encode
7176 {
7177 my $v = shift;
7178 my $n = shift;
7179
7180 my $itoa64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
7181
7182 my $ret = "";
7183
7184 while (($n - 1) >= 0)
7185 {
7186 $n = $n - 1;
7187
7188 $ret = substr ($itoa64, $v & 0x3f, 1) . $ret;
7189
7190 $v = $v >> 6;
7191 }
7192
7193 return $ret
7194 }
7195
7196 sub pseudo_base64
7197 {
7198 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7199
7200 my $md5 = shift;
7201 my $s64 = "";
7202 for my $i (0..3) {
7203 my $v = unpack "V", substr($md5, $i*4, 4);
7204 for (1..4) {
7205 $s64 .= substr($itoa64, $v & 0x3f, 1);
7206 $v >>= 6;
7207 }
7208 }
7209 return $s64;
7210 }
7211
7212 sub racf_hash
7213 {
7214 my ($username, $password) = @_;
7215
7216 $username = substr ($username . " " x 8, 0, 8);
7217 $password = substr ($password . " " x 8, 0, 8);
7218
7219 my $username_ebc = ascii2ebcdic ($username);
7220 my $password_ebc = ascii2ebcdic ($password);
7221
7222 my @pw = split ("", $password_ebc);
7223
7224 for (my $i = 0; $i < 8; $i++)
7225 {
7226 $pw[$i] = unpack ("C", $pw[$i]);
7227 $pw[$i] ^= 0x55;
7228 $pw[$i] <<= 1;
7229 $pw[$i] = pack ("C", $pw[$i] & 0xff);
7230 }
7231
7232 my $key = join ("", @pw);
7233
7234 my $cipher = new Crypt::DES $key;
7235
7236 my $ciphertext = $cipher->encrypt ($username_ebc);
7237
7238 my $ct = unpack ("H16", $ciphertext);
7239
7240 return $ct;
7241 }
7242
7243 sub oracle_hash
7244 {
7245 my ($username, $password) = @_;
7246
7247 my $userpass = pack('n*', unpack('C*', uc($username.$password)));
7248 $userpass .= pack('C', 0) while (length($userpass) % 8);
7249
7250 my $key = pack('H*', "0123456789ABCDEF");
7251 my $iv = pack('H*', "0000000000000000");
7252
7253 my $c = new Crypt::CBC(
7254 -literal_key => 1,
7255 -cipher => "DES",
7256 -key => $key,
7257 -iv => $iv,
7258 -header => "none"
7259 );
7260 my $key2 = substr($c->encrypt($userpass), length($userpass)-8, 8);
7261
7262 my $c2 = new Crypt::CBC(
7263 -literal_key => 1,
7264 -cipher => "DES",
7265 -key => $key2,
7266 -iv => $iv,
7267 -header => "none"
7268 );
7269 my $hash = substr($c2->encrypt($userpass), length($userpass)-8, 8);
7270
7271 return uc(unpack('H*', $hash));
7272 }
7273
7274 sub androidpin_hash
7275 {
7276 my $word_buf = shift;
7277
7278 my $salt_buf = shift;
7279
7280 my $w = sprintf ("%d%s%s", 0, $word_buf, $salt_buf);
7281
7282 my $digest = sha1 ($w);
7283
7284 for (my $i = 1; $i < 1024; $i++)
7285 {
7286 $w = $digest . sprintf ("%d%s%s", $i, $word_buf, $salt_buf);
7287
7288 $digest = sha1 ($w);
7289 }
7290
7291 my ($A, $B, $C, $D, $E) = unpack ("N5", $digest);
7292
7293 return sprintf ("%08x%08x%08x%08x%08x", $A, $B, $C, $D, $E);
7294 }
7295
7296 sub to64
7297 {
7298 my $v = shift;
7299 my $n = shift;
7300
7301 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7302
7303 my $ret = "";
7304
7305 while (($n - 1) >= 0)
7306 {
7307 $n = $n - 1;
7308
7309 $ret .= substr ($itoa64, $v & 0x3f, 1);
7310
7311 $v = $v >> 6;
7312 }
7313
7314 return $ret
7315 }
7316
7317 sub md5_crypt
7318 {
7319 my $magic = shift;
7320
7321 my $iter = shift;
7322 my $pass = shift;
7323 my $salt = shift;
7324
7325 my $hash = ""; # hash to be returned by this function
7326
7327 my $final = md5 ($pass . $salt . $pass);
7328
7329 $salt = substr ($salt, 0, 8);
7330
7331 my $tmp = $pass . $magic . $salt;
7332
7333 my $pass_len = length ($pass);
7334
7335 my $i;
7336
7337 for ($i = $pass_len; $i > 0; $i -= 16)
7338 {
7339 my $len = 16;
7340
7341 if ($i < $len)
7342 {
7343 $len = $i;
7344 }
7345
7346 $tmp .= substr ($final, 0, $len);
7347 }
7348
7349 $i = $pass_len;
7350
7351 while ($i > 0)
7352 {
7353 if ($i & 1)
7354 {
7355 $tmp .= chr (0);
7356 }
7357 else
7358 {
7359 $tmp .= substr ($pass, 0, 1);
7360 }
7361
7362 $i >>= 1;
7363 }
7364
7365 $final = md5 ($tmp);
7366
7367 for ($i = 0; $i < $iter; $i++)
7368 {
7369 $tmp = "";
7370
7371 if ($i & 1)
7372 {
7373 $tmp .= $pass;
7374 }
7375 else
7376 {
7377 $tmp .= $final;
7378 }
7379
7380 if ($i % 3)
7381 {
7382 $tmp .= $salt;
7383 }
7384
7385 if ($i % 7)
7386 {
7387 $tmp .= $pass;
7388 }
7389
7390 if ($i & 1)
7391 {
7392 $tmp .= $final;
7393 }
7394 else
7395 {
7396 $tmp .= $pass;
7397 }
7398
7399 $final = md5 ($tmp);
7400 }
7401
7402 # done
7403 # now format the output sting ("hash")
7404
7405 my $hash_buf;
7406
7407 $hash = to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 6, 1)) << 8) | (ord (substr ($final, 12, 1))), 4);
7408 $hash .= to64 ((ord (substr ($final, 1, 1)) << 16) | (ord (substr ($final, 7, 1)) << 8) | (ord (substr ($final, 13, 1))), 4);
7409 $hash .= to64 ((ord (substr ($final, 2, 1)) << 16) | (ord (substr ($final, 8, 1)) << 8) | (ord (substr ($final, 14, 1))), 4);
7410 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 9, 1)) << 8) | (ord (substr ($final, 15, 1))), 4);
7411 $hash .= to64 ((ord (substr ($final, 4, 1)) << 16) | (ord (substr ($final, 10, 1)) << 8) | (ord (substr ($final, 5, 1))), 4);
7412 $hash .= to64 (ord (substr ($final, 11, 1)), 2);
7413
7414 if ($iter == 1000) # default
7415 {
7416 $hash_buf = sprintf ("%s%s\$%s", $magic , $salt , $hash);
7417 }
7418 else
7419 {
7420 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
7421 }
7422
7423 return $hash_buf;
7424 }
7425
7426 sub sha512_crypt
7427 {
7428 my $iter = shift;
7429 my $pass = shift;
7430 my $salt = shift;
7431
7432 my $hash = ""; # hash to be returned by this function
7433
7434 my $final = sha512 ($pass . $salt . $pass);
7435
7436 $salt = substr ($salt, 0, 16);
7437
7438 my $tmp = $pass . $salt;
7439
7440 my $pass_len = length ($pass);
7441 my $salt_len = length ($salt);
7442
7443 my $i;
7444
7445 for ($i = $pass_len; $i > 0; $i -= 16)
7446 {
7447 my $len = 16;
7448
7449 if ($i < $len)
7450 {
7451 $len = $i;
7452 }
7453
7454 $tmp .= substr ($final, 0, $len);
7455 }
7456
7457 $i = $pass_len;
7458
7459 while ($i > 0)
7460 {
7461 if ($i & 1)
7462 {
7463 $tmp .= $final;
7464 }
7465 else
7466 {
7467 $tmp .= $pass;
7468 }
7469
7470 $i >>= 1;
7471 }
7472
7473 $final = sha512 ($tmp);
7474
7475 # p_bytes
7476
7477 my $p_bytes = "";
7478
7479 for ($i = 0; $i < $pass_len; $i++)
7480 {
7481 $p_bytes .= $pass;
7482 }
7483
7484 $p_bytes = sha512 ($p_bytes);
7485 $p_bytes = substr ($p_bytes, 0, $pass_len);
7486
7487 # s_bytes
7488
7489 my $final_first_byte = ord (substr ($final, 0, 1));
7490
7491 my $s_bytes = "";
7492
7493 for ($i = 0; $i < (16 + $final_first_byte); $i++)
7494 {
7495 $s_bytes .= $salt;
7496 }
7497
7498 $s_bytes = sha512 ($s_bytes);
7499 $s_bytes = substr ($s_bytes, 0, $salt_len);
7500
7501 for ($i = 0; $i < $iter; $i++)
7502 {
7503 $tmp = "";
7504
7505 if ($i & 1)
7506 {
7507 $tmp .= $p_bytes;
7508 }
7509 else
7510 {
7511 $tmp .= $final;
7512 }
7513
7514 if ($i % 3)
7515 {
7516 $tmp .= $s_bytes;
7517 }
7518
7519 if ($i % 7)
7520 {
7521 $tmp .= $p_bytes;
7522 }
7523
7524 if ($i & 1)
7525 {
7526 $tmp .= $final;
7527 }
7528 else
7529 {
7530 $tmp .= $p_bytes;
7531 }
7532
7533 $final = sha512 ($tmp);
7534 }
7535
7536 # done
7537 # now format the output string ("hash")
7538
7539 my $hash_buf;
7540
7541 $hash .= to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 21, 1)) << 8) | (ord (substr ($final, 42, 1))), 4);
7542 $hash .= to64 ((ord (substr ($final, 22, 1)) << 16) | (ord (substr ($final, 43, 1)) << 8) | (ord (substr ($final, 1, 1))), 4);
7543 $hash .= to64 ((ord (substr ($final, 44, 1)) << 16) | (ord (substr ($final, 2, 1)) << 8) | (ord (substr ($final, 23, 1))), 4);
7544 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 24, 1)) << 8) | (ord (substr ($final, 45, 1))), 4);
7545 $hash .= to64 ((ord (substr ($final, 25, 1)) << 16) | (ord (substr ($final, 46, 1)) << 8) | (ord (substr ($final, 4, 1))), 4);
7546 $hash .= to64 ((ord (substr ($final, 47, 1)) << 16) | (ord (substr ($final, 5, 1)) << 8) | (ord (substr ($final, 26, 1))), 4);
7547 $hash .= to64 ((ord (substr ($final, 6, 1)) << 16) | (ord (substr ($final, 27, 1)) << 8) | (ord (substr ($final, 48, 1))), 4);
7548 $hash .= to64 ((ord (substr ($final, 28, 1)) << 16) | (ord (substr ($final, 49, 1)) << 8) | (ord (substr ($final, 7, 1))), 4);
7549 $hash .= to64 ((ord (substr ($final, 50, 1)) << 16) | (ord (substr ($final, 8, 1)) << 8) | (ord (substr ($final, 29, 1))), 4);
7550 $hash .= to64 ((ord (substr ($final, 9, 1)) << 16) | (ord (substr ($final, 30, 1)) << 8) | (ord (substr ($final, 51, 1))), 4);
7551 $hash .= to64 ((ord (substr ($final, 31, 1)) << 16) | (ord (substr ($final, 52, 1)) << 8) | (ord (substr ($final, 10, 1))), 4);
7552 $hash .= to64 ((ord (substr ($final, 53, 1)) << 16) | (ord (substr ($final, 11, 1)) << 8) | (ord (substr ($final, 32, 1))), 4);
7553 $hash .= to64 ((ord (substr ($final, 12, 1)) << 16) | (ord (substr ($final, 33, 1)) << 8) | (ord (substr ($final, 54, 1))), 4);
7554 $hash .= to64 ((ord (substr ($final, 34, 1)) << 16) | (ord (substr ($final, 55, 1)) << 8) | (ord (substr ($final, 13, 1))), 4);
7555 $hash .= to64 ((ord (substr ($final, 56, 1)) << 16) | (ord (substr ($final, 14, 1)) << 8) | (ord (substr ($final, 35, 1))), 4);
7556 $hash .= to64 ((ord (substr ($final, 15, 1)) << 16) | (ord (substr ($final, 36, 1)) << 8) | (ord (substr ($final, 57, 1))), 4);
7557 $hash .= to64 ((ord (substr ($final, 37, 1)) << 16) | (ord (substr ($final, 58, 1)) << 8) | (ord (substr ($final, 16, 1))), 4);
7558 $hash .= to64 ((ord (substr ($final, 59, 1)) << 16) | (ord (substr ($final, 17, 1)) << 8) | (ord (substr ($final, 38, 1))), 4);
7559 $hash .= to64 ((ord (substr ($final, 18, 1)) << 16) | (ord (substr ($final, 39, 1)) << 8) | (ord (substr ($final, 60, 1))), 4);
7560 $hash .= to64 ((ord (substr ($final, 40, 1)) << 16) | (ord (substr ($final, 61, 1)) << 8) | (ord (substr ($final, 19, 1))), 4);
7561 $hash .= to64 ((ord (substr ($final, 62, 1)) << 16) | (ord (substr ($final, 20, 1)) << 8) | (ord (substr ($final, 41, 1))), 4);
7562 $hash .= to64 (ord (substr ($final, 63, 1)), 2);
7563
7564 my $magic = '$6$';
7565
7566 if ($iter == 5000) # default
7567 {
7568 $hash_buf = sprintf ("%s%s\$%s", $magic, $salt , $hash);
7569 }
7570 else
7571 {
7572 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
7573 }
7574
7575 return $hash_buf;
7576 }
7577
7578 sub sha256_crypt
7579 {
7580 my $iter = shift;
7581 my $pass = shift;
7582 my $salt = shift;
7583
7584 my $hash = ""; # hash to be returned by this function
7585
7586 my $final = sha256 ($pass . $salt . $pass);
7587
7588 $salt = substr ($salt, 0, 16);
7589
7590 my $tmp = $pass . $salt;
7591
7592 my $pass_len = length ($pass);
7593 my $salt_len = length ($salt);
7594
7595 my $i;
7596
7597 for ($i = $pass_len; $i > 0; $i -= 16)
7598 {
7599 my $len = 16;
7600
7601 if ($i < $len)
7602 {
7603 $len = $i;
7604 }
7605
7606 $tmp .= substr ($final, 0, $len);
7607 }
7608
7609 $i = $pass_len;
7610
7611 while ($i > 0)
7612 {
7613 if ($i & 1)
7614 {
7615 $tmp .= $final;
7616 }
7617 else
7618 {
7619 $tmp .= $pass;
7620 }
7621
7622 $i >>= 1;
7623 }
7624
7625 $final = sha256 ($tmp);
7626
7627 # p_bytes
7628
7629 my $p_bytes = "";
7630
7631 for ($i = 0; $i < $pass_len; $i++)
7632 {
7633 $p_bytes .= $pass;
7634 }
7635
7636 $p_bytes = sha256 ($p_bytes);
7637 $p_bytes = substr ($p_bytes, 0, $pass_len);
7638
7639 # s_bytes
7640
7641 my $final_first_byte = ord (substr ($final, 0, 1));
7642
7643 my $s_bytes = "";
7644
7645 for ($i = 0; $i < (16 + $final_first_byte); $i++)
7646 {
7647 $s_bytes .= $salt;
7648 }
7649
7650 $s_bytes = sha256 ($s_bytes);
7651 $s_bytes = substr ($s_bytes, 0, $salt_len);
7652
7653 for ($i = 0; $i < $iter; $i++)
7654 {
7655 $tmp = "";
7656
7657 if ($i & 1)
7658 {
7659 $tmp .= $p_bytes;
7660 }
7661 else
7662 {
7663 $tmp .= $final;
7664 }
7665
7666 if ($i % 3)
7667 {
7668 $tmp .= $s_bytes;
7669 }
7670
7671 if ($i % 7)
7672 {
7673 $tmp .= $p_bytes;
7674 }
7675
7676 if ($i & 1)
7677 {
7678 $tmp .= $final;
7679 }
7680 else
7681 {
7682 $tmp .= $p_bytes;
7683 }
7684
7685 $final = sha256 ($tmp);
7686 }
7687
7688 # done
7689 # now format the output string ("hash")
7690
7691 my $hash_buf;
7692
7693 $hash .= to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 10, 1)) << 8) | (ord (substr ($final, 20, 1))), 4);
7694 $hash .= to64 ((ord (substr ($final, 21, 1)) << 16) | (ord (substr ($final, 1, 1)) << 8) | (ord (substr ($final, 11, 1))), 4);
7695 $hash .= to64 ((ord (substr ($final, 12, 1)) << 16) | (ord (substr ($final, 22, 1)) << 8) | (ord (substr ($final, 2, 1))), 4);
7696 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 13, 1)) << 8) | (ord (substr ($final, 23, 1))), 4);
7697 $hash .= to64 ((ord (substr ($final, 24, 1)) << 16) | (ord (substr ($final, 4, 1)) << 8) | (ord (substr ($final, 14, 1))), 4);
7698 $hash .= to64 ((ord (substr ($final, 15, 1)) << 16) | (ord (substr ($final, 25, 1)) << 8) | (ord (substr ($final, 5, 1))), 4);
7699 $hash .= to64 ((ord (substr ($final, 6, 1)) << 16) | (ord (substr ($final, 16, 1)) << 8) | (ord (substr ($final, 26, 1))), 4);
7700 $hash .= to64 ((ord (substr ($final, 27, 1)) << 16) | (ord (substr ($final, 7, 1)) << 8) | (ord (substr ($final, 17, 1))), 4);
7701 $hash .= to64 ((ord (substr ($final, 18, 1)) << 16) | (ord (substr ($final, 28, 1)) << 8) | (ord (substr ($final, 8, 1))), 4);
7702 $hash .= to64 ((ord (substr ($final, 9, 1)) << 16) | (ord (substr ($final, 19, 1)) << 8) | (ord (substr ($final, 29, 1))), 4);
7703 $hash .= to64 ((ord (substr ($final, 31, 1)) << 8) | (ord (substr ($final, 30, 1))), 3);
7704
7705 my $magic = '$5$';
7706
7707 if ($iter == 5000) # default
7708 {
7709 $hash_buf = sprintf ("%s%s\$%s", $magic, $salt , $hash);
7710 }
7711 else
7712 {
7713 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
7714 }
7715
7716 return $hash_buf;
7717 }
7718
7719 sub aix_ssha256_pbkdf2
7720 {
7721 my $word_buf = shift;
7722 my $salt_buf = shift;
7723 my $iterations = shift;
7724
7725 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256);
7726
7727 my $pbkdf2 = Crypt::PBKDF2->new (
7728 hasher => $hasher,
7729 iterations => $iterations,
7730 output_len => 32
7731 );
7732
7733 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
7734
7735 my $tmp_hash = "";
7736
7737 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4);
7738 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4);
7739 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4);
7740 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4);
7741 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4);
7742 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4);
7743 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) | (int (ord (substr ($hash_buf, 20, 1)))), 4);
7744 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 21, 1))) << 16) | (int (ord (substr ($hash_buf, 22, 1))) << 8) | (int (ord (substr ($hash_buf, 23, 1)))), 4);
7745 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 24, 1))) << 16) | (int (ord (substr ($hash_buf, 25, 1))) << 8) | (int (ord (substr ($hash_buf, 26, 1)))), 4);
7746 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 27, 1))) << 16) | (int (ord (substr ($hash_buf, 28, 1))) << 8) | (int (ord (substr ($hash_buf, 29, 1)))), 4);
7747 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) , 3);
7748
7749 return $tmp_hash;
7750 }
7751
7752 sub aix_ssha512_pbkdf2
7753 {
7754 my $word_buf = shift;
7755 my $salt_buf = shift;
7756 my $iterations = shift;
7757
7758 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512);
7759
7760 my $pbkdf2 = Crypt::PBKDF2->new (
7761 hasher => $hasher,
7762 iterations => $iterations,
7763 );
7764
7765 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
7766
7767 my $tmp_hash = "";
7768
7769 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4);
7770 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4);
7771 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4);
7772 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4);
7773 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4);
7774 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4);
7775 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) | (int (ord (substr ($hash_buf, 20, 1)))), 4);
7776 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 21, 1))) << 16) | (int (ord (substr ($hash_buf, 22, 1))) << 8) | (int (ord (substr ($hash_buf, 23, 1)))), 4);
7777 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 24, 1))) << 16) | (int (ord (substr ($hash_buf, 25, 1))) << 8) | (int (ord (substr ($hash_buf, 26, 1)))), 4);
7778 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 27, 1))) << 16) | (int (ord (substr ($hash_buf, 28, 1))) << 8) | (int (ord (substr ($hash_buf, 29, 1)))), 4);
7779 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) | (int (ord (substr ($hash_buf, 32, 1)))), 4);
7780 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 33, 1))) << 16) | (int (ord (substr ($hash_buf, 34, 1))) << 8) | (int (ord (substr ($hash_buf, 35, 1)))), 4);
7781 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 36, 1))) << 16) | (int (ord (substr ($hash_buf, 37, 1))) << 8) | (int (ord (substr ($hash_buf, 38, 1)))), 4);
7782 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 39, 1))) << 16) | (int (ord (substr ($hash_buf, 40, 1))) << 8) | (int (ord (substr ($hash_buf, 41, 1)))), 4);
7783 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 42, 1))) << 16) | (int (ord (substr ($hash_buf, 43, 1))) << 8) | (int (ord (substr ($hash_buf, 44, 1)))), 4);
7784 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 45, 1))) << 16) | (int (ord (substr ($hash_buf, 46, 1))) << 8) | (int (ord (substr ($hash_buf, 47, 1)))), 4);
7785 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 48, 1))) << 16) | (int (ord (substr ($hash_buf, 49, 1))) << 8) | (int (ord (substr ($hash_buf, 50, 1)))), 4);
7786 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 51, 1))) << 16) | (int (ord (substr ($hash_buf, 52, 1))) << 8) | (int (ord (substr ($hash_buf, 53, 1)))), 4);
7787 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 54, 1))) << 16) | (int (ord (substr ($hash_buf, 55, 1))) << 8) | (int (ord (substr ($hash_buf, 56, 1)))), 4);
7788 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 57, 1))) << 16) | (int (ord (substr ($hash_buf, 58, 1))) << 8) | (int (ord (substr ($hash_buf, 59, 1)))), 4);
7789 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 60, 1))) << 16) | (int (ord (substr ($hash_buf, 61, 1))) << 8) | (int (ord (substr ($hash_buf, 62, 1)))), 4);
7790 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 63, 1))) << 16) , 2);
7791
7792 return $tmp_hash;
7793 }
7794
7795 sub aix_ssha1_pbkdf2
7796 {
7797 my $word_buf = shift;
7798 my $salt_buf = shift;
7799 my $iterations = shift;
7800
7801 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
7802
7803 my $pbkdf2 = Crypt::PBKDF2->new (
7804 hasher => $hasher,
7805 iterations => $iterations,
7806 );
7807
7808 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
7809
7810 my $tmp_hash = "";
7811
7812 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4);
7813 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4);
7814 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4);
7815 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4);
7816 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4);
7817 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4);
7818 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) , 3);
7819
7820 return $tmp_hash;
7821 }
7822
7823 sub sapb_transcode
7824 {
7825 my $data_s = shift;
7826
7827 my @data = split "", $data_s;
7828
7829 my $transTable_s =
7830 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7831 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7832 "\x3f\x40\x41\x50\x43\x44\x45\x4b\x47\x48\x4d\x4e\x54\x51\x53\x46" .
7833 "\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x56\x55\x5c\x49\x5d\x4a" .
7834 "\x42\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" .
7835 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x58\x5b\x59\xff\x52" .
7836 "\x4c\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" .
7837 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x57\x5e\x5a\x4f\xff" .
7838 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7839 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7840 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7841 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7842 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7843 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7844 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
7845 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
7846
7847 my @transTable = unpack ("C256", $transTable_s);
7848
7849 my @out;
7850
7851 for (my $i = 0; $i < scalar @data; $i++)
7852 {
7853 $out[$i] = $transTable[int (ord ($data[$i]))];
7854 }
7855
7856 return pack ("C*", @out);
7857 }
7858
7859 sub sapb_waldorf
7860 {
7861 my $digest_s = shift;
7862
7863 my $w_s = shift;
7864 my $s_s = shift;
7865
7866 my @w = unpack "C*", $w_s;
7867 my @s = unpack "C*", $s_s;
7868
7869 my $bcodeTable_s =
7870 "\x14\x77\xf3\xd4\xbb\x71\x23\xd0\x03\xff\x47\x93\x55\xaa\x66\x91" .
7871 "\xf2\x88\x6b\x99\xbf\xcb\x32\x1a\x19\xd9\xa7\x82\x22\x49\xa2\x51" .
7872 "\xe2\xb7\x33\x71\x8b\x9f\x5d\x01\x44\x70\xae\x11\xef\x28\xf0\x0d";
7873
7874 my @bcodeTable = unpack ("C48", $bcodeTable_s);
7875
7876 my @abcd = unpack ("C16", $digest_s);
7877
7878 my $sum20 = ($abcd[0] & 3)
7879 + ($abcd[1] & 3)
7880 + ($abcd[2] & 3)
7881 + ($abcd[3] & 3)
7882 + ($abcd[5] & 3);
7883
7884 $sum20 |= 0x20;
7885
7886 my @out;
7887
7888 for (my $i2 = 0; $i2 < $sum20; $i2++)
7889 {
7890 $out[$i2] = 0;
7891 }
7892
7893 for (my $i1 = 0, my $i2 = 0, my $i3 = 0; $i2 < $sum20; $i2++, $i2++)
7894 {
7895 if ($i1 < length $w_s)
7896 {
7897 if ($abcd[15 - $i1] & 1)
7898 {
7899 $out[$i2] = $bcodeTable[48 - 1 - $i1];
7900
7901 $i2++;
7902 }
7903
7904 $out[$i2] = $w[$i1];
7905
7906 $i1++;
7907 $i2++;
7908 }
7909
7910 if ($i3 < length $s_s)
7911 {
7912 $out[$i2] = $s[$i3];
7913
7914 $i2++;
7915 $i3++;
7916 }
7917
7918 $out[$i2] = $bcodeTable[$i2 - $i1 - $i3];
7919 }
7920
7921 return substr (pack ("C*", @out), 0, $sum20);
7922 }
7923
7924 sub setup_des_key
7925 {
7926 my @key_56 = split (//, shift);
7927
7928 my $key = "";
7929
7930 $key = $key_56[0];
7931
7932 $key .= chr(((ord($key_56[0]) << 7) | (ord($key_56[1]) >> 1)) & 255);
7933 $key .= chr(((ord($key_56[1]) << 6) | (ord($key_56[2]) >> 2)) & 255);
7934 $key .= chr(((ord($key_56[2]) << 5) | (ord($key_56[3]) >> 3)) & 255);
7935 $key .= chr(((ord($key_56[3]) << 4) | (ord($key_56[4]) >> 4)) & 255);
7936 $key .= chr(((ord($key_56[4]) << 3) | (ord($key_56[5]) >> 5)) & 255);
7937 $key .= chr(((ord($key_56[5]) << 2) | (ord($key_56[6]) >> 6)) & 255);
7938 $key .= chr(( ord($key_56[6]) << 1) & 255);
7939
7940 return $key;
7941 }
7942
7943 sub randbytes
7944 {
7945 my $len = shift;
7946
7947 my @arr;
7948
7949 for (my $i = 0; $i < $len; $i++)
7950 {
7951 my $c = get_random_chr (0, 255);
7952
7953 push (@arr, $c);
7954 }
7955
7956 return join ("", @arr);
7957 }
7958
7959 sub get_random_netntlmv1_salt
7960 {
7961 my $len_user = shift;
7962 my $len_domain = shift;
7963
7964 my $char;
7965 my $type;
7966 my $user = "";
7967
7968 for (my $i = 0; $i < $len_user; $i++)
7969 {
7970 $type = get_random_num (1, 3);
7971
7972 if ($type == 1)
7973 {
7974 $char = get_random_chr (0x30, 0x39);
7975 }
7976 elsif ($type == 2)
7977 {
7978 $char = get_random_chr (0x41, 0x5A);
7979 }
7980 else
7981 {
7982 $char = get_random_chr (0x61, 0x7A);
7983 }
7984
7985 $user .= $char;
7986 }
7987
7988 my $domain = "";
7989
7990 for (my $i = 0; $i < $len_domain; $i++)
7991 {
7992 $type = get_random_num (1, 3);
7993
7994 if ($type == 1)
7995 {
7996 $char = get_random_chr (0x30, 0x39);
7997 }
7998 elsif ($type == 2)
7999 {
8000 $char = get_random_chr (0x41, 0x5A);
8001 }
8002 else
8003 {
8004 $char = get_random_chr (0x61, 0x7A);
8005 }
8006
8007 $domain .= $char;
8008 }
8009
8010 my $c_challenge = randbytes (8);
8011 my $s_challenge = randbytes (8);
8012
8013 my $salt_buf = $user . "::" . $domain . ":" . unpack ("H*", $c_challenge) . unpack ("H*", $s_challenge);
8014
8015 return $salt_buf;
8016 }
8017
8018 sub get_random_netntlmv2_salt
8019 {
8020 my $len_user = shift;
8021 my $len_domain = shift;
8022
8023 my $char;
8024 my $type;
8025 my $user = "";
8026
8027 if ($len_user + $len_domain > 27)
8028 {
8029 if ($len_user > $len_domain)
8030 {
8031 $len_user = 27 - $len_domain;
8032 }
8033 else
8034 {
8035 $len_domain = 27 - $len_user;
8036 }
8037 }
8038
8039 for (my $i = 0; $i < $len_user; $i++)
8040 {
8041 $type = get_random_num (1, 3);
8042
8043 if ($type == 1)
8044 {
8045 $char = get_random_chr (0x30, 0x39);
8046 }
8047 elsif ($type == 2)
8048 {
8049 $char = get_random_chr (0x41, 0x5A);
8050 }
8051 else
8052 {
8053 $char = get_random_chr (0x61, 0x7A);
8054 }
8055
8056 $user .= $char;
8057 }
8058
8059 my $domain = "";
8060
8061 for (my $i = 0; $i < $len_domain; $i++)
8062 {
8063 $type = get_random_num (1, 3);
8064
8065 if ($type == 1)
8066 {
8067 $char = get_random_chr (0x30, 0x39);
8068 }
8069 elsif ($type == 2)
8070 {
8071 $char = get_random_chr (0x41, 0x5A);
8072 }
8073 else
8074 {
8075 $char = get_random_chr (0x61, 0x7A);
8076 }
8077
8078 $domain .= $char;
8079 }
8080
8081 my $c_challenge = randbytes (8);
8082 my $s_challenge = randbytes (8);
8083
8084 my $temp = "\x01\x01" .
8085 "\x00" x 6 .
8086 randbytes (8) .
8087 $c_challenge .
8088 "\x00" x 4 .
8089 randbytes (20 * rand () + 1) .
8090 "\x00";
8091
8092 my $salt_buf = $user . "::" . $domain . ":" . unpack ("H*", $s_challenge) . unpack ("H*", $temp);
8093
8094 return $salt_buf;
8095 }
8096
8097 sub get_random_ike_salt
8098 {
8099 my $nr_buf = "";
8100
8101 for (my $i = 0; $i < 40; $i++)
8102 {
8103 $nr_buf .= get_random_chr (0, 0xff);
8104 }
8105
8106 my $msg_buf = "";
8107
8108 for (my $i = 0; $i < 440; $i++)
8109 {
8110 $msg_buf .= get_random_chr (0, 0xff);
8111 }
8112
8113 my $nr_buf_hex = unpack ("H*", $nr_buf);
8114 my $msg_buf_hex = unpack ("H*", $msg_buf);
8115
8116 my $salt_buf = sprintf ("%s:%s:%s:%s:%s:%s:%s:%s", substr ($msg_buf_hex, 0, 256), substr ($msg_buf_hex, 256, 256), substr ($msg_buf_hex, 512, 16), substr ($msg_buf_hex, 528, 16), substr ($msg_buf_hex, 544, 320), substr ($msg_buf_hex, 864, 16), substr ($nr_buf_hex, 0, 40), substr ($nr_buf_hex, 40, 40));
8117
8118 return $salt_buf;
8119 }
8120
8121 sub get_random_agilekeychain_salt
8122 {
8123 my $salt_buf = "";
8124
8125 for (my $i = 0; $i < 8; $i++)
8126 {
8127 $salt_buf .= get_random_chr (0x0, 0xff);
8128 }
8129
8130 my $iv = "";
8131
8132 for (my $i = 0; $i < 16; $i++)
8133 {
8134 $iv .= get_random_chr (0x0, 0xff);
8135 }
8136
8137 my $prefix = "\x00" x 1008;
8138
8139 my $ret = unpack ("H*", $salt_buf . $prefix . $iv);
8140
8141 return $ret;
8142 }
8143
8144 sub get_random_cloudkeychain_salt
8145 {
8146 my $salt_buf = "";
8147
8148 for (my $i = 0; $i < 16; $i++)
8149 {
8150 $salt_buf .= get_random_chr (0x0, 0xff);
8151 }
8152
8153 for (my $i = 0; $i < 304; $i++)
8154 {
8155 $salt_buf .= get_random_chr (0x0, 0xff);
8156 }
8157
8158 my $ret = unpack ("H*", $salt_buf);
8159
8160 return $ret;
8161 }
8162
8163 sub get_random_kerberos5_salt
8164 {
8165 my $custom_salt = shift;
8166
8167 my $clear_data = randbytes (14) .
8168 strftime ("%Y%m%d%H%M%S", localtime) .
8169 randbytes (8);
8170
8171 my $user = "user";
8172 my $realm = "realm";
8173 my $salt = "salt";
8174
8175 my $salt_buf = $user . "\$" . $realm . "\$" . $salt . "\$" . unpack ("H*", $custom_salt) . "\$" . unpack ("H*", $clear_data) . "\$";
8176
8177 return $salt_buf;
8178 }
8179
8180 sub get_random_kerberos5_tgs_salt
8181 {
8182 my $nonce = randbytes (8);
8183
8184 my $user = "user";
8185 my $realm = "realm";
8186 my $spn = "test/spn";
8187
8188 my $salt_buf = $user . "\$" . $realm . "\$" . $spn . "\$" . unpack ("H*",$nonce);
8189
8190 return $salt_buf;
8191 }
8192
8193 sub get_random_axcrypt_salt
8194 {
8195 my $mysalt = randbytes (16);
8196
8197 $mysalt = unpack ("H*", $mysalt);
8198
8199 my $iteration = get_random_num (6, 100000);
8200
8201 my $salt_buf = $iteration . '*' . $mysalt;
8202
8203 return $salt_buf;
8204 }
8205
8206 sub get_random_md5chap_salt
8207 {
8208 my $salt_buf = shift;
8209
8210 my $salt = unpack ("H*", $salt_buf);
8211
8212 $salt .= ":";
8213
8214 $salt .= unpack ("H*", randbytes (1));
8215
8216 return $salt;
8217 }
8218
8219 sub get_random_dnssec_salt
8220 {
8221 my $salt_buf = "";
8222
8223 $salt_buf .= ".";
8224
8225 for (my $i = 0; $i < 8; $i++)
8226 {
8227 $salt_buf .= get_random_chr (0x61, 0x7a);
8228 }
8229
8230 $salt_buf .= ".net";
8231
8232 $salt_buf .= ":";
8233
8234 for (my $i = 0; $i < 8; $i++)
8235 {
8236 $salt_buf .= get_random_chr (0x30, 0x39);
8237 }
8238
8239 return $salt_buf;
8240 }
8241
8242 sub md5bit
8243 {
8244 my $digest = shift;
8245 my $bit = shift;
8246
8247 $bit %= 128;
8248
8249 my $byte_off = int ($bit / 8);
8250 my $bit_off = int ($bit % 8);
8251
8252 my $char = substr ($digest, $byte_off, 1);
8253 my $num = ord ($char);
8254
8255 return (($num & (1 << $bit_off)) ? 1 : 0);
8256 }
8257
8258 sub sun_md5
8259 {
8260 my $pw = shift;
8261 my $salt = shift;
8262 my $iter = shift;
8263
8264 my $constant_phrase =
8265 "To be, or not to be,--that is the question:--\n" .
8266 "Whether 'tis nobler in the mind to suffer\n" .
8267 "The slings and arrows of outrageous fortune\n" .
8268 "Or to take arms against a sea of troubles,\n" .
8269 "And by opposing end them?--To die,--to sleep,--\n" .
8270 "No more; and by a sleep to say we end\n" .
8271 "The heartache, and the thousand natural shocks\n" .
8272 "That flesh is heir to,--'tis a consummation\n" .
8273 "Devoutly to be wish'd. To die,--to sleep;--\n" .
8274 "To sleep! perchance to dream:--ay, there's the rub;\n" .
8275 "For in that sleep of death what dreams may come,\n" .
8276 "When we have shuffled off this mortal coil,\n" .
8277 "Must give us pause: there's the respect\n" .
8278 "That makes calamity of so long life;\n" .
8279 "For who would bear the whips and scorns of time,\n" .
8280 "The oppressor's wrong, the proud man's contumely,\n" .
8281 "The pangs of despis'd love, the law's delay,\n" .
8282 "The insolence of office, and the spurns\n" .
8283 "That patient merit of the unworthy takes,\n" .
8284 "When he himself might his quietus make\n" .
8285 "With a bare bodkin? who would these fardels bear,\n" .
8286 "To grunt and sweat under a weary life,\n" .
8287 "But that the dread of something after death,--\n" .
8288 "The undiscover'd country, from whose bourn\n" .
8289 "No traveller returns,--puzzles the will,\n" .
8290 "And makes us rather bear those ills we have\n" .
8291 "Than fly to others that we know not of?\n" .
8292 "Thus conscience does make cowards of us all;\n" .
8293 "And thus the native hue of resolution\n" .
8294 "Is sicklied o'er with the pale cast of thought;\n" .
8295 "And enterprises of great pith and moment,\n" .
8296 "With this regard, their currents turn awry,\n" .
8297 "And lose the name of action.--Soft you now!\n" .
8298 "The fair Ophelia!--Nymph, in thy orisons\n" .
8299 "Be all my sins remember'd.\n\x00";
8300
8301 my $constant_len = length ($constant_phrase);
8302
8303 my $hash_buf = md5 ($pw . $salt);
8304
8305 my $W;
8306
8307 my $to_hash;
8308
8309 for (my $round = 0; $round < $iter; $round++)
8310 {
8311 my $shift_a = md5bit ($hash_buf, $round + 0);
8312 my $shift_b = md5bit ($hash_buf, $round + 64);
8313
8314 my @shift_4;
8315 my @shift_7;
8316
8317 for (my $k = 0; $k < 16; $k++)
8318 {
8319 my $s7shift = ord (substr ($hash_buf, $k, 1)) % 8;
8320
8321 my $l = ($k + 3) % 16;
8322
8323 my $num = ord (substr ($hash_buf, $l, 1));
8324
8325 $shift_4[$k] = $num % 5;
8326
8327 $shift_7[$k] = ($num >> $s7shift) & 1;
8328 }
8329
8330 my @indirect_4;
8331
8332 for (my $k = 0; $k < 16; $k++)
8333 {
8334 $indirect_4[$k] = (ord (substr ($hash_buf, $k, 1)) >> $shift_4[$k]) & 0xf;
8335 }
8336
8337 my @indirect_7;
8338
8339 for (my $k = 0; $k < 16; $k++)
8340 {
8341 $indirect_7[$k] = (ord (substr ($hash_buf, $indirect_4[$k], 1)) >> $shift_7[$k]) & 0x7f;
8342 }
8343
8344 my $indirect_a = 0;
8345 my $indirect_b = 0;
8346
8347 for (my $k = 0; $k < 8; $k++)
8348 {
8349 $indirect_a |= md5bit ($hash_buf, $indirect_7[$k + 0]) << $k;
8350
8351 $indirect_b |= md5bit ($hash_buf, $indirect_7[$k + 8]) << $k;
8352 }
8353
8354 $indirect_a = ($indirect_a >> $shift_a) & 0x7f;
8355 $indirect_b = ($indirect_b >> $shift_b) & 0x7f;
8356
8357 my $bit_a = md5bit ($hash_buf, $indirect_a);
8358 my $bit_b = md5bit ($hash_buf, $indirect_b);
8359
8360 $W = $hash_buf;
8361
8362 my $pos = 16;
8363
8364 my $total = $pos;
8365
8366 $to_hash = "";
8367
8368 if ($bit_a ^ $bit_b)
8369 {
8370 substr ($W, 16, 48) = substr ($constant_phrase, 0, 48);
8371
8372 $total += 48;
8373
8374 $to_hash .= substr ($W, 0, 64);
8375
8376 my $constant_off;
8377
8378 for ($constant_off = 48; $constant_off < $constant_len - 64; $constant_off += 64)
8379 {
8380 substr ($W, 0, 64) = substr ($constant_phrase, $constant_off, 64);
8381
8382 $total += 64;
8383
8384 $to_hash .= substr ($W, 0, 64);
8385 }
8386
8387 $pos = $constant_len - $constant_off;
8388
8389 $total += $pos;
8390
8391 substr ($W, 0, $pos) = substr ($constant_phrase, $constant_off, $pos);
8392 }
8393
8394 my $a_len = 0;
8395
8396 my @a_buf;
8397 $a_buf[0] = 0;
8398 $a_buf[1] = 0;
8399 $a_buf[2] = 0;
8400 $a_buf[3] = 0;
8401
8402 my $tmp = $round;
8403
8404 do
8405 {
8406 my $round_div = int ($tmp / 10);
8407 my $round_mod = int ($tmp % 10);
8408
8409 $tmp = $round_div;
8410
8411 $a_buf[int ($a_len / 4)] = (($round_mod + 0x30) | ($a_buf[int ($a_len / 4)] << 8));
8412
8413 $a_len++;
8414
8415 } while ($tmp);
8416
8417 my $tmp_str = "";
8418
8419 my $g;
8420
8421 for ($g = 0; $g < $a_len; $g++)
8422 {
8423 my $remainder = $a_buf[$g];
8424 my $factor = 7;
8425 my $started = 1;
8426
8427 my $sub;
8428
8429 while ($remainder > 0)
8430 {
8431 $sub = $remainder >> (8 * $factor);
8432
8433 if ($started != 1 || $sub > 0)
8434 {
8435 $started = 0;
8436
8437 $tmp_str = chr ($sub) . $tmp_str;
8438
8439 $remainder -= ($sub << (8 * $factor));
8440 }
8441
8442 $factor--;
8443 }
8444
8445 }
8446
8447 substr ($W, $pos, $a_len) = $tmp_str;
8448
8449 $pos += $a_len;
8450
8451 $total += $a_len;
8452
8453 $to_hash .= substr ($W, 0, $pos);
8454
8455 $to_hash = substr ($to_hash, 0, $total);
8456
8457 $hash_buf = md5 ($to_hash);
8458 }
8459
8460 my $passwd = "";
8461
8462 $passwd .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 6, 1))) << 8) | (int (ord (substr ($hash_buf, 12, 1)))), 4);
8463 $passwd .= to64 ((int (ord (substr ($hash_buf, 1, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 13, 1)))), 4);
8464 $passwd .= to64 ((int (ord (substr ($hash_buf, 2, 1))) << 16) | (int (ord (substr ($hash_buf, 8, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4);
8465 $passwd .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 9, 1))) << 8) | (int (ord (substr ($hash_buf, 15, 1)))), 4);
8466 $passwd .= to64 ((int (ord (substr ($hash_buf, 4, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4);
8467 $passwd .= to64 ((int (ord (substr ($hash_buf, 11, 1)))), 2);
8468
8469 return $passwd;
8470 }
8471
8472 sub usage_die
8473 {
8474 die ("usage: $0 single|passthrough| [mode] [len]\n" .
8475 " or\n" .
8476 " $0 verify [mode] [hashfile] [cracks] [outfile]\n");
8477 }
8478
8479 sub pad16
8480 {
8481 my $block_ref = shift;
8482
8483 my $offset = shift;
8484
8485 my $value = 16 - $offset;
8486
8487 for (my $i = $offset; $i < 16; $i++)
8488 {
8489 push @{$block_ref}, $value;
8490 }
8491 }
8492
8493 sub lotus_mix
8494 {
8495 my $in_ref = shift;
8496
8497 my $p = 0;
8498
8499 for (my $i = 0; $i < 18; $i++)
8500 {
8501 for (my $j = 0; $j < 48; $j++)
8502 {
8503 $p = ($p + 48 - $j) & 0xff;
8504
8505 my $c = $lotus_magic_table[$p];
8506
8507 $p = $in_ref->[$j] ^ $c;
8508
8509 $in_ref->[$j] = $p;
8510 }
8511 }
8512 }
8513
8514 sub lotus_transform_password
8515 {
8516 my $in_ref = shift;
8517 my $out_ref = shift;
8518
8519 my $t = $out_ref->[15];
8520
8521 for (my $i = 0; $i < 16; $i++)
8522 {
8523 $t ^= $in_ref->[$i];
8524
8525 my $c = $lotus_magic_table[$t];
8526
8527 $out_ref->[$i] ^= $c;
8528
8529 $t = $out_ref->[$i];
8530 }
8531 }
8532
8533 sub mdtransform_norecalc
8534 {
8535 my $state_ref = shift;
8536 my $block_ref = shift;
8537
8538 my @x;
8539
8540 push (@x, @{$state_ref});
8541 push (@x, @{$block_ref});
8542
8543 for (my $i = 0; $i < 16; $i++)
8544 {
8545 push (@x, $x[0 + $i] ^ $x[16 + $i]);
8546 }
8547
8548 lotus_mix (\@x);
8549
8550 for (my $i = 0; $i < 16; $i++)
8551 {
8552 $state_ref->[$i] = $x[$i];
8553 }
8554 }
8555
8556 sub mdtransform
8557 {
8558 my $state_ref = shift;
8559 my $checksum_ref = shift;
8560 my $block_ref = shift;
8561
8562 mdtransform_norecalc ($state_ref, $block_ref);
8563
8564 lotus_transform_password ($block_ref, $checksum_ref);
8565 }
8566
8567 sub domino_big_md
8568 {
8569 my $saved_key_ref = shift;
8570
8571 my $size = shift;
8572
8573 @{$saved_key_ref} = splice (@{$saved_key_ref}, 0, $size);
8574
8575 my @state = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
8576
8577 my @checksum;
8578
8579 my $curpos;
8580
8581 for ($curpos = 0; $curpos + 16 < $size; $curpos += 16)
8582 {
8583 my $curpos16 = $curpos + 16;
8584
8585 my @block = splice (@{$saved_key_ref}, 0, 16);
8586
8587 mdtransform (\@state, \@checksum, \@block);
8588 }
8589
8590 my $left = $size - $curpos;
8591
8592 my @block = splice (@{$saved_key_ref}, 0, 16);
8593
8594 pad16 (\@block, $left);
8595
8596 mdtransform (\@state, \@checksum, \@block);
8597
8598 mdtransform_norecalc (\@state, \@checksum);
8599
8600 return @state;
8601 }
8602
8603 sub pdf_compute_encryption_key
8604 {
8605 my $word_buf = shift;
8606 my $padding = shift;
8607 my $id = shift;
8608 my $u = shift;
8609 my $o = shift;
8610 my $P = shift;
8611 my $V = shift;
8612 my $R = shift;
8613 my $enc = shift;
8614
8615 ## start
8616
8617 my $data;
8618
8619 $data .= $word_buf;
8620
8621 $data .= substr ($padding, 0, 32 - length $word_buf);
8622
8623 $data .= pack ("H*", $o);
8624
8625 $data .= pack ("I", $P);
8626
8627 $data .= pack ("H*", $id);
8628
8629 if ($R >= 4)
8630 {
8631 if (!$enc)
8632 {
8633 $data .= pack ("I", -1);
8634 }
8635 }
8636
8637 my $res = md5 ($data);
8638
8639 if ($R >= 3)
8640 {
8641 for (my $i = 0; $i < 50; $i++)
8642 {
8643 $res = md5 ($res);
8644 }
8645 }
8646
8647 return $res;
8648 }
8649
8650 sub gen_random_wpa_eapol
8651 {
8652 my $keyver = shift;
8653 my $snonce = shift;
8654
8655 my $ret = "";
8656
8657 # version
8658
8659 my $version = 1; # 802.1X-2001
8660
8661 $ret .= pack ("C*", $version);
8662
8663 my $type = 3; # means that this EAPOL frame is used to transfer key information
8664
8665 $ret .= pack ("C*", $type);
8666
8667 my $length; # length of remaining data
8668
8669 if ($keyver == 1)
8670 {
8671 $length = 119;
8672 }
8673 else
8674 {
8675 $length = 117;
8676 }
8677
8678 $ret .= pack ("n*", $length);
8679
8680 my $descriptor_type;
8681
8682 if ($keyver == 1)
8683 {
8684 $descriptor_type = 254; # EAPOL WPA key
8685 }
8686 else
8687 {
8688 $descriptor_type = 1; # EAPOL RSN key
8689 }
8690
8691 $ret .= pack ("C*", $descriptor_type);
8692
8693 # key_info is a bit vector:
8694 # generated from these 13 bits: encrypted key data, request, error, secure, key mic, key ack, install, key index (2), key type, key descriptor (3)
8695
8696 my $key_info = 0;
8697
8698 $key_info |= 1 << 8; # set key MIC
8699 $key_info |= 1 << 3; # set if it is a pairwise key
8700
8701 if ($keyver == 1)
8702 {
8703 $key_info |= 1 << 0; # RC4 Cipher, HMAC-MD5 MIC
8704 }
8705 else
8706 {
8707 $key_info |= 1 << 1; # AES Cipher, HMAC-SHA1 MIC
8708 }
8709
8710 $ret .= pack ("n*", $key_info);
8711
8712 my $key_length;
8713
8714 if ($keyver == 1)
8715 {
8716 $key_length = 32;
8717 }
8718 else
8719 {
8720 $key_length = 0;
8721 }
8722
8723 $ret .= pack ("n*", $key_length);
8724
8725 my $replay_counter = 1;
8726
8727 $ret .= pack ("Q>*", $replay_counter);
8728
8729 $ret .= $snonce;
8730
8731 my $key_iv = "\x00" x 16;
8732
8733 $ret .= $key_iv;
8734
8735 my $key_rsc = "\x00" x 8;
8736
8737 $ret .= $key_rsc;
8738
8739 my $key_id = "\x00" x 8;
8740
8741 $ret .= $key_id;
8742
8743 my $key_mic = "\x00" x 16;
8744
8745 $ret .= $key_mic;
8746
8747 my $key_data_len;
8748
8749 if ($keyver == 1)
8750 {
8751 $key_data_len = 24; # length of the key_data (== WPA info)
8752 }
8753 else
8754 {
8755 $key_data_len = 22; # length of the key_data (== RSN info)
8756 }
8757
8758 $ret .= pack ("n*", $key_data_len);
8759
8760 my $key_data = "";
8761
8762 if ($keyver == 1)
8763 {
8764 # wpa info
8765
8766 my $wpa_info = "";
8767
8768 my $vendor_specific_data = "";
8769
8770 my $tag_number = 221; # means it is a vendor specific tag
8771
8772 $vendor_specific_data .= pack ("C*", $tag_number);
8773
8774 my $tag_len = 22; # length of the remaining "tag data"
8775
8776 $vendor_specific_data .= pack ("C*", $tag_len);
8777
8778 my $vendor_specific_oui = pack ("H*", "0050f2"); # microsoft
8779
8780 $vendor_specific_data .= $vendor_specific_oui;
8781
8782 my $vendor_specific_oui_type = 1; # WPA Information Element
8783
8784 $vendor_specific_data .= pack ("C*", $vendor_specific_oui_type);
8785
8786 my $vendor_specific_wpa_version = 1;
8787
8788 $vendor_specific_data .= pack ("v*", $vendor_specific_wpa_version);
8789
8790 # multicast
8791
8792 my $vendor_specific_multicast_oui = pack ("H*", "0050f2");
8793
8794 $vendor_specific_data .= $vendor_specific_multicast_oui;
8795
8796 my $vendor_specific_multicast_type = 2; # TKIP
8797
8798 $vendor_specific_data .= pack ("C*", $vendor_specific_multicast_type);
8799
8800 # unicast
8801
8802 my $vendor_specific_unicast_count = 1;
8803
8804 $vendor_specific_data .= pack ("v*", $vendor_specific_unicast_count);
8805
8806 my $vendor_specific_unicast_oui = pack ("H*", "0050f2");
8807
8808 $vendor_specific_data .= $vendor_specific_multicast_oui;
8809
8810 my $vendor_specific_unicast_type = 2; # TKIP
8811
8812 $vendor_specific_data .= pack ("C*", $vendor_specific_unicast_type);
8813
8814 # Auth Key Management (AKM)
8815
8816 my $auth_key_management_count = 1;
8817
8818 $vendor_specific_data .= pack ("v*", $auth_key_management_count);
8819
8820 my $auth_key_management_oui = pack ("H*", "0050f2");
8821
8822 $vendor_specific_data .= $auth_key_management_oui;
8823
8824 my $auth_key_management_type = 2; # Pre-Shared Key (PSK)
8825
8826 $vendor_specific_data .= pack ("C*", $auth_key_management_type);
8827
8828 $wpa_info = $vendor_specific_data;
8829
8830 $key_data = $wpa_info;
8831 }
8832 else
8833 {
8834 # rsn info
8835
8836 my $rsn_info = "";
8837
8838 my $tag_number = 48; # RSN info
8839
8840 $rsn_info .= pack ("C*", $tag_number);
8841
8842 my $tag_len = 20; # length of the remaining "tag_data"
8843
8844 $rsn_info .= pack ("C*", $tag_len);
8845
8846 my $rsn_version = 1;
8847
8848 $rsn_info .= pack ("v*", $rsn_version);
8849
8850 # group cipher suite
8851
8852 my $group_cipher_suite_oui = pack ("H*", "000fac"); # Ieee8021
8853
8854 $rsn_info .= $group_cipher_suite_oui;
8855
8856 my $group_cipher_suite_type = 4; # AES (CCM)
8857
8858 $rsn_info .= pack ("C*", $group_cipher_suite_type);
8859
8860 # pairwise cipher suite
8861
8862 my $pairwise_cipher_suite_count = 1;
8863
8864 $rsn_info .= pack ("v*", $pairwise_cipher_suite_count);
8865
8866 my $pairwise_cipher_suite_oui = pack ("H*", "000fac"); # Ieee8021
8867
8868 $rsn_info .= $pairwise_cipher_suite_oui;
8869
8870 my $pairwise_cipher_suite_type = 4; # AES (CCM)
8871
8872 $rsn_info .= pack ("C*", $pairwise_cipher_suite_type);
8873
8874 # Auth Key Management (AKM)
8875
8876 my $auth_key_management_count = 1;
8877
8878 $rsn_info .= pack ("v*", $auth_key_management_count);
8879
8880 my $auth_key_management_oui = pack ("H*", "000fac"); # Ieee8021
8881
8882 $rsn_info .= $auth_key_management_oui;
8883
8884 my $auth_key_management_type = 2; # Pre-Shared Key (PSK)
8885
8886 $rsn_info .= pack ("C*", $auth_key_management_type);
8887
8888 # RSN Capabilities
8889
8890 # bit vector of these 9 bits: peerkey enabled, management frame protection (MFP) capable, MFP required,
8891 # RSN GTKSA Capabilities (2), RSN PTKSA Capabilities (2), no pairwise Capabilities, Pre-Auth Capabilities
8892
8893 my $rsn_capabilities = pack ("H*", "0000");
8894
8895 $rsn_info .= $rsn_capabilities;
8896
8897 $key_data = $rsn_info;
8898 }
8899
8900 $ret .= $key_data;
8901
8902 return $ret;
8903 }
8904
8905 sub wpa_prf_512
8906 {
8907 my $pmk = shift;
8908 my $stmac = shift;
8909 my $bssid = shift;
8910 my $snonce = shift;
8911 my $anonce = shift;
8912
8913 my $data = "Pairwise key expansion";
8914
8915 $data .= "\x00";
8916
8917 #
8918 # Min(AA, SPA) || Max(AA, SPA)
8919 #
8920
8921 # compare if greater: Min()/Max() on the MACs (6 bytes)
8922
8923 if (memcmp ($stmac, $bssid, 6) < 0)
8924 {
8925 $data .= $stmac;
8926 $data .= $bssid;
8927 }
8928 else
8929 {
8930 $data .= $bssid;
8931 $data .= $stmac;
8932 }
8933
8934 #
8935 # Min(ANonce,SNonce) || Max(ANonce,SNonce)
8936 #
8937
8938 # compare if greater: Min()/Max() on the nonces (32 bytes)
8939
8940 if (memcmp ($snonce, $anonce, 32) < 0)
8941 {
8942 $data .= $snonce;
8943 $data .= $anonce;
8944 }
8945 else
8946 {
8947 $data .= $anonce;
8948 $data .= $snonce;
8949 }
8950
8951 $data .= "\x00";
8952
8953 my $prf_buf = hmac ($data, $pmk, \&sha1);
8954
8955 $prf_buf = substr ($prf_buf, 0, 16);
8956
8957 return $prf_buf;
8958 }
8959
8960 sub memcmp
8961 {
8962 my $str1 = shift;
8963 my $str2 = shift;
8964 my $len = shift;
8965
8966 my $len_str1 = length ($str1);
8967 my $len_str2 = length ($str2);
8968
8969 if (($len > $len_str1) || ($len > $len_str2))
8970 {
8971 print "ERROR: memcmp () lengths wrong";
8972
8973 exit (1);
8974 }
8975
8976 for (my $i = 0; $i < $len; $i++)
8977 {
8978 my $c_1 = ord (substr ($str1, $i, 1));
8979 my $c_2 = ord (substr ($str2, $i, 1));
8980
8981 return -1 if ($c_1 < $c_2);
8982 return 1 if ($c_1 > $c_2);
8983 }
8984
8985 return 0;
8986 }