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