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