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