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