Added new hash-mode 13800 = Windows 8+ phone PIN/Password
[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 = "./hashcat";
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, 133, 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, 13600, 13800);
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 11600 13500 13800);
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 13800);
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 || $mode == 13800)
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 hashcat'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 elsif ($mode == 13600)
2373 {
2374 ($hash_in, $word) = split ":", $line;
2375
2376 next unless defined $hash_in;
2377 next unless defined $word;
2378
2379 my @data = split ('\*', $hash_in);
2380
2381 next unless scalar @data == 10;
2382
2383 my $tag_start = shift @data;
2384 my $type = shift @data;
2385 my $mode = shift @data;
2386 my $magic = shift @data;
2387 my $salt = shift @data;
2388 my $verify_bytes = shift @data;
2389 my $length = shift @data;
2390 my $data = shift @data;
2391 my $auth = shift @data;
2392 my $tag_end = shift @data;
2393
2394 next unless ($tag_start eq '$zip2$');
2395 next unless ($tag_end eq '$/zip2$');
2396
2397 $param = $type;
2398 $param2 = $mode;
2399 $param3 = $magic;
2400 $param4 = $salt;
2401 $param5 = $length;
2402 $param6 = $data;
2403
2404 next unless (exists ($db->{$hash_in}) and (! defined ($db->{$hash_in})));
2405 }
2406 else
2407 {
2408 print "ERROR: hash mode is not supported\n";
2409
2410 exit (1);
2411 }
2412
2413 if ($word =~ m/^\$HEX\[[0-9a-fA-F]*\]$/)
2414 {
2415 $word = pack ("H*", substr ($word, 5, -1));
2416 }
2417
2418 # finally generate the hash
2419
2420 # special case:
2421 if ($mode == 6800)
2422 {
2423 # check both variations
2424 $hash_out = gen_hash ($mode, $word, $salt, $iter, 1);
2425
2426 $len = length $hash_out; # == length $alternative
2427
2428 if (substr ($line, 0, $len) ne $hash_out)
2429 {
2430 my $alternative = gen_hash ($mode, $word, $salt, $iter, 2);
2431
2432 return unless (substr ($line, 0, $len) eq $alternative);
2433 }
2434 }
2435 elsif ($mode == 8700)
2436 {
2437 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2438
2439 $len = length $hash_out;
2440
2441 return unless (substr ($line, 0, $len) eq $hash_out);
2442 }
2443 elsif ($mode == 8900)
2444 {
2445 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3);
2446
2447 $len = length $hash_out;
2448
2449 return unless (substr ($line, 0, $len) eq $hash_out);
2450 }
2451 elsif ($mode == 9100)
2452 {
2453 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2454
2455 $len = length $hash_out;
2456
2457 return unless (substr ($line, 0, $len) eq $hash_out);
2458 }
2459 elsif ($mode == 190)
2460 {
2461 $hash_out = gen_hash ($mode, $word, $salt, $iter, 0);
2462
2463 $len = length $hash_out; # == length $alternative
2464
2465 if (substr ($line, 0, $len) ne $hash_out)
2466 {
2467 my $alternative = gen_hash ($mode, $word, $salt, $iter, 1);
2468
2469 return unless (substr ($line, 0, $len) eq $alternative);
2470 }
2471 }
2472 elsif ($mode == 3300)
2473 {
2474 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2475
2476 $len = length $hash_out;
2477
2478 return unless (substr ($line, 0, $len) eq $hash_out);
2479 }
2480 elsif ($mode == 5100)
2481 {
2482 # check 3 variants (start, middle, end)
2483
2484 my $idx = 0;
2485
2486 $hash_out = gen_hash ($mode, $word, $salt, $iter, $idx++);
2487
2488 $len = length $hash_out; # == length $alternative
2489
2490 if (substr ($line, 0, $len) ne $hash_out)
2491 {
2492 my $alternative = gen_hash ($mode, $word, $salt, $iter, $idx++);
2493
2494 if (substr ($line, 0, $len) ne $alternative)
2495 {
2496 my $alternative = gen_hash ($mode, $word, $salt, $iter, $idx++);
2497
2498 return unless (substr ($line, 0, $len) eq $alternative);
2499 }
2500 }
2501 }
2502 elsif ($mode == 9400)
2503 {
2504 $hash_out = gen_hash ($mode, $word, $salt, 50000, $param, $param2);
2505
2506 $len = length $hash_out;
2507
2508 return unless (substr ($line, 0, $len) eq $hash_out);
2509 }
2510 elsif ($mode == 9500)
2511 {
2512 $hash_out = gen_hash ($mode, $word, $salt, 100000, $param);
2513
2514 $len = length $hash_out;
2515
2516 return unless (substr ($line, 0, $len) eq $hash_out);
2517 }
2518 elsif ($mode == 9600)
2519 {
2520 $hash_out = gen_hash ($mode, $word, $salt, 100000, $param);
2521
2522 $len = length $hash_out;
2523
2524 return unless (substr ($line, 0, $len) eq $hash_out);
2525 }
2526 elsif ($mode == 9700)
2527 {
2528 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2);
2529
2530 $len = length $hash_out;
2531
2532 return unless (substr ($line, 0, $len) eq $hash_out);
2533 }
2534 elsif ($mode == 9800)
2535 {
2536 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2);
2537
2538 $len = length $hash_out;
2539
2540 return unless (substr ($line, 0, $len) eq $hash_out);
2541 }
2542 elsif ($mode == 10400)
2543 {
2544 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3);
2545
2546 $len = length $hash_out;
2547
2548 return unless (substr ($line, 0, $len) eq $hash_out);
2549 }
2550 elsif ($mode == 10500)
2551 {
2552 $hash_out = gen_hash ($mode, $word, $salt, 0, $param, $param2, $param3, $param4, $param5, $param6);
2553
2554 $len = length $hash_out;
2555
2556 return unless (substr ($line, 0, $len) eq $hash_out);
2557 }
2558 elsif ($mode == 10600)
2559 {
2560 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2561
2562 $len = length $hash_out;
2563
2564 return unless (substr ($line, 0, $len) eq $hash_out);
2565 }
2566 elsif ($mode == 10700)
2567 {
2568 $hash_out = gen_hash ($mode, $word, $salt, 0, $param);
2569
2570 $len = length $hash_out;
2571
2572 return unless (substr ($line, 0, $len) eq $hash_out);
2573 }
2574 elsif ($mode == 10900)
2575 {
2576 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2577
2578 $len = length $hash_out;
2579
2580 return unless (substr ($line, 0, $len) eq $hash_out);
2581 }
2582 elsif ($mode == 11100)
2583 {
2584 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2585
2586 $len = length $hash_out;
2587
2588 return unless (substr ($line, 0, $len) eq $hash_out);
2589 }
2590 elsif ($mode == 11400)
2591 {
2592 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param, $param2, $param3, $param4, $param5, $param6, $param7, $param8, $param9, $param10, $param11);
2593
2594 $len = length $hash_out;
2595
2596 return unless (substr ($line, 0, $len) eq $hash_out);
2597 }
2598 elsif ($mode == 11600)
2599 {
2600 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param, $param2, $param3, $param4, $param5, $param6);
2601
2602 $len = length $hash_out;
2603
2604 return unless (substr ($line, 0, $len) eq $hash_out);
2605 }
2606 elsif ($mode == 11900)
2607 {
2608 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2609
2610 $len = length $hash_out;
2611
2612 return unless (substr ($line, 0, $len) eq $hash_out);
2613 }
2614 elsif ($mode == 12000)
2615 {
2616 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2617
2618 $len = length $hash_out;
2619
2620 return unless (substr ($line, 0, $len) eq $hash_out);
2621 }
2622 elsif ($mode == 12100)
2623 {
2624 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2625
2626 $len = length $hash_out;
2627
2628 return unless (substr ($line, 0, $len) eq $hash_out);
2629 }
2630 elsif ($mode == 12200)
2631 {
2632 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2633
2634 $len = length $hash_out;
2635
2636 return unless (substr ($line, 0, $len) eq $hash_out);
2637 }
2638 elsif ($mode == 12700)
2639 {
2640 # this is very special, we can't call gen_hash () because the param part is not always the same
2641 # we only know that it should contain the letters "guid" at the beginning of the decryted string
2642
2643 my $pbkdf2 = Crypt::PBKDF2->new (
2644 hash_class => 'HMACSHA1',
2645 iterations => 10,
2646 output_len => 32
2647 );
2648
2649 my $salt_bin = pack ("H*", $salt);
2650
2651 my $key = $pbkdf2->PBKDF2 ($salt_bin, $word);
2652
2653 my $cipher = Crypt::CBC->new ({
2654 key => $key,
2655 cipher => "Crypt::Rijndael",
2656 iv => $salt_bin,
2657 literal_key => 1,
2658 header => "none",
2659 keysize => 32
2660 });
2661
2662 my $param_bin = pack ("H*", $param);
2663
2664 my $decrypted = $cipher->decrypt ($param_bin);
2665
2666 my $decrypted_part = substr ($decrypted, 1, 16);
2667
2668 return unless ($decrypted_part =~ /"guid"/);
2669
2670 $hash_out = $hash_in;
2671 }
2672 elsif ($mode == 12900)
2673 {
2674 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2675
2676 $len = length $hash_out;
2677
2678 return unless (substr ($line, 0, $len) eq $hash_out);
2679 }
2680 elsif ($mode == 13000)
2681 {
2682 $hash_out = gen_hash ($mode, $word, $salt, $iter, $param);
2683
2684 $len = length $hash_out;
2685
2686 return unless (substr ($line, 0, $len) eq $hash_out);
2687 }
2688 elsif ($mode == 13100)
2689 {
2690 $hash_out = gen_hash ($mode, $word, $salt);
2691
2692 $len = length $hash_out;
2693
2694 return unless (substr ($line, 0, $len) eq $hash_out);
2695 }
2696 elsif ($mode == 13200)
2697 {
2698 $hash_out = gen_hash ($mode, $word, $salt);
2699
2700 $len = length $hash_out;
2701
2702 return unless (substr ($line, 0, $len) eq $hash_out);
2703 }
2704 elsif ($mode == 13400)
2705 {
2706 $hash_out = gen_hash ($mode, $word, $salt);
2707
2708 $len = length $hash_out;
2709
2710 return unless (substr ($line, 0, $len) eq $hash_out);
2711 }
2712 elsif ($mode == 13600)
2713 {
2714 $hash_out = gen_hash ($mode, $word, undef, undef, $param, $param2, $param3, $param4, $param5, $param6);
2715
2716 $len = length $hash_out;
2717
2718 return unless (substr ($line, 0, $len) eq $hash_out);
2719 }
2720 else
2721 {
2722 $hash_out = gen_hash ($mode, $word, $salt, $iter);
2723
2724 $len = length $hash_out;
2725
2726 # special cases:
2727 if ($mode == 400)
2728 {
2729 # allow $P$ and $H$ for -m 400
2730 next unless (substr ($line, 3, $len - 3) eq substr ($hash_out, 3));
2731 }
2732 elsif ($mode == 5600)
2733 {
2734 # hashcat outputs the user name always upper-case, we need
2735 next unless (substr ($line, 0, $len) eq $hash_out);
2736
2737 my $found = 0;
2738
2739 my $hash_out_lower = lc ($hash_out);
2740
2741 for my $key (keys %{$db})
2742 {
2743 if (lc ($key) eq $hash_out_lower)
2744 {
2745 $found = 1;
2746
2747 last;
2748 }
2749 }
2750
2751 next unless $found;
2752 }
2753 else
2754 {
2755 next unless (substr ($line, 0, $len) eq $hash_out);
2756 }
2757 }
2758
2759 # do not forget "exists ($db->$hash_out)" should be done above!
2760 $db->{$hash_out} = $word;
2761 print OUT $line . "\n";
2762 }
2763
2764 close (IN);
2765 close (OUT);
2766 }
2767
2768 sub passthrough
2769 {
2770 my $mode = shift || 0;
2771
2772 while (my $word_buf = <>)
2773 {
2774 chomp ($word_buf);
2775
2776 next if length ($word_buf) > 31;
2777
2778 ##
2779 ## gen salt
2780 ##
2781
2782 my @salt_arr;
2783
2784 for (my $i = 0; $i < 256; $i++)
2785 {
2786 my $c = get_random_chr (0x30, 0x39);
2787
2788 push (@salt_arr, $c);
2789 }
2790
2791 my $salt_buf = join ("", @salt_arr);
2792
2793 ##
2794 ## gen hash
2795 ##
2796
2797 my $tmp_hash;
2798
2799 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)
2800 {
2801 $tmp_hash = gen_hash ($mode, $word_buf, "");
2802 }
2803 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)
2804 {
2805 my $salt_len = get_random_num (1, 15);
2806
2807 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2808 }
2809 elsif ($mode == 11 || $mode == 12 || $mode == 7600 || $mode == 12300)
2810 {
2811 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
2812 }
2813 elsif ($mode == 21)
2814 {
2815 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 2));
2816 }
2817 elsif ($mode == 22)
2818 {
2819 my $salt_len = get_random_num (1, 11);
2820
2821 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2822 }
2823 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)
2824 {
2825 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 8));
2826 }
2827 elsif ($mode == 112)
2828 {
2829 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 20));
2830 }
2831 elsif ($mode == 121)
2832 {
2833 my $salt_len = get_random_num (1, 9);
2834
2835 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2836 }
2837 elsif ($mode == 125)
2838 {
2839 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 8));
2840 }
2841 elsif ($mode == 141 || $mode == 1441)
2842 {
2843 my $salt_len = get_random_num (1, 15);
2844
2845 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2846 }
2847 elsif ($mode == 1100)
2848 {
2849 my $salt_len = get_random_num (1, 19);
2850
2851 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2852 }
2853 elsif ($mode == 1500)
2854 {
2855 next if length ($word_buf) > 8;
2856
2857 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 2));
2858 }
2859 elsif ($mode == 2100)
2860 {
2861 next if length ($word_buf) > 13;
2862
2863 my $salt_len = get_random_num (1, 19);
2864
2865 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2866 }
2867 elsif ($mode == 2410)
2868 {
2869 next if length ($word_buf) > 15;
2870
2871 my $salt_len = get_random_num (1, 15);
2872
2873 my $word_len = length ($word_buf);
2874
2875 $salt_len = min ($salt_len, 15 - $word_len);
2876
2877 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2878 }
2879 elsif ($mode == 2500)
2880 {
2881 next if length ($word_buf) < 8;
2882
2883 my $salt_len = get_random_num (0, 32);
2884
2885 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2886 }
2887 elsif ($mode == 2611)
2888 {
2889 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 3));
2890 }
2891 elsif ($mode == 2612)
2892 {
2893 my $salt_len = get_random_num (1, 22);
2894
2895 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2896 }
2897 elsif ($mode == 2711)
2898 {
2899 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 30));
2900 }
2901 elsif ($mode == 2811)
2902 {
2903 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 5));
2904 }
2905 elsif ($mode == 3000)
2906 {
2907 next if length ($word_buf) > 7;
2908
2909 $tmp_hash = gen_hash ($mode, $word_buf, "");
2910 }
2911 elsif ($mode == 3100)
2912 {
2913 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 10));
2914 }
2915 elsif ($mode == 3200 || $mode == 5800 || $mode == 6400 || $mode == 6500 || $mode == 6700 || $mode == 7400 || $mode == 3300 || $mode == 8000 || $mode == 9100 || $mode == 12200)
2916 {
2917 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 16));
2918 }
2919 elsif ($mode == 3800 || $mode == 4900)
2920 {
2921 my $salt_len = get_random_num (1, 11);
2922
2923 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2924 }
2925 elsif ($mode == 4800)
2926 {
2927 $salt_buf = get_random_md5chap_salt (substr ($salt_buf, 0, 16));
2928
2929 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2930 }
2931 elsif ($mode == 5300 || $mode == 5400)
2932 {
2933 $salt_buf = get_random_ike_salt ();
2934
2935 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2936 }
2937 elsif ($mode == 5500)
2938 {
2939 my $user_len = get_random_num (0, 15);
2940 my $domain_len = get_random_num (0, 15);
2941
2942 $salt_buf = get_random_netntlmv1_salt ($user_len, $domain_len);
2943
2944 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2945 }
2946 elsif ($mode == 5600)
2947 {
2948 my $user_len = get_random_num (0, 15);
2949 my $domain_len = get_random_num (0, 15);
2950
2951 $salt_buf = get_random_netntlmv2_salt ($user_len, $domain_len);
2952
2953 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2954 }
2955 elsif ($mode == 6600)
2956 {
2957 $salt_buf = get_random_agilekeychain_salt ();
2958
2959 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2960 }
2961 elsif ($mode == 6800)
2962 {
2963 my $email_len = get_random_num (1, 15);
2964
2965 my $email = "";
2966
2967 for (my $i = 0; $i < $email_len; $i++)
2968 {
2969 $email .= get_random_chr (0x61, 0x7a);
2970 }
2971
2972 $email .= '@trash-mail.com';
2973
2974 $tmp_hash = gen_hash ($mode, $word_buf, $email);
2975 }
2976 elsif ($mode == 7100)
2977 {
2978 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 64));
2979 }
2980 elsif ($mode == 7200)
2981 {
2982 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 128));
2983 }
2984 elsif ($mode == 7300)
2985 {
2986 my $salt_len = get_random_num (32, 256);
2987
2988 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
2989 }
2990 elsif ($mode == 7500)
2991 {
2992 $salt_buf = get_random_kerberos5_salt (substr ($salt_buf, 0, 16));
2993
2994 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
2995 }
2996 elsif ($mode == 7700)
2997 {
2998 next if length ($word_buf) > 8;
2999
3000 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 12));
3001 }
3002 elsif ($mode == 7800)
3003 {
3004 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 12));
3005 }
3006 elsif ($mode == 8200)
3007 {
3008 $salt_buf = get_random_cloudkeychain_salt ();
3009
3010 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3011 }
3012 elsif ($mode == 8300)
3013 {
3014 $salt_buf = get_random_dnssec_salt ();
3015
3016 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3017 }
3018 elsif ($mode == 8400 || $mode == 11200)
3019 {
3020 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 40));
3021 }
3022 elsif ($mode == 8500)
3023 {
3024 next if length ($word_buf) > 8;
3025
3026 my $salt_len = get_random_num (1, 9);
3027
3028 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3029 }
3030 elsif ($mode == 8600)
3031 {
3032 next if length ($word_buf) > 16;
3033
3034 $tmp_hash = gen_hash ($mode, $word_buf, "");
3035 }
3036 elsif ($mode == 8700)
3037 {
3038 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 5));
3039 }
3040 elsif ($mode == 9200 || $mode == 9300)
3041 {
3042 my $salt_len = 14;
3043
3044 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3045 }
3046 elsif ($mode == 9400 || $mode == 9500 || $mode == 9600 || $mode == 9700 || $mode == 9800)
3047 {
3048 next if length ($word_buf) > 19;
3049
3050 my $salt_len = 32;
3051
3052 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3053 }
3054 elsif ($mode == 10100)
3055 {
3056 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
3057 }
3058 elsif ($mode == 10300)
3059 {
3060 my $salt_len = get_random_num (4, 15);
3061
3062 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3063 }
3064 elsif ($mode == 10400)
3065 {
3066 next if length ($word_buf) > 31;
3067
3068 my $salt_len = 32;
3069
3070 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3071 }
3072 elsif ($mode == 10500)
3073 {
3074 next if length ($word_buf) > 15;
3075
3076 my $salt_len = 32;
3077
3078 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3079 }
3080 elsif ($mode == 10600)
3081 {
3082 next if length ($word_buf) > 31;
3083
3084 my $salt_len = 32;
3085
3086 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3087 }
3088 elsif ($mode == 10700)
3089 {
3090 next if length ($word_buf) > 15;
3091
3092 my $salt_len = 32;
3093
3094 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3095 }
3096 elsif ($mode == 11000)
3097 {
3098 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 56));
3099 }
3100 elsif ($mode == 11300)
3101 {
3102 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 16));
3103 }
3104 elsif ($mode == 11400)
3105 {
3106 next if length ($word_buf) > 24;
3107
3108 my $salt_len = get_random_num (1, 15);
3109
3110 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3111 }
3112 elsif ($mode == 11600)
3113 {
3114 my $salt_len = get_random_num (0, 16);
3115
3116 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, $salt_len));
3117 }
3118 elsif ($mode == 12400)
3119 {
3120 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 4));
3121 }
3122 elsif ($mode == 12600)
3123 {
3124 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 64));
3125 }
3126 elsif ($mode == 12700)
3127 {
3128 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
3129 }
3130 elsif ($mode == 12800)
3131 {
3132 next if length ($word_buf) > 24;
3133
3134 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 20));
3135 }
3136 elsif ($mode == 12900)
3137 {
3138 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
3139 }
3140 elsif ($mode == 13000)
3141 {
3142 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
3143 }
3144 elsif ($mode == 13100)
3145 {
3146 $salt_buf = get_random_kerberos5_tgs_salt ();
3147
3148 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3149 }
3150 elsif ($mode == 13200)
3151 {
3152 $salt_buf = get_random_axcrypt_salt ();
3153
3154 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3155 }
3156 elsif ($mode == 13400)
3157 {
3158 $salt_buf = get_random_keepass_salt ();
3159
3160 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3161 }
3162 elsif ($mode == 13500)
3163 {
3164 $salt_buf = get_pstoken_salt ();
3165
3166 $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
3167 }
3168 elsif ($mode == 13600)
3169 {
3170 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 32));
3171 }
3172 elsif ($mode == 13800)
3173 {
3174 $tmp_hash = gen_hash ($mode, $word_buf, substr ($salt_buf, 0, 256));
3175 }
3176 else
3177 {
3178 print "ERROR: Unsupported hash type\n";
3179
3180 exit (1);
3181 }
3182
3183 print $tmp_hash, "\n";
3184 }
3185 }
3186
3187 sub single
3188 {
3189 my $mode = shift;
3190
3191 if (defined $mode)
3192 {
3193 @modes = ($mode);
3194 }
3195
3196 for (my $j = 0; $j < scalar @modes; $j++)
3197 {
3198 my $mode = $modes[$j];
3199
3200 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)
3201 {
3202 for (my $i = 1; $i < 32; $i++)
3203 {
3204 if ($len != 0)
3205 {
3206 rnd ($mode, $len, 0);
3207 }
3208 else
3209 {
3210 rnd ($mode, $i, 0);
3211 }
3212 }
3213 }
3214 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)
3215 {
3216 my $salt_len = get_random_num (1, 15);
3217
3218 for (my $i = 1; $i < 32; $i++)
3219 {
3220 if ($len != 0)
3221 {
3222 rnd ($mode, $len, $salt_len);
3223 }
3224 else
3225 {
3226 rnd ($mode, $i, $salt_len);
3227 }
3228 }
3229 }
3230 elsif ($mode == 11 || $mode == 12 || $mode == 7600 || $mode == 12300)
3231 {
3232 for (my $i = 1; $i < 32; $i++)
3233 {
3234 if ($len != 0)
3235 {
3236 rnd ($mode, $len, 32);
3237 }
3238 else
3239 {
3240 rnd ($mode, $i, 32);
3241 }
3242 }
3243 }
3244 elsif ($mode == 21 || $mode == 22)
3245 {
3246 for (my $i = 1; $i < 32; $i++)
3247 {
3248 if ($len != 0)
3249 {
3250 rnd ($mode, $len, 2);
3251 }
3252 else
3253 {
3254 rnd ($mode, $i, 2);
3255 }
3256 }
3257 }
3258 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)
3259 {
3260 for (my $i = 1; $i < 32; $i++)
3261 {
3262 if ($len != 0)
3263 {
3264 rnd ($mode, $len, 8);
3265 }
3266 else
3267 {
3268 rnd ($mode, $i, 8);
3269 }
3270 }
3271 }
3272 elsif ($mode == 112)
3273 {
3274 for (my $i = 1; $i < 32; $i++)
3275 {
3276 if ($len != 0)
3277 {
3278 rnd ($mode, $len, 20);
3279 }
3280 else
3281 {
3282 rnd ($mode, $i, 20);
3283 }
3284 }
3285 }
3286 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)
3287 {
3288 for (my $i = 1; $i < 32; $i++)
3289 {
3290 if ($len != 0)
3291 {
3292 rnd ($mode, $len, 16);
3293 }
3294 else
3295 {
3296 rnd ($mode, $i, 16);
3297 }
3298 }
3299 }
3300 if ($mode == 1100)
3301 {
3302 my $salt_len = get_random_num (1, 19);
3303
3304 for (my $i = 1; $i < 32; $i++)
3305 {
3306 if ($len != 0)
3307 {
3308 rnd ($mode, $len, $salt_len);
3309 }
3310 else
3311 {
3312 rnd ($mode, $i, $salt_len);
3313 }
3314 }
3315 }
3316 elsif ($mode == 1500)
3317 {
3318 for (my $i = 1; $i < 9; $i++)
3319 {
3320 if ($len != 0)
3321 {
3322 rnd ($mode, $len, 2);
3323 }
3324 else
3325 {
3326 rnd ($mode, $i, 2);
3327 }
3328 }
3329 }
3330 elsif ($mode == 2100)
3331 {
3332 my $salt_len = get_random_num (1, 19);
3333
3334 for (my $i = 1; $i < 13; $i++)
3335 {
3336 if ($len != 0)
3337 {
3338 rnd ($mode, $len, $salt_len);
3339 }
3340 else
3341 {
3342 rnd ($mode, $i, $salt_len);
3343 }
3344 }
3345 }
3346 elsif ($mode == 2500)
3347 {
3348 my $salt_len = get_random_num (0, 32);
3349
3350 for (my $i = 8; $i < 16; $i++)
3351 {
3352 my $generate_from_len = 0;
3353
3354 if ($len != 0)
3355 {
3356 if ($len < 8)
3357 {
3358 $len += 7;
3359 }
3360
3361 rnd ($mode, $len, $salt_len);
3362 }
3363 else
3364 {
3365 rnd ($mode, $i, $salt_len);
3366 }
3367 }
3368 }
3369 elsif ($mode == 2611)
3370 {
3371 for (my $i = 1; $i < 32; $i++)
3372 {
3373 if ($len != 0)
3374 {
3375 rnd ($mode, $len, 3);
3376 }
3377 else
3378 {
3379 rnd ($mode, $i, 3);
3380 }
3381 }
3382 }
3383 elsif ($mode == 2612)
3384 {
3385 my $salt_len = get_random_num (1, 22);
3386
3387 for (my $i = 1; $i < 32; $i++)
3388 {
3389 if ($len != 0)
3390 {
3391 rnd ($mode, $len, $salt_len);
3392 }
3393 else
3394 {
3395 rnd ($mode, $i, $salt_len);
3396 }
3397 }
3398 }
3399 elsif ($mode == 2711)
3400 {
3401 for (my $i = 1; $i < 32; $i++)
3402 {
3403 if ($len != 0)
3404 {
3405 rnd ($mode, $len, 30);
3406 }
3407 else
3408 {
3409 rnd ($mode, $i, 30);
3410 }
3411 }
3412 }
3413 elsif ($mode == 2811)
3414 {
3415 for (my $i = 1; $i < 32; $i++)
3416 {
3417 if ($len != 0)
3418 {
3419 rnd ($mode, $len, 5);
3420 }
3421 else
3422 {
3423 rnd ($mode, $i, 5);
3424 }
3425 }
3426 }
3427 elsif ($mode == 3000)
3428 {
3429 for (my $i = 1; $i < 8; $i++)
3430 {
3431 if ($len != 0)
3432 {
3433 rnd ($mode, $len, 0);
3434 }
3435 else
3436 {
3437 rnd ($mode, $i, 0);
3438 }
3439 }
3440 }
3441 elsif ($mode == 3100)
3442 {
3443 for (my $i = 1; $i < 32; $i++)
3444 {
3445 if ($len != 0)
3446 {
3447 rnd ($mode, $len, 10);
3448 }
3449 else
3450 {
3451 rnd ($mode, $i, 10);
3452 }
3453 }
3454 }
3455 elsif ($mode == 3800 || $mode == 4900)
3456 {
3457 my $salt_len = get_random_num (1, 11);
3458
3459 for (my $i = 1; $i < 32; $i++)
3460 {
3461 if ($len != 0)
3462 {
3463 rnd ($mode, $len, $salt_len);
3464 }
3465 else
3466 {
3467 rnd ($mode, $i, $salt_len);
3468 }
3469 }
3470 }
3471 elsif ($mode == 5500 || $mode == 5600)
3472 {
3473 my $salt_len;
3474
3475 for (my $i = 1; $i < 27; $i++)
3476 {
3477 $salt_len = get_random_num (1, 15);
3478
3479 if ($len != 0)
3480 {
3481 rnd ($mode, $len, $salt_len);
3482 }
3483 else
3484 {
3485 rnd ($mode, $i, $salt_len);
3486 }
3487 }
3488 }
3489 elsif ($mode == 5800)
3490 {
3491 for (my $i = 1; $i < 14; $i++)
3492 {
3493 if ($len != 0)
3494 {
3495 rnd ($mode, $len, 16);
3496 }
3497 else
3498 {
3499 rnd ($mode, $i, 16);
3500 }
3501 }
3502 }
3503 elsif ($mode == 6800)
3504 {
3505 my $salt_len = get_random_num (8, 25);
3506
3507 for (my $i = 1; $i < 32; $i++)
3508 {
3509 if ($len != 0)
3510 {
3511 rnd ($mode, $len, $salt_len);
3512 }
3513 else
3514 {
3515 rnd ($mode, $i, $salt_len);
3516 }
3517 }
3518 }
3519 elsif ($mode == 7100)
3520 {
3521 for (my $i = 1; $i < 32; $i++)
3522 {
3523 if ($len != 0)
3524 {
3525 rnd ($mode, $len, 64);
3526 }
3527 else
3528 {
3529 rnd ($mode, $i, 64);
3530 }
3531 }
3532 }
3533 elsif ($mode == 7200)
3534 {
3535 for (my $i = 1; $i < 32; $i++)
3536 {
3537 if ($len != 0)
3538 {
3539 rnd ($mode, $len, 128);
3540 }
3541 else
3542 {
3543 rnd ($mode, $i, 128);
3544 }
3545 }
3546 }
3547 elsif ($mode == 7300)
3548 {
3549 my $salt_len = get_random_num (32, 255);
3550
3551 for (my $i = 1; $i < 32; $i++)
3552 {
3553 if ($len != 0)
3554 {
3555 rnd ($mode, $len, $salt_len);
3556 }
3557 else
3558 {
3559 rnd ($mode, $i, $salt_len);
3560 }
3561 }
3562 }
3563 elsif ($mode == 7500)
3564 {
3565 for (my $i = 1; $i < 27; $i++)
3566 {
3567 if ($len != 0)
3568 {
3569 rnd ($mode, $len, 16);
3570 }
3571 else
3572 {
3573 rnd ($mode, $i, 16);
3574 }
3575 }
3576 }
3577 elsif ($mode == 7700)
3578 {
3579 my $salt_len = get_random_num (1, 12);
3580
3581 for (my $i = 1; $i < 9; $i++)
3582 {
3583 if ($len != 0)
3584 {
3585 rnd ($mode, $len, $salt_len);
3586 }
3587 else
3588 {
3589 rnd ($mode, $i, $salt_len);
3590 }
3591 }
3592 }
3593 elsif ($mode == 7800)
3594 {
3595 my $salt_len = get_random_num (1, 12);
3596
3597 for (my $i = 1; $i < 32; $i++)
3598 {
3599 if ($len != 0)
3600 {
3601 rnd ($mode, $len, $salt_len);
3602 }
3603 else
3604 {
3605 rnd ($mode, $i, $salt_len);
3606 }
3607 }
3608 }
3609 elsif ($mode == 8400 || $mode == 11200)
3610 {
3611 for (my $i = 1; $i < 32; $i++)
3612 {
3613 if ($len != 0)
3614 {
3615 rnd ($mode, $len, 40);
3616 }
3617 else
3618 {
3619 rnd ($mode, $i, 40);
3620 }
3621 }
3622 }
3623 elsif ($mode == 8500)
3624 {
3625 my $salt_len = get_random_num (1, 8);
3626
3627 for (my $i = 1; $i < 9; $i++)
3628 {
3629 if ($len != 0)
3630 {
3631 rnd ($mode, $len, $salt_len);
3632 }
3633 else
3634 {
3635 rnd ($mode, $i, $salt_len);
3636 }
3637 }
3638 }
3639 elsif ($mode == 8600)
3640 {
3641 for (my $i = 1; $i < 17; $i++)
3642 {
3643 if ($len != 0)
3644 {
3645 rnd ($mode, $len, 0);
3646 }
3647 else
3648 {
3649 rnd ($mode, $i, 0);
3650 }
3651 }
3652 }
3653 elsif ($mode == 8700)
3654 {
3655 for (my $i = 1; $i < 32; $i++)
3656 {
3657 if ($len != 0)
3658 {
3659 rnd ($mode, $len, 5);
3660 }
3661 else
3662 {
3663 rnd ($mode, $i, 5);
3664 }
3665 }
3666 }
3667 elsif ($mode == 9200 || $mode == 9300)
3668 {
3669 my $salt_len = 14;
3670
3671 for (my $i = 1; $i < 32; $i++)
3672 {
3673 if ($len != 0)
3674 {
3675 rnd ($mode, $len, $salt_len);
3676 }
3677 else
3678 {
3679 rnd ($mode, $i, $salt_len);
3680 }
3681 }
3682 }
3683 elsif ($mode == 9400 || $mode == 9500 || $mode == 9600 || $mode == 9700 || $mode == 9800)
3684 {
3685 my $salt_len = 32;
3686
3687 for (my $i = 1; $i < 20; $i++)
3688 {
3689 if ($len != 0)
3690 {
3691 rnd ($mode, $len, $salt_len);
3692 }
3693 else
3694 {
3695 rnd ($mode, $i, $salt_len);
3696 }
3697 }
3698 }
3699 elsif ($mode == 10100)
3700 {
3701 for (my $i = 1; $i < 32; $i++)
3702 {
3703 if ($len != 0)
3704 {
3705 rnd ($mode, $len, 32);
3706 }
3707 else
3708 {
3709 rnd ($mode, $i, 32);
3710 }
3711 }
3712 }
3713 elsif ($mode == 10300)
3714 {
3715 my $salt_len = get_random_num (4, 15);
3716
3717 for (my $i = 1; $i < 32; $i++)
3718 {
3719 if ($len != 0)
3720 {
3721 rnd ($mode, $len, $salt_len);
3722 }
3723 else
3724 {
3725 rnd ($mode, $i, $salt_len);
3726 }
3727 }
3728 }
3729 elsif ($mode == 10400 || $mode == 10600)
3730 {
3731 my $salt_len = 32;
3732
3733 for (my $i = 1; $i < 32; $i++)
3734 {
3735 if ($len != 0)
3736 {
3737 rnd ($mode, $len, $salt_len);
3738 }
3739 else
3740 {
3741 rnd ($mode, $i, $salt_len);
3742 }
3743 }
3744 }
3745 elsif ($mode == 10500 || $mode == 10700)
3746 {
3747 my $salt_len = 32;
3748
3749 for (my $i = 1; $i < 16; $i++)
3750 {
3751 if ($len != 0)
3752 {
3753 rnd ($mode, $len, $salt_len);
3754 }
3755 else
3756 {
3757 rnd ($mode, $i, $salt_len);
3758 }
3759 }
3760 }
3761 elsif ($mode == 11000)
3762 {
3763 for (my $i = 1; $i < 32; $i++)
3764 {
3765 if ($len != 0)
3766 {
3767 rnd ($mode, $len, 56);
3768 }
3769 else
3770 {
3771 rnd ($mode, $i, 56);
3772 }
3773 }
3774 }
3775 elsif ($mode == 11300)
3776 {
3777 for (my $i = 1; $i < 32; $i++)
3778 {
3779 if ($len != 0)
3780 {
3781 rnd ($mode, $len, 16);
3782 }
3783 else
3784 {
3785 rnd ($mode, $i, 16);
3786 }
3787 }
3788 }
3789 elsif ($mode == 11400)
3790 {
3791 for (my $i = 1; $i < 24; $i++)
3792 {
3793 if ($len != 0)
3794 {
3795 rnd ($mode, $len, 16);
3796 }
3797 else
3798 {
3799 rnd ($mode, $i, 16);
3800 }
3801 }
3802 }
3803 elsif ($mode == 11600)
3804 {
3805 my $salt_len = get_random_num (0, 16);
3806
3807 for (my $i = 1; $i < 32; $i++)
3808 {
3809 if ($len != 0)
3810 {
3811 rnd ($mode, $len, $salt_len);
3812 }
3813 else
3814 {
3815 rnd ($mode, $i, $salt_len);
3816 }
3817 }
3818 }
3819 elsif ($mode == 12400)
3820 {
3821 for (my $i = 1; $i < 32; $i++)
3822 {
3823 if ($len != 0)
3824 {
3825 rnd ($mode, $len, 4);
3826 }
3827 else
3828 {
3829 rnd ($mode, $i, 4);
3830 }
3831 }
3832 }
3833 elsif ($mode == 12600)
3834 {
3835 for (my $i = 1; $i < 32; $i++)
3836 {
3837 if ($len != 0)
3838 {
3839 rnd ($mode, $len, 64);
3840 }
3841 else
3842 {
3843 rnd ($mode, $i, 64);
3844 }
3845 }
3846 }
3847 elsif ($mode == 12700)
3848 {
3849 for (my $i = 1; $i < 32; $i++)
3850 {
3851 if ($len != 0)
3852 {
3853 rnd ($mode, $len, 32);
3854 }
3855 else
3856 {
3857 rnd ($mode, $i, 32);
3858 }
3859 }
3860 }
3861 elsif ($mode == 12800)
3862 {
3863 for (my $i = 1; $i < 25; $i++)
3864 {
3865 if ($len != 0)
3866 {
3867 rnd ($mode, $len, 20);
3868 }
3869 else
3870 {
3871 rnd ($mode, $i, 20);
3872 }
3873 }
3874 }
3875 elsif ($mode == 12900)
3876 {
3877 for (my $i = 1; $i < 32; $i++)
3878 {
3879 if ($len != 0)
3880 {
3881 rnd ($mode, $len, 32);
3882 }
3883 else
3884 {
3885 rnd ($mode, $i, 32);
3886 }
3887 }
3888 }
3889 elsif ($mode == 13000)
3890 {
3891 for (my $i = 1; $i < 32; $i++)
3892 {
3893 if ($len != 0)
3894 {
3895 rnd ($mode, $len, 32);
3896 }
3897 else
3898 {
3899 rnd ($mode, $i, 32);
3900 }
3901 }
3902 }
3903 elsif ($mode == 13100)
3904 {
3905 for (my $i = 1; $i < 27; $i++)
3906 {
3907 if ($len != 0)
3908 {
3909 rnd ($mode, $len, 16);
3910 }
3911 else
3912 {
3913 rnd ($mode, $i, 16);
3914 }
3915 }
3916 }
3917 elsif ($mode == 13200)
3918 {
3919 for (my $i = 1; $i < 32; $i++)
3920 {
3921 if ($len != 0)
3922 {
3923 rnd ($mode, $len, 32);
3924 }
3925 else
3926 {
3927 rnd ($mode, $i, 32);
3928 }
3929 }
3930 }
3931 elsif ($mode == 13400)
3932 {
3933 for (my $i = 1; $i < 16; $i++)
3934 {
3935 if ($len != 0)
3936 {
3937 rnd ($mode, $len, 16);
3938 }
3939 else
3940 {
3941 rnd ($mode, $i, 16);
3942 }
3943 }
3944 }
3945 elsif ($mode == 13500)
3946 {
3947 for (my $i = 1; $i < 16; $i++)
3948 {
3949 if ($len != 0)
3950 {
3951 rnd ($mode, $len, 16);
3952 }
3953 else
3954 {
3955 rnd ($mode, $i, 16);
3956 }
3957 }
3958 }
3959 elsif ($mode == 13600)
3960 {
3961 for (my $i = 1; $i < 16; $i++)
3962 {
3963 if ($len != 0)
3964 {
3965 rnd ($mode, $len, 32);
3966 }
3967 else
3968 {
3969 rnd ($mode, $i, 32);
3970 }
3971 }
3972 }
3973 elsif ($mode == 13800)
3974 {
3975 for (my $i = 1; $i < 32; $i++)
3976 {
3977 if ($len != 0)
3978 {
3979 rnd ($mode, $len, 256);
3980 }
3981 else
3982 {
3983 rnd ($mode, $i, 256);
3984 }
3985 }
3986 }
3987 }
3988 }
3989
3990 exit;
3991
3992 sub gen_hash
3993 {
3994 my $mode = shift;
3995
3996 my $word_buf = shift;
3997
3998 my $salt_buf = shift;
3999
4000 my $iter = shift;
4001
4002 my $additional_param = shift;
4003
4004 my $additional_param2 = shift;
4005
4006 my $additional_param3 = shift;
4007
4008 my $additional_param4 = shift;
4009
4010 my $additional_param5 = shift;
4011
4012 my $additional_param6 = shift;
4013
4014 my $additional_param7 = shift;
4015
4016 my $additional_param8 = shift;
4017
4018 my $additional_param9 = shift;
4019
4020 my $additional_param10 = shift;
4021
4022 my $additional_param11 = shift;
4023
4024 ##
4025 ## gen hash
4026 ##
4027
4028 my $tmp_hash;
4029
4030 my $hash_buf;
4031
4032 if ($mode == 0)
4033 {
4034 $hash_buf = md5_hex ($word_buf);
4035
4036 $tmp_hash = sprintf ("%s", $hash_buf);
4037 }
4038 elsif ($mode == 10)
4039 {
4040 $hash_buf = md5_hex ($word_buf . $salt_buf);
4041
4042 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4043 }
4044 elsif ($mode == 11)
4045 {
4046 $hash_buf = md5_hex ($word_buf . $salt_buf);
4047
4048 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4049 }
4050 elsif ($mode == 12)
4051 {
4052 $hash_buf = md5_hex ($word_buf . $salt_buf);
4053
4054 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4055 }
4056 elsif ($mode == 20)
4057 {
4058 $hash_buf = md5_hex ($salt_buf . $word_buf);
4059
4060 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4061 }
4062 elsif ($mode == 21)
4063 {
4064 $hash_buf = md5_hex ($salt_buf . $word_buf);
4065
4066 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4067 }
4068 elsif ($mode == 22)
4069 {
4070 my $itoa64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4071 my $salt_suffix = "Administration Tools";
4072
4073 my $pass = sprintf ("%s:%s:%s", $salt_buf, $salt_suffix, $word_buf);
4074
4075 $hash_buf = md5 ($pass);
4076
4077 my $res = "";
4078
4079 for (my $pos = 0; $pos < 16; $pos += 2)
4080 {
4081 my $octet1 = ord (substr ($hash_buf, $pos + 0, 1));
4082 my $octet2 = ord (substr ($hash_buf, $pos + 1, 1));
4083
4084 my $num = ($octet1 <<8 & 0xff00) | ($octet2 & 0xff);
4085
4086 my $idx1 = $num >> 12 & 0x0f;
4087 my $idx2 = $num >> 6 & 0x3f;
4088 my $idx3 = $num & 0x3f;
4089
4090 $res = $res . substr ($itoa64, $idx1, 1) . substr ($itoa64, $idx2, 1) . substr ($itoa64, $idx3, 1);
4091 }
4092
4093 my $obfuscate_str = "nrcstn";
4094 my @obfuscate_pos = (0, 6, 12, 17, 23, 29);
4095
4096 foreach my $pos (keys @obfuscate_pos)
4097 {
4098 my $idx = $obfuscate_pos[$pos];
4099 my $before = substr ($res, 0, $idx);
4100 my $char = substr ($obfuscate_str, $pos, 1);
4101 my $after = substr ($res, $idx);
4102
4103 $res = sprintf ("%s%s%s", $before, $char, $after);
4104 }
4105
4106 $tmp_hash = sprintf ("%s:%s", $res, $salt_buf);
4107 }
4108 elsif ($mode == 23)
4109 {
4110 $hash_buf = md5_hex ($salt_buf . "\nskyper\n" . $word_buf);
4111
4112 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4113 }
4114 elsif ($mode == 30)
4115 {
4116 $hash_buf = md5_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4117
4118 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4119 }
4120 elsif ($mode == 40)
4121 {
4122 $hash_buf = md5_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4123
4124 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4125 }
4126 elsif ($mode == 50)
4127 {
4128 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&md5, 64);
4129
4130 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4131 }
4132 elsif ($mode == 60)
4133 {
4134 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&md5, 64);
4135
4136 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4137 }
4138 elsif ($mode == 100)
4139 {
4140 $hash_buf = sha1_hex ($word_buf);
4141
4142 $tmp_hash = sprintf ("%s", $hash_buf);
4143 }
4144 elsif ($mode == 101)
4145 {
4146 $hash_buf = sha1 ($word_buf);
4147
4148 my $base64_buf = encode_base64 ($hash_buf);
4149
4150 chomp ($base64_buf);
4151
4152 $tmp_hash = sprintf ("{SHA}%s", $base64_buf);
4153 }
4154 elsif ($mode == 110)
4155 {
4156 $hash_buf = sha1_hex ($word_buf . $salt_buf);
4157
4158 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4159 }
4160 elsif ($mode == 111)
4161 {
4162 $hash_buf = sha1 ($word_buf . $salt_buf);
4163
4164 my $base64_buf = encode_base64 ($hash_buf . $salt_buf);
4165
4166 chomp ($base64_buf);
4167
4168 $tmp_hash = sprintf ("{SSHA}%s", $base64_buf);
4169 }
4170 elsif ($mode == 112)
4171 {
4172 my $salt_buf_bin = pack ("H*", $salt_buf);
4173
4174 $hash_buf = sha1_hex ($word_buf . $salt_buf_bin);
4175
4176 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4177 }
4178 elsif ($mode == 120)
4179 {
4180 $hash_buf = sha1_hex ($salt_buf . $word_buf);
4181
4182 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4183 }
4184 elsif ($mode == 121)
4185 {
4186 $hash_buf = sha1_hex (lc ($salt_buf) . $word_buf);
4187
4188 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4189 }
4190 elsif ($mode == 122)
4191 {
4192 my $salt_buf_bin = pack ("H*", $salt_buf);
4193
4194 $hash_buf = sha1_hex ($salt_buf_bin . $word_buf);
4195
4196 $tmp_hash = sprintf ("%s%s", $salt_buf, $hash_buf);
4197 }
4198 elsif ($mode == 125)
4199 {
4200 my $signature = "01";
4201
4202 my $salt_buf_bin = pack ("H*", $salt_buf . $signature);
4203
4204 $hash_buf = sha1_hex ($salt_buf_bin . $word_buf);
4205
4206 $tmp_hash = sprintf ("%s%s%s", $salt_buf, $signature, $hash_buf);
4207 }
4208 elsif ($mode == 130)
4209 {
4210 $hash_buf = sha1_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4211
4212 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4213 }
4214 elsif ($mode == 131)
4215 {
4216 my $salt_buf_bin = pack ("H*", $salt_buf);
4217
4218 $hash_buf = sha1_hex (encode ("UTF-16LE", uc ($word_buf)) . $salt_buf_bin);
4219
4220 $tmp_hash = sprintf ("0x0100%s%s%s", $salt_buf, "0" x 40, $hash_buf);
4221 }
4222 elsif ($mode == 132)
4223 {
4224 my $salt_buf_bin = pack ("H*", $salt_buf);
4225
4226 $hash_buf = sha1_hex (encode ("UTF-16LE", $word_buf) . $salt_buf_bin);
4227
4228 $tmp_hash = sprintf ("0x0100%s%s", $salt_buf, $hash_buf);
4229 }
4230 elsif ($mode == 133)
4231 {
4232 $hash_buf = sha1 (encode ("UTF-16LE", $word_buf));
4233
4234 $hash_buf = encode_base64 ($hash_buf);
4235 $hash_buf =~ s/[\r\n]//g;
4236
4237 $tmp_hash = sprintf ("%s", $hash_buf);
4238 }
4239 elsif ($mode == 140)
4240 {
4241 $hash_buf = sha1_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4242
4243 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4244 }
4245 elsif ($mode == 141)
4246 {
4247 $hash_buf = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
4248
4249 my $base64_salt_buf = encode_base64 ($salt_buf);
4250
4251 chomp ($base64_salt_buf);
4252
4253 my $base64_hash_buf = encode_base64 ($hash_buf);
4254
4255 $base64_hash_buf = substr ($base64_hash_buf, 0, 27);
4256
4257 $tmp_hash = sprintf ("\$episerver\$*0*%s*%s", $base64_salt_buf, $base64_hash_buf);
4258 }
4259 elsif ($mode == 150)
4260 {
4261 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha1, 64);
4262
4263 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4264 }
4265 elsif ($mode == 160)
4266 {
4267 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha1, 64);
4268
4269 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4270 }
4271 elsif ($mode == 190)
4272 {
4273 $hash_buf = sha1_hex ($word_buf);
4274
4275 my $variant = int (rand (2));
4276
4277 if (defined ($additional_param))
4278 {
4279 $variant = $additional_param;
4280 }
4281
4282 if ($variant == 1)
4283 {
4284 substr ($hash_buf, 0, 5) = "00000";
4285 }
4286
4287 $tmp_hash = sprintf ("%s", $hash_buf);
4288 }
4289 elsif ($mode == 200)
4290 {
4291 my $ppr = Authen::Passphrase::MySQL323->new (passphrase => $word_buf);
4292
4293 $hash_buf = $ppr->hash_hex;
4294
4295 $tmp_hash = sprintf ("%s", $hash_buf);
4296 }
4297 elsif ($mode == 300)
4298 {
4299 $hash_buf = substr (password41 ($word_buf), 1);
4300
4301 $hash_buf = lc ($hash_buf); # useful for 'not matched' check only
4302
4303 $tmp_hash = sprintf ("%s", $hash_buf);
4304 }
4305 elsif ($mode == 400)
4306 {
4307 my $cost = 11;
4308
4309 if (length ($iter))
4310 {
4311 $cost = $iter;
4312 }
4313
4314 my $ppr = Authen::Passphrase::PHPass->new
4315 (
4316 cost => $cost,
4317 salt => $salt_buf,
4318 passphrase => $word_buf,
4319 );
4320
4321 $hash_buf = $ppr->as_rfc2307;
4322
4323 $tmp_hash = sprintf ("%s", substr ($hash_buf, 7));
4324 }
4325 elsif ($mode == 500)
4326 {
4327 my $iterations = 1000;
4328
4329 if (defined ($iter))
4330 {
4331 if ($iter > 0)
4332 {
4333 $iterations = int ($iter);
4334 }
4335 }
4336
4337 $hash_buf = md5_crypt ('$1$', $iterations, $word_buf, $salt_buf);
4338
4339 $tmp_hash = sprintf ("%s", $hash_buf);
4340 }
4341 elsif ($mode == 900)
4342 {
4343 $hash_buf = md4_hex ($word_buf);
4344
4345 $tmp_hash = sprintf ("%s", $hash_buf);
4346 }
4347 elsif ($mode == 1000)
4348 {
4349 $hash_buf = md4_hex (encode ("UTF-16LE", $word_buf));
4350
4351 $tmp_hash = sprintf ("%s", $hash_buf);
4352 }
4353 elsif ($mode == 1100)
4354 {
4355 $hash_buf = md4_hex (md4 (encode ("UTF-16LE", $word_buf)) . encode ("UTF-16LE", lc ($salt_buf)));
4356
4357 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4358 }
4359 elsif ($mode == 1400)
4360 {
4361 $hash_buf = sha256_hex ($word_buf);
4362
4363 $tmp_hash = sprintf ("%s", $hash_buf);
4364 }
4365 elsif ($mode == 1410)
4366 {
4367 $hash_buf = sha256_hex ($word_buf . $salt_buf);
4368
4369 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4370 }
4371 elsif ($mode == 1420)
4372 {
4373 $hash_buf = sha256_hex ($salt_buf . $word_buf);
4374
4375 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4376 }
4377 elsif ($mode == 1430)
4378 {
4379 $hash_buf = sha256_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4380
4381 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4382 }
4383 elsif ($mode == 1440)
4384 {
4385 $hash_buf = sha256_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4386
4387 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4388 }
4389 elsif ($mode == 1441)
4390 {
4391 $hash_buf = sha256 ($salt_buf . encode ("UTF-16LE", $word_buf));
4392
4393 my $base64_salt_buf = encode_base64 ($salt_buf);
4394
4395 chomp ($base64_salt_buf);
4396
4397 my $base64_hash_buf = encode_base64 ($hash_buf);
4398
4399 chomp ($base64_hash_buf);
4400
4401 $base64_hash_buf = substr ($base64_hash_buf, 0, 43);
4402
4403 $tmp_hash = sprintf ("\$episerver\$*1*%s*%s", $base64_salt_buf, $base64_hash_buf);
4404 }
4405 elsif ($mode == 1450)
4406 {
4407 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha256, 64);
4408
4409 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4410 }
4411 elsif ($mode == 1460)
4412 {
4413 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha256, 64);
4414
4415 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4416 }
4417 elsif ($mode == 1500)
4418 {
4419 $hash_buf = crypt ($word_buf, $salt_buf);
4420
4421 $tmp_hash = sprintf ("%s", $hash_buf);
4422 }
4423 elsif ($mode == 1600)
4424 {
4425 my $iterations = 1000;
4426
4427 if (defined ($iter))
4428 {
4429 if ($iter > 0)
4430 {
4431 $iterations = int ($iter);
4432 }
4433 }
4434
4435 $hash_buf = md5_crypt ('$apr1$', $iterations, $word_buf, $salt_buf);
4436
4437 $tmp_hash = sprintf ("%s", $hash_buf);
4438 }
4439 elsif ($mode == 1700)
4440 {
4441 $hash_buf = sha512_hex ($word_buf);
4442
4443 $tmp_hash = sprintf ("%s", $hash_buf);
4444 }
4445 elsif ($mode == 1710)
4446 {
4447 $hash_buf = sha512_hex ($word_buf . $salt_buf);
4448
4449 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4450 }
4451 elsif ($mode == 1711)
4452 {
4453 $hash_buf = sha512_hex ($word_buf . $salt_buf);
4454
4455 my $base64_buf = encode_base64 (pack ("H*", $hash_buf) . $salt_buf);
4456
4457 $base64_buf =~ s/[ \n]//g;
4458
4459 $tmp_hash = sprintf ("{SSHA512}%s", $base64_buf);
4460 }
4461 elsif ($mode == 1720)
4462 {
4463 $hash_buf = sha512_hex ($salt_buf . $word_buf);
4464
4465 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4466 }
4467 elsif ($mode == 1730)
4468 {
4469 $hash_buf = sha512_hex (encode ("UTF-16LE", $word_buf) . $salt_buf);
4470
4471 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4472 }
4473 elsif ($mode == 1740)
4474 {
4475 $hash_buf = sha512_hex ($salt_buf . encode ("UTF-16LE", $word_buf));
4476
4477 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4478 }
4479 elsif ($mode == 1722)
4480 {
4481 my $salt_buf_bin = pack ("H*", $salt_buf);
4482
4483 $hash_buf = sha512_hex ($salt_buf_bin . $word_buf);
4484
4485 $tmp_hash = sprintf ("%s%s", $salt_buf, $hash_buf);
4486 }
4487 elsif ($mode == 1731)
4488 {
4489 my $salt_buf_bin = pack ("H*", $salt_buf);
4490
4491 $hash_buf = sha512_hex (encode ("UTF-16LE", $word_buf) . $salt_buf_bin);
4492
4493 $tmp_hash = sprintf ("0x0200%s%s", $salt_buf, $hash_buf);
4494 }
4495 elsif ($mode == 1750)
4496 {
4497 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha512, 128);
4498
4499 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4500 }
4501 elsif ($mode == 1760)
4502 {
4503 $hash_buf = hmac_hex ($word_buf, $salt_buf, \&sha512, 128);
4504
4505 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4506 }
4507 elsif ($mode == 1800)
4508 {
4509 my $iterations = 5000;
4510
4511 if (defined ($iter))
4512 {
4513 if ($iter > 0)
4514 {
4515 $iterations = int ($iter);
4516 }
4517 }
4518
4519 $hash_buf = sha512_crypt ($iterations, $word_buf, $salt_buf);
4520
4521 $tmp_hash = sprintf ("%s", $hash_buf);
4522 }
4523 elsif ($mode == 2100)
4524 {
4525 my $iterations = 10240;
4526
4527 if (length ($iter))
4528 {
4529 $iterations = int ($iter);
4530 }
4531
4532 my $salt = encode ("UTF-16LE", lc ($salt_buf));
4533
4534 my $pbkdf2 = Crypt::PBKDF2->new
4535 (
4536 hash_class => 'HMACSHA1',
4537 iterations => $iterations,
4538 output_len => 16,
4539 salt_len => length ($salt),
4540 );
4541
4542 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 ($salt, md4 (md4 (encode ("UTF-16LE", $word_buf)) . $salt)));
4543
4544 $tmp_hash = sprintf ("\$DCC2\$%i#%s#%s", $iterations, $salt_buf, $hash_buf);
4545 }
4546 elsif ($mode == 2400)
4547 {
4548 $tmp_hash = sprintf ("%s", pseudo_base64 (Digest::MD5::md5 ($word_buf . "\0" x (16 - length ($word_buf)))));
4549 }
4550 elsif ($mode == 2410)
4551 {
4552 my $salt_len = length ($salt_buf);
4553
4554 my $salt_len_max4 = ($salt_len < 4) ? $salt_len : 4;
4555
4556 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)));
4557
4558 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4559 }
4560 elsif ($mode == 2500)
4561 {
4562 my ($bssid, $stmac, $snonce, $anonce, $eapol, $keyver, $eapol_size);
4563
4564 if (! defined ($additional_param))
4565 {
4566 # random stuff
4567
4568 $bssid = randbytes (6);
4569 $stmac = randbytes (6);
4570 $snonce = randbytes (32);
4571 $anonce = randbytes (32);
4572
4573 $keyver = get_random_num (1, 3); # 1 or 2
4574
4575 # eapol:
4576 # should be "validly" generated, but in theory could be anything for us also:
4577 # $eapol = "\x00" x 121; # works too, but let's generate it correctly
4578
4579 $eapol = gen_random_wpa_eapol ($keyver, $snonce);
4580 }
4581 else
4582 {
4583 $bssid = $additional_param;
4584 $stmac = $additional_param2;
4585 $snonce = $additional_param3;
4586 $anonce = $additional_param4;
4587 $keyver = $additional_param5;
4588 $eapol = $additional_param6;
4589 }
4590
4591 $eapol_size = length ($eapol);
4592
4593 # constants
4594
4595 my $iterations = 4096;
4596
4597 #
4598 # START
4599 #
4600
4601 # generate the Pairwise Master Key (PMK)
4602
4603 my $pbkdf2 = Crypt::PBKDF2->new
4604 (
4605 hash_class => 'HMACSHA1',
4606 iterations => $iterations,
4607 output_len => 32,
4608 );
4609
4610 my $pmk = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
4611
4612 # Pairwise Transient Key (PTK) transformation
4613
4614 my $ptk = wpa_prf_512 ($pmk, $stmac, $bssid, $snonce, $anonce);
4615
4616 # generate the Message Integrity Code (MIC)
4617
4618 my $mic = "";
4619
4620 if ($keyver == 1) # WPA1 => MD5
4621 {
4622 $mic = hmac ($eapol, $ptk, \&md5);
4623 }
4624 else # WPA2 => SHA1
4625 {
4626 $mic = hmac ($eapol, $ptk, \&sha1);
4627 }
4628
4629 $mic = substr ($mic, 0, 16);
4630
4631 #
4632 # format the binary output
4633 #
4634
4635 $hash_buf = "";
4636
4637 # first the essid (NULL-padded up to the first 36 bytes)
4638
4639 $hash_buf .= $salt_buf;
4640 $hash_buf .= "\x00" x (36 - length ($salt_buf));
4641
4642 # the 2 MAC addresses
4643
4644 $hash_buf .= $bssid;
4645 $hash_buf .= $stmac;
4646
4647 # nonces
4648
4649 $hash_buf .= $snonce;
4650 $hash_buf .= $anonce;
4651
4652 # eapol
4653
4654 $hash_buf .= $eapol;
4655 $hash_buf .= "\x00" x (256 - $eapol_size);
4656
4657 # eapol size
4658
4659 $hash_buf .= pack ("L*", $eapol_size);
4660
4661 # key version
4662
4663 $hash_buf .= pack ("L*", $keyver);
4664
4665 # and finally: the key mic
4666
4667 $hash_buf .= $mic;
4668
4669 # base64 encode the output
4670
4671 $tmp_hash = encode_base64 ($hash_buf, '');
4672 }
4673 elsif ($mode == 2600)
4674 {
4675 $hash_buf = md5_hex (md5_hex ($word_buf));
4676
4677 $tmp_hash = sprintf ("%s", $hash_buf);
4678 }
4679 elsif ($mode == 2611)
4680 {
4681 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4682
4683 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4684 }
4685 elsif ($mode == 2612)
4686 {
4687 my $salt_buf_hex = unpack ("H*", $salt_buf);
4688
4689 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4690
4691 $tmp_hash = sprintf ("\$PHPS\$%s\$%s", $salt_buf_hex, $hash_buf);
4692 }
4693 elsif ($mode == 2711)
4694 {
4695 $hash_buf = md5_hex (md5_hex ($word_buf) . $salt_buf);
4696
4697 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4698 }
4699 elsif ($mode == 2811)
4700 {
4701 $hash_buf = md5_hex (md5_hex ($salt_buf) . md5_hex ($word_buf));
4702
4703 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4704 }
4705 elsif ($mode == 3000)
4706 {
4707 my $ppr = Authen::Passphrase::LANManager->new ("passphrase" => $word_buf);
4708
4709 $hash_buf = $ppr->hash_hex;
4710
4711 $tmp_hash = sprintf ("%s", substr ($hash_buf, 0, 16));
4712 }
4713 elsif ($mode == 3100)
4714 {
4715 $hash_buf = oracle_hash ($salt_buf, $word_buf);
4716
4717 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4718 }
4719 elsif ($mode == 3200)
4720 {
4721 my $cost = "05";
4722
4723 if (length ($iter))
4724 {
4725 $cost = $iter;
4726 }
4727
4728 $tmp_hash = bcrypt ($word_buf, sprintf ('$2a$%s$%s$', $cost, en_base64 ($salt_buf)));
4729 }
4730 elsif ($mode == 3300)
4731 {
4732 my $iterations = 904;
4733
4734 if (length ($iter))
4735 {
4736 $iterations = int ($iter);
4737 }
4738
4739 my $variant = "\$";
4740
4741 if (defined ($additional_param))
4742 {
4743 $variant = $additional_param;
4744 }
4745
4746 my $prefix = sprintf ("\$md5%srounds=%i\$%s", $variant, $iterations, $salt_buf);
4747
4748 $iterations += 4096;
4749
4750 $hash_buf = sun_md5 ($word_buf, $prefix, $iterations);
4751
4752 $tmp_hash = sprintf ("%s\$%s", $prefix, $hash_buf);
4753 }
4754 elsif ($mode == 3500)
4755 {
4756 $hash_buf = md5_hex (md5_hex (md5_hex ($word_buf)));
4757
4758 $tmp_hash = sprintf ("%s", $hash_buf);
4759 }
4760 elsif ($mode == 3610)
4761 {
4762 $hash_buf = md5_hex (md5_hex ($salt_buf) . $word_buf);
4763
4764 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4765 }
4766 elsif ($mode == 3710)
4767 {
4768 $hash_buf = md5_hex ($salt_buf . md5_hex ($word_buf));
4769
4770 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4771 }
4772 elsif ($mode == 3711)
4773 {
4774 $hash_buf = md5_hex ($salt_buf . "-" . md5_hex ($word_buf));
4775
4776 $tmp_hash = sprintf ("\$B\$%s\$%s", $salt_buf, $hash_buf);
4777 }
4778 elsif ($mode == 3720)
4779 {
4780 $hash_buf = md5_hex ($word_buf . md5_hex ($salt_buf));
4781
4782 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4783 }
4784 elsif ($mode == 3800)
4785 {
4786 $hash_buf = md5_hex ($salt_buf . $word_buf . $salt_buf);
4787
4788 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4789 }
4790 elsif ($mode == 3910)
4791 {
4792 $hash_buf = md5_hex (md5_hex ($word_buf) . md5_hex ($salt_buf));
4793
4794 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4795 }
4796 elsif ($mode == 4010)
4797 {
4798 $hash_buf = md5_hex ($salt_buf . md5_hex ($salt_buf . $word_buf));
4799
4800 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4801 }
4802 elsif ($mode == 4110)
4803 {
4804 $hash_buf = md5_hex ($salt_buf . md5_hex ($word_buf . $salt_buf));
4805
4806 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4807 }
4808 elsif ($mode == 4210)
4809 {
4810 $hash_buf = md5_hex ($salt_buf . "\x00" . $word_buf);
4811
4812 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4813 }
4814 elsif ($mode == 4300)
4815 {
4816 $hash_buf = md5_hex (uc (md5_hex ($word_buf)));
4817
4818 $tmp_hash = sprintf ("%s", $hash_buf);
4819 }
4820 elsif ($mode == 4400)
4821 {
4822 $hash_buf = md5_hex (sha1_hex ($word_buf));
4823
4824 $tmp_hash = sprintf ("%s", $hash_buf);
4825 }
4826 elsif ($mode == 4500)
4827 {
4828 $hash_buf = sha1_hex (sha1_hex ($word_buf));
4829
4830 $tmp_hash = sprintf ("%s", $hash_buf);
4831 }
4832 elsif ($mode == 4600)
4833 {
4834 $hash_buf = sha1_hex (sha1_hex (sha1_hex ($word_buf)));
4835
4836 $tmp_hash = sprintf ("%s", $hash_buf);
4837 }
4838 elsif ($mode == 4700)
4839 {
4840 $hash_buf = sha1_hex (md5_hex ($word_buf));
4841
4842 $tmp_hash = sprintf ("%s", $hash_buf);
4843 }
4844 elsif ($mode == 4800)
4845 {
4846 my $index = rindex ($salt_buf, ":");
4847
4848 my $salt = substr ($salt_buf, 0, $index);
4849 my $salt_bin = pack ("H*", $salt);
4850 my $chap_sign = substr ($salt_buf, $index + 1);
4851 my $chap_sign_bin = pack ("H*", $chap_sign);
4852
4853 $hash_buf = md5_hex ($chap_sign_bin . $word_buf . $salt_bin);
4854
4855 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4856 }
4857 elsif ($mode == 4900)
4858 {
4859 $hash_buf = sha1_hex ($salt_buf . $word_buf . $salt_buf);
4860
4861 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4862 }
4863 elsif ($mode == 5000)
4864 {
4865 $hash_buf = keccak_256_hex ($word_buf);
4866
4867 $tmp_hash = sprintf ("%s", $hash_buf);
4868 }
4869 elsif ($mode == 5100)
4870 {
4871 my $pos;
4872
4873 if (! defined ($additional_param))
4874 {
4875 $pos = 0;
4876 }
4877 else
4878 {
4879 $pos = $additional_param * 8 unless ($additional_param > 2);
4880 }
4881
4882 $hash_buf = md5_hex ($word_buf);
4883
4884 $tmp_hash = sprintf ("%s", substr ($hash_buf, $pos, 16));
4885 }
4886 elsif ($mode == 5300)
4887 {
4888 my @salt_arr = split (":", $salt_buf);
4889
4890 my $msg_buf = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]);
4891 my $nr_buf = pack ("H*", $salt_arr[6] . $salt_arr[7]);
4892
4893 my $hash_buf = hmac ($nr_buf , $word_buf, \&md5, 64);
4894 $hash_buf = hmac_hex ($msg_buf, $hash_buf, \&md5, 64);
4895
4896 $tmp_hash = sprintf ("%s:%s", $salt_buf, $hash_buf);
4897 }
4898 elsif ($mode == 5400)
4899 {
4900 my @salt_arr = split (":", $salt_buf);
4901
4902 my $msg_buf = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]);
4903 my $nr_buf = pack ("H*", $salt_arr[6] . $salt_arr[7]);
4904
4905 my $hash_buf = hmac ($nr_buf , $word_buf, \&sha1, 64);
4906 $hash_buf = hmac_hex ($msg_buf, $hash_buf, \&sha1, 64);
4907
4908 $tmp_hash = sprintf ("%s:%s", $salt_buf, $hash_buf);
4909 }
4910 elsif ($mode == 5500)
4911 {
4912 my $index1 = index ($salt_buf, "::");
4913 my $user = substr ($salt_buf, 0, $index1);
4914
4915 my $index2 = index ($salt_buf, ":", $index1 + 2);
4916 my $domain = substr ($salt_buf, $index1 + 2, $index2 - $index1 - 2);
4917
4918 my $len = length (substr ($salt_buf, $index2 + 1));
4919
4920 my $c_challenge_hex;
4921
4922 if ($len > 32)
4923 {
4924 $c_challenge_hex = substr ($salt_buf, $index2 + 1, 48);
4925 $index2 += 32;
4926 }
4927 else
4928 {
4929 $c_challenge_hex = substr ($salt_buf, $index2 + 1, 16);
4930 $c_challenge_hex .= 00 x 32;
4931 }
4932
4933 my $c_challenge = pack ("H*", substr ($c_challenge_hex, 0, 16));
4934 my $s_challenge_hex = substr ($salt_buf, $index2 + 17, 16);
4935 my $s_challenge = pack ("H*", $s_challenge_hex);
4936
4937 my $challenge = substr (md5 ($s_challenge . $c_challenge), 0, 8);
4938
4939 my $ntresp;
4940
4941 my $nthash = Authen::Passphrase::NTHash->new (passphrase => $word_buf)->hash . "\x00" x 5;
4942
4943 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 0, 7)), "DES", $challenge, "none");
4944 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 7, 7)), "DES", $challenge, "none");
4945 $ntresp .= Crypt::ECB::encrypt (setup_des_key (substr ($nthash, 14, 7)), "DES", $challenge, "none");
4946
4947 $tmp_hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $c_challenge_hex, unpack ("H*", $ntresp), $s_challenge_hex);
4948 }
4949 elsif ($mode == 5600)
4950 {
4951 my $index1 = index ($salt_buf, "::");
4952 my $user = substr ($salt_buf, 0, $index1);
4953
4954 my $index2 = index ($salt_buf, ":", $index1 + 2);
4955 my $domain = substr ($salt_buf, $index1 + 2, $index2 - $index1 - 2);
4956
4957 my $s_challenge_hex = substr ($salt_buf, $index2 + 1, 16);
4958 my $s_challenge = pack ("H*", $s_challenge_hex);
4959
4960 my $temp_hex = substr ($salt_buf, $index2 + 17);
4961 my $temp = pack ("H*", $temp_hex);
4962
4963 my $nthash = Authen::Passphrase::NTHash->new (passphrase => $word_buf)->hash;
4964 my $identity = Encode::encode ("UTF-16LE", uc ($user) . $domain);
4965
4966 $hash_buf = hmac_hex ($s_challenge . $temp, hmac ($identity, $nthash, \&md5, 64), \&md5, 64);
4967
4968 $tmp_hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $s_challenge_hex, $hash_buf, $temp_hex);
4969 }
4970 elsif ($mode == 5700)
4971 {
4972 $hash_buf = sha256 ($word_buf);
4973
4974 my $base64_buf = encode_base64 ($hash_buf);
4975
4976 $tmp_hash = "";
4977
4978 for (my $i = 0; $i < 43; $i++)
4979 {
4980 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($base64_buf, $i, 1)};
4981 }
4982 }
4983 elsif ($mode == 5800)
4984 {
4985 $hash_buf = androidpin_hash ($word_buf, $salt_buf);
4986
4987 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
4988 }
4989 elsif ($mode == 6000)
4990 {
4991 $hash_buf = ripemd160_hex ($word_buf);
4992
4993 $tmp_hash = sprintf ("%s", $hash_buf);
4994 }
4995 elsif ($mode == 6100)
4996 {
4997 $hash_buf = whirlpool_hex ($word_buf);
4998
4999 $tmp_hash = sprintf ("%s", $hash_buf);
5000 }
5001 elsif ($mode == 6300)
5002 {
5003 my $iterations = 1000; # hard coded by the AIX format
5004
5005 $hash_buf = md5_crypt ('', $iterations, $word_buf, $salt_buf);
5006
5007 $tmp_hash = sprintf ("{smd5}%s", $hash_buf);
5008 }
5009 elsif ($mode == 6400)
5010 {
5011 my $iterations = 64;
5012
5013 if (length ($iter))
5014 {
5015 $iterations = 1 << int ($iter);
5016 }
5017
5018 $hash_buf = aix_ssha256_pbkdf2 ($word_buf, $salt_buf, $iterations);
5019
5020 $tmp_hash = sprintf ("{ssha256}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
5021 }
5022 elsif ($mode == 6500)
5023 {
5024 my $iterations = 64;
5025
5026 if (length ($iter))
5027 {
5028 $iterations = 1 << int ($iter);
5029 }
5030
5031 $hash_buf = aix_ssha512_pbkdf2 ($word_buf, $salt_buf, $iterations);
5032
5033 $tmp_hash = sprintf ("{ssha512}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
5034 }
5035 elsif ($mode == 6600)
5036 {
5037 my $iterations = 1000;
5038
5039 if (length ($iter))
5040 {
5041 $iterations = int ($iter);
5042 }
5043
5044 my $salt_hex = substr ($salt_buf, 0, 16);
5045 my $salt = pack ("H*", $salt_hex);
5046
5047 my $prefix = substr ($salt_buf, 16, 2016);
5048
5049 my $iv_hex = substr ($salt_buf, 2032);
5050 my $iv = pack ("H*", $iv_hex);
5051
5052 my $data = pack ("H*", "10101010101010101010101010101010");
5053
5054 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
5055
5056 my $pbkdf2 = Crypt::PBKDF2->new (
5057 hasher => $hasher,
5058 iterations => $iterations,
5059 output_len => 16
5060 );
5061
5062 my $key = $pbkdf2->PBKDF2 ($salt, $word_buf);
5063
5064 my $cipher = Crypt::CBC->new ({
5065 key => $key,
5066 cipher => "Crypt::Rijndael",
5067 iv => $iv,
5068 literal_key => 1,
5069 header => "none",
5070 keysize => 16
5071 });
5072
5073 my $encrypted = unpack ("H*", $cipher->encrypt ($data));
5074
5075 $hash_buf = substr ($encrypted, 0, 32);
5076
5077 $tmp_hash = sprintf ("%i:%s:%s%s%s", $iterations, $salt_hex, $prefix, $iv_hex, $hash_buf);
5078 }
5079 elsif ($mode == 6700)
5080 {
5081 my $iterations = 64;
5082
5083 if (length ($iter))
5084 {
5085 $iterations = 1 << int ($iter);
5086 }
5087
5088 $hash_buf = aix_ssha1_pbkdf2 ($word_buf, $salt_buf, $iterations);
5089
5090 $tmp_hash = sprintf ("{ssha1}%02i\$%s\$%s", log ($iterations) / log (2), $salt_buf, $hash_buf);
5091 }
5092 elsif ($mode == 6800)
5093 {
5094 my $variant = $additional_param;
5095
5096 if (! defined ($variant))
5097 {
5098 $variant = int (rand (2));
5099 }
5100
5101 my $iterations = 500;
5102
5103 if (length ($iter))
5104 {
5105 $iterations = int ($iter);
5106 }
5107
5108 my $iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
5109
5110 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256);
5111
5112 my $pbkdf2 = Crypt::PBKDF2->new (
5113 hasher => $hasher,
5114 iterations => $iterations,
5115 output_len => 32
5116 );
5117
5118 my $key = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
5119
5120 my $cipher = Crypt::CBC->new ({
5121 key => $key,
5122 cipher => "Crypt::Rijndael",
5123 iv => $iv,
5124 literal_key => 1,
5125 header => "none",
5126 keysize => 32
5127 });
5128
5129 if ($variant == 1)
5130 {
5131 my $encrypt = $cipher->encrypt (substr ($salt_buf, 0, 16));
5132
5133 $hash_buf = substr (unpack ("H*", $encrypt), 0, 32);
5134 }
5135 else
5136 {
5137 my $verifier = "lastpass rocks\x02\x02";
5138
5139 $hash_buf = unpack ("H*", substr ($cipher->encrypt ($verifier), 0, 16));
5140 }
5141
5142 $tmp_hash = sprintf ("%s:%i:%s", $hash_buf, $iterations, $salt_buf);
5143 }
5144 elsif ($mode == 6900)
5145 {
5146 $hash_buf = gost_hex ($word_buf);
5147
5148 $tmp_hash = sprintf ("%s", $hash_buf);
5149 }
5150 elsif ($mode == 7100)
5151 {
5152 my $iterations = 1024;
5153
5154 if (length ($iter))
5155 {
5156 $iterations = int ($iter);
5157 }
5158
5159 my $pbkdf2 = Crypt::PBKDF2->new
5160 (
5161 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
5162 iterations => $iterations
5163 );
5164
5165 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 (pack ("H*", $salt_buf), $word_buf));
5166
5167 $tmp_hash = sprintf ("\$ml\$%i\$%s\$%0128s", $iterations, $salt_buf, $hash_buf);
5168 }
5169 elsif ($mode == 7200)
5170 {
5171 my $iterations = 1024;
5172
5173 if (length ($iter))
5174 {
5175 $iterations = int ($iter);
5176 }
5177
5178 my $pbkdf2 = Crypt::PBKDF2->new (
5179 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
5180 iterations => $iterations
5181 );
5182
5183 $hash_buf = unpack ("H*", $pbkdf2->PBKDF2 (pack ("H*", $salt_buf), $word_buf));
5184
5185 $tmp_hash = sprintf ("grub.pbkdf2.sha512.%i.%s.%0128s", $iterations, $salt_buf, $hash_buf);
5186 }
5187 elsif ($mode == 7300)
5188 {
5189 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha1);
5190
5191 $tmp_hash = sprintf ("%s:%s", unpack ("H*", $salt_buf), $hash_buf);
5192 }
5193 elsif ($mode == 7400)
5194 {
5195 my $iterations = 5000;
5196
5197 if (defined ($iter))
5198 {
5199 if ($iter > 0)
5200 {
5201 $iterations = int ($iter);
5202 }
5203 }
5204
5205 $hash_buf = sha256_crypt ($iterations, $word_buf, $salt_buf);
5206
5207 $tmp_hash = sprintf ("%s", $hash_buf);
5208 }
5209 elsif ($mode == 7500)
5210 {
5211 my @salt_arr = split ("\\\$", $salt_buf);
5212
5213 my $user = $salt_arr[0];
5214
5215 my $realm = $salt_arr[1];
5216
5217 my $salt = $salt_arr[2];
5218
5219 my $hmac_salt = $salt_arr[3];
5220 my $hmac_salt_bin = pack ("H*", $hmac_salt);
5221
5222 my $clear_data = $salt_arr[4];
5223
5224 my $k = md4 (encode ("UTF-16LE", $word_buf));
5225
5226 my $k1 = hmac_md5 ("\x01\x00\x00\x00", $k);
5227
5228 my $k3 = hmac_md5 ($hmac_salt_bin, $k1);
5229
5230 if (length ($clear_data) > 1)
5231 {
5232 my $clear_data_bin = pack ("H*", $clear_data);
5233
5234 $hash_buf = RC4 ($k3, $clear_data_bin);
5235 }
5236 else
5237 {
5238 my $hash = $salt_arr[5];
5239
5240 my $hash_bin = pack ("H*", $hash);
5241
5242 my $clear_data = RC4 ($k3, $hash_bin);
5243
5244 my $timestamp = substr ($clear_data, 14, 14);
5245
5246 my $is_numeric = 1;
5247 my $num;
5248
5249 if ($timestamp !~ /^[[:digit:]]{14}$/)
5250 {
5251 $is_numeric = 0;
5252 }
5253
5254 if (! $is_numeric)
5255 {
5256 $hash_buf = "\x00" x 36;
5257
5258 if ($hash_buf eq $hash_bin)
5259 {
5260 $hash_buf = "\x01" x 36;
5261 }
5262 }
5263 else
5264 {
5265 $hash_buf = $hash_bin;
5266 }
5267 }
5268
5269 $tmp_hash = sprintf ("\$krb5pa\$23\$%s\$%s\$%s\$%s%s", $user, $realm, $salt, unpack ("H*", $hash_buf), $hmac_salt);
5270 }
5271 elsif ($mode == 7600)
5272 {
5273 $hash_buf = sha1_hex ($salt_buf . sha1_hex ($word_buf));
5274
5275 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
5276 }
5277 elsif ($mode == 7700)
5278 {
5279 $word_buf = uc $word_buf;
5280 $salt_buf = uc $salt_buf;
5281
5282 my $word_buf_t = sapb_transcode ($word_buf);
5283 my $salt_buf_t = sapb_transcode ($salt_buf);
5284
5285 my $digest1 = md5 ($word_buf_t . $salt_buf_t);
5286
5287 my $data = sapb_waldorf ($digest1, $word_buf_t, $salt_buf_t);
5288
5289 my $digest2 = md5 ($data);
5290
5291 my ($a, $b, $c, $d) = unpack ("N4", $digest2);
5292
5293 $a ^= $c;
5294 $b ^= $d;
5295
5296 $tmp_hash = sprintf ("%s\$%08X%08X", $salt_buf, $a, $b);
5297 }
5298 elsif ($mode == 7800)
5299 {
5300 my $theMagicArray_s =
5301 "\x91\xac\x51\x14\x9f\x67\x54\x43\x24\xe7\x3b\xe0\x28\x74\x7b\xc2" .
5302 "\x86\x33\x13\xeb\x5a\x4f\xcb\x5c\x08\x0a\x73\x37\x0e\x5d\x1c\x2f" .
5303 "\x33\x8f\xe6\xe5\xf8\x9b\xae\xdd\x16\xf2\x4b\x8d\x2c\xe1\xd4\xdc" .
5304 "\xb0\xcb\xdf\x9d\xd4\x70\x6d\x17\xf9\x4d\x42\x3f\x9b\x1b\x11\x94" .
5305 "\x9f\x5b\xc1\x9b\x06\x05\x9d\x03\x9d\x5e\x13\x8a\x1e\x9a\x6a\xe8" .
5306 "\xd9\x7c\x14\x17\x58\xc7\x2a\xf6\xa1\x99\x63\x0a\xd7\xfd\x70\xc3" .
5307 "\xf6\x5e\x74\x13\x03\xc9\x0b\x04\x26\x98\xf7\x26\x8a\x92\x93\x25" .
5308 "\xb0\xa2\x0d\x23\xed\x63\x79\x6d\x13\x32\xfa\x3c\x35\x02\x9a\xa3" .
5309 "\xb3\xdd\x8e\x0a\x24\xbf\x51\xc3\x7c\xcd\x55\x9f\x37\xaf\x94\x4c" .
5310 "\x29\x08\x52\x82\xb2\x3b\x4e\x37\x9f\x17\x07\x91\x11\x3b\xfd\xcd";
5311
5312 $salt_buf = uc $salt_buf;
5313
5314 my $digest = sha1 ($word_buf . $salt_buf);
5315
5316 my ($a, $b, $c, $d, $e) = unpack ("I*", $digest);
5317
5318 my $lengthMagicArray = 0x20;
5319 my $offsetMagicArray = 0;
5320
5321 $lengthMagicArray += (($a >> 0) & 0xff) % 6;
5322 $lengthMagicArray += (($a >> 8) & 0xff) % 6;
5323 $lengthMagicArray += (($a >> 16) & 0xff) % 6;
5324 $lengthMagicArray += (($a >> 24) & 0xff) % 6;
5325 $lengthMagicArray += (($b >> 0) & 0xff) % 6;
5326 $lengthMagicArray += (($b >> 8) & 0xff) % 6;
5327 $lengthMagicArray += (($b >> 16) & 0xff) % 6;
5328 $lengthMagicArray += (($b >> 24) & 0xff) % 6;
5329 $lengthMagicArray += (($c >> 0) & 0xff) % 6;
5330 $lengthMagicArray += (($c >> 8) & 0xff) % 6;
5331 $offsetMagicArray += (($c >> 16) & 0xff) % 8;
5332 $offsetMagicArray += (($c >> 24) & 0xff) % 8;
5333 $offsetMagicArray += (($d >> 0) & 0xff) % 8;
5334 $offsetMagicArray += (($d >> 8) & 0xff) % 8;
5335 $offsetMagicArray += (($d >> 16) & 0xff) % 8;
5336 $offsetMagicArray += (($d >> 24) & 0xff) % 8;
5337 $offsetMagicArray += (($e >> 0) & 0xff) % 8;
5338 $offsetMagicArray += (($e >> 8) & 0xff) % 8;
5339 $offsetMagicArray += (($e >> 16) & 0xff) % 8;
5340 $offsetMagicArray += (($e >> 24) & 0xff) % 8;
5341
5342 my $hash_buf = sha1_hex ($word_buf . substr ($theMagicArray_s, $offsetMagicArray, $lengthMagicArray) . $salt_buf);
5343
5344 $tmp_hash = sprintf ("%s\$%s", $salt_buf, uc $hash_buf);
5345 }
5346 elsif ($mode == 7900)
5347 {
5348 my $cost = 14;
5349
5350 if (length ($iter))
5351 {
5352 $cost = $iter;
5353 }
5354
5355 my $phpass_it = 1 << $cost;
5356
5357 $hash_buf = sha512 ($salt_buf . $word_buf);
5358
5359 for (my $i = 0; $i < $phpass_it; $i++)
5360 {
5361 $hash_buf = sha512 ($hash_buf . $word_buf);
5362 }
5363
5364 my $base64_buf = substr (Authen::Passphrase::PHPass::_en_base64 ($hash_buf), 0, 43);
5365
5366 my $base64_digits = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
5367
5368 my $cost_str = substr ($base64_digits , $cost, 1);
5369
5370 $tmp_hash = sprintf ('$S$%s%s%s', $cost_str, $salt_buf, $base64_buf);
5371 }
5372 elsif ($mode == 8000)
5373 {
5374 my $salt_buf_bin = pack ("H*", $salt_buf);
5375
5376 my $word_buf_utf = encode ("UTF-16BE", $word_buf);
5377
5378 $hash_buf = sha256_hex ($word_buf_utf . "\x00" x (510 - (length ($word_buf) * 2)) . $salt_buf_bin);
5379
5380 $tmp_hash = sprintf ("0xc007%s%s", $salt_buf, $hash_buf);
5381 }
5382 elsif ($mode == 8100)
5383 {
5384 $hash_buf = sha1_hex ($salt_buf . $word_buf . "\x00");
5385
5386 $tmp_hash = sprintf ("1%s%s", $salt_buf, $hash_buf);
5387 }
5388 elsif ($mode == 8200)
5389 {
5390 my $iterations = 40000;
5391
5392 if (defined ($iter))
5393 {
5394 $iterations = $iter;
5395 }
5396
5397 my $salt_hex = substr ($salt_buf, 0, 32);
5398 my $salt = pack ("H*", $salt_hex);
5399
5400 my $data_hex = substr ($salt_buf, 32);
5401 my $data = pack ("H*", $data_hex);
5402
5403 my $pbkdf2 = Crypt::PBKDF2->new
5404 (
5405 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
5406 iterations => int $iterations
5407 );
5408
5409 my $key = $pbkdf2->PBKDF2 ($salt, $word_buf);
5410
5411 $hash_buf = hmac_hex ($data, substr ($key, 32, 32), \&sha256, 64);
5412
5413 $tmp_hash = sprintf ("%s:%s:%d:%s", $hash_buf, $salt_hex, $iterations, $data_hex);
5414 }
5415 elsif ($mode == 8300)
5416 {
5417 my ($domain, $salt_hex) = split (":", $salt_buf);
5418
5419 my $hashalg = Net::DNS::SEC->digtype ("SHA1");
5420
5421 my $salt = pack ("H*", $salt_hex);
5422
5423 my $iterations = 1;
5424
5425 if (defined ($iter))
5426 {
5427 $iterations = $iter;
5428 }
5429
5430 my $name = lc ($word_buf . $domain);
5431
5432 my $hash_buf = Net::DNS::RR::NSEC3::name2hash ($hashalg, $name, $iterations, $salt);
5433
5434 $tmp_hash = sprintf ("%s:%s:%s:%d", $hash_buf, $domain, $salt_hex, $iterations);
5435 }
5436 elsif ($mode == 8400)
5437 {
5438 $hash_buf = sha1_hex ($salt_buf . sha1_hex ($salt_buf . sha1_hex ($word_buf)));
5439
5440 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
5441 }
5442 elsif ($mode == 8500)
5443 {
5444 $hash_buf = racf_hash (uc $salt_buf, $word_buf);
5445
5446 $tmp_hash = sprintf ('$racf$*%s*%s', uc $salt_buf, uc $hash_buf);
5447 }
5448 elsif ($mode == 8600)
5449 {
5450 my @saved_key = map { ord $_; } split "", $word_buf;
5451
5452 my $len = scalar @saved_key;
5453
5454 my @state = domino_big_md (\@saved_key, $len);
5455
5456 $tmp_hash = sprintf ('%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x',
5457 $state[ 0],
5458 $state[ 1],
5459 $state[ 2],
5460 $state[ 3],
5461 $state[ 4],
5462 $state[ 5],
5463 $state[ 6],
5464 $state[ 7],
5465 $state[ 8],
5466 $state[ 9],
5467 $state[10],
5468 $state[11],
5469 $state[12],
5470 $state[13],
5471 $state[14],
5472 $state[15],
5473 );
5474 }
5475 elsif ($mode == 8700)
5476 {
5477 my $domino_char = undef;
5478
5479 if (defined ($additional_param))
5480 {
5481 $domino_char = $additional_param;
5482 }
5483
5484 my @saved_key = map { ord $_; } split "", $word_buf;
5485
5486 my $len = scalar @saved_key;
5487
5488 my @state = domino_big_md (\@saved_key, $len);
5489
5490 my $str = "(" . unpack ("H*", join ("", (map { chr $_; } @state))) . ")";
5491
5492 @saved_key = map { ord $_; } split "", $salt_buf . uc $str;
5493
5494 @state = domino_big_md (\@saved_key, 34);
5495
5496 $hash_buf = join ("", (map { chr $_; } @state));
5497
5498 $tmp_hash = sprintf ('(G%s)', domino_encode ($salt_buf . $hash_buf, $domino_char));
5499 }
5500 elsif ($mode == 8900)
5501 {
5502 my $N = 1024;
5503 my $r = 1;
5504 my $p = 1;
5505
5506 if (defined ($additional_param))
5507 {
5508 $N = $additional_param;
5509 $r = $additional_param2;
5510 $p = $additional_param3;
5511 }
5512
5513 $hash_buf = scrypt_hash ($word_buf, $salt_buf, $N, $r, $p, 32);
5514
5515 $tmp_hash = sprintf ('%s', $hash_buf);
5516 }
5517 elsif ($mode == 9100)
5518 {
5519 my $iterations = 5000;
5520
5521 if (defined ($iter))
5522 {
5523 $iterations = $iter;
5524 }
5525
5526 my $domino_char = undef;
5527
5528 # domino 5 hash - SEC_pwddigest_V1 - -m 8600
5529
5530 my @saved_key = map { ord $_; } split "", $word_buf;
5531
5532 my $len = scalar @saved_key;
5533
5534 my @state = domino_big_md (\@saved_key, $len);
5535
5536
5537 # domino 6 hash - SEC_pwddigest_V2 - -m 8700
5538
5539 my $salt_part = substr ($salt_buf, 0, 5);
5540
5541 my $str = "(" . unpack ("H*", join ("", (map { chr $_; } @state))) . ")";
5542
5543 @saved_key = map { ord $_; } split "", $salt_part . uc $str;
5544
5545 @state = domino_big_md (\@saved_key, 34);
5546
5547 $hash_buf = join ("", (map { chr $_; } @state));
5548
5549 $tmp_hash = sprintf ('(G%s)', domino_encode ($salt_part . $hash_buf, $domino_char));
5550
5551
5552 # domino 8(.5.x) hash - SEC_pwddigest_V3 - -m 9100
5553
5554 my $pbkdf2 = Crypt::PBKDF2->new
5555 (
5556 hash_class => 'HMACSHA1',
5557 iterations => $iterations,
5558 output_len => 8,
5559 salt_len => 16,
5560 );
5561
5562 my $chars = "02";
5563
5564 if (defined ($additional_param))
5565 {
5566 $chars = $additional_param;
5567 }
5568
5569 my $digest_new = $pbkdf2->PBKDF2 ($salt_buf, $tmp_hash);
5570
5571 my $iteration_str = "" . $iterations;
5572
5573 for (my $i = length ($iterations); $i < 10; $i++)
5574 {
5575 $iterations = "0" . $iterations;
5576 }
5577
5578 $tmp_hash = sprintf ('(H%s)', domino_85x_encode ($salt_buf . $iterations . $chars . $digest_new, $domino_char));
5579 }
5580 elsif ($mode == 9200)
5581 {
5582 my $iterations = 20000;
5583
5584 my $pbkdf2 = Crypt::PBKDF2->new
5585 (
5586 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
5587 iterations => $iterations
5588 );
5589
5590 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
5591
5592 $tmp_hash = "";
5593
5594 for (my $i = 0; $i < 43; $i++)
5595 {
5596 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($hash_buf, $i, 1)};
5597 }
5598
5599 $tmp_hash = sprintf ("\$8\$%s\$%s", $salt_buf, $tmp_hash);
5600 }
5601 elsif ($mode == 9300)
5602 {
5603 my $N = 16384;
5604 my $r = 1;
5605 my $p = 1;
5606
5607 $hash_buf = scrypt_b64 ($word_buf, $salt_buf, $N, $r, $p, 32);
5608
5609 $tmp_hash = "";
5610
5611 for (my $i = 0; $i < 43; $i++)
5612 {
5613 $tmp_hash .= $CISCO_BASE64_MAPPING->{substr ($hash_buf, $i, 1)};
5614 }
5615
5616 $tmp_hash = sprintf ('$9$%s$%s', $salt_buf, $tmp_hash);
5617 }
5618 elsif ($mode == 9400)
5619 {
5620 my $iterations = 50000;
5621
5622 if (length ($iter))
5623 {
5624 $iterations = int ($iter);
5625 }
5626
5627 my $aes_key_size = 128; # or 256
5628
5629 if (defined ($additional_param2))
5630 {
5631 $aes_key_size = $additional_param2;
5632 }
5633
5634 $salt_buf = pack ("H*", $salt_buf);
5635
5636 my $tmp = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
5637
5638 for (my $i = 0; $i < $iterations; $i++)
5639 {
5640 my $num32 = pack ("L", $i);
5641
5642 $tmp = sha1 ($num32 . $tmp);
5643 }
5644
5645 my $zero32 = pack ("L", 0x00);
5646
5647 my $derivation_array1 = pack ("C", 0x36) x 64;
5648 my $derivation_array2 = pack ("C", 0x5C) x 64;
5649
5650 $tmp = sha1 ($tmp . $zero32);
5651
5652 my $tmp2 = sha1 ($derivation_array1 ^ $tmp);
5653 my $tmp3 = sha1 ($derivation_array2 ^ $tmp);
5654
5655 my $key = substr ($tmp2 . $tmp3, 0, $aes_key_size / 8);
5656
5657 my $m = Crypt::Mode::ECB->new ('AES', 0);
5658
5659 my $encdata;
5660
5661 if (defined $additional_param)
5662 {
5663 $encdata = $m->decrypt (pack ("H*", $additional_param), $key);
5664 }
5665 else
5666 {
5667 $encdata = "A" x 16; ## can be anything
5668 }
5669
5670 my $data1_buf = $encdata;
5671 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5672
5673 $data1_buf = substr ($data1_buf . ("\x00" x 16), 0, 16);
5674 $data2_buf = substr ($data2_buf . ("\x00" x 16), 0, 32);
5675
5676 my $encrypted1 = unpack ("H*", $m->encrypt ($data1_buf, $key));
5677 my $encrypted2 = unpack ("H*", $m->encrypt ($data2_buf, $key));
5678
5679 $encrypted1 = substr ($encrypted1, 0, 32);
5680 $encrypted2 = substr ($encrypted2, 0, 40);
5681
5682 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2007, 20, $aes_key_size, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5683 }
5684 elsif ($mode == 9500)
5685 {
5686 my $iterations = 100000;
5687
5688 if (length ($iter))
5689 {
5690 $iterations = int ($iter);
5691 }
5692
5693 $salt_buf = pack ("H*", $salt_buf);
5694
5695 my $tmp = sha1 ($salt_buf . encode ("UTF-16LE", $word_buf));
5696
5697 for (my $i = 0; $i < $iterations; $i++)
5698 {
5699 my $num32 = pack ("L", $i);
5700
5701 $tmp = sha1 ($num32 . $tmp);
5702 }
5703
5704 my $encryptedVerifierHashInputBlockKey = "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79";
5705 my $encryptedVerifierHashValueBlockKey = "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e";
5706
5707 my $final1 = sha1 ($tmp . $encryptedVerifierHashInputBlockKey);
5708 my $final2 = sha1 ($tmp . $encryptedVerifierHashValueBlockKey);
5709
5710 my $key1 = substr ($final1, 0, 16);
5711 my $key2 = substr ($final2, 0, 16);
5712
5713 my $cipher1 = Crypt::CBC->new ({
5714 key => $key1,
5715 cipher => "Crypt::Rijndael",
5716 iv => $salt_buf,
5717 literal_key => 1,
5718 header => "none",
5719 keysize => 16,
5720 padding => "null",
5721 });
5722
5723 my $cipher2 = Crypt::CBC->new ({
5724 key => $key2,
5725 cipher => "Crypt::Rijndael",
5726 iv => $salt_buf,
5727 literal_key => 1,
5728 header => "none",
5729 keysize => 16,
5730 padding => "null",
5731 });
5732
5733 my $encdata;
5734
5735 if (defined $additional_param)
5736 {
5737 $encdata = $cipher1->decrypt (pack ("H*", $additional_param));
5738 }
5739 else
5740 {
5741 $encdata = "A" x 16; ## can be anything
5742 }
5743
5744 my $data1_buf = $encdata;
5745 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5746
5747 my $encrypted1 = unpack ("H*", $cipher1->encrypt ($data1_buf));
5748 my $encrypted2 = unpack ("H*", $cipher2->encrypt ($data2_buf));
5749
5750 $encrypted2 = substr ($encrypted2, 0, 64);
5751
5752 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2010, 100000, 128, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5753 }
5754 elsif ($mode == 9600)
5755 {
5756 my $iterations = 100000;
5757
5758 if (length ($iter))
5759 {
5760 $iterations = int ($iter);
5761 }
5762
5763 $salt_buf = pack ("H*", $salt_buf);
5764
5765 my $tmp = sha512 ($salt_buf . encode ("UTF-16LE", $word_buf));
5766
5767 for (my $i = 0; $i < $iterations; $i++)
5768 {
5769 my $num32 = pack ("L", $i);
5770
5771 $tmp = sha512 ($num32 . $tmp);
5772 }
5773
5774 my $encryptedVerifierHashInputBlockKey = "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79";
5775 my $encryptedVerifierHashValueBlockKey = "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e";
5776
5777 my $final1 = sha512 ($tmp . $encryptedVerifierHashInputBlockKey);
5778 my $final2 = sha512 ($tmp . $encryptedVerifierHashValueBlockKey);
5779
5780 my $key1 = substr ($final1, 0, 32);
5781 my $key2 = substr ($final2, 0, 32);
5782
5783 my $cipher1 = Crypt::CBC->new ({
5784 key => $key1,
5785 cipher => "Crypt::Rijndael",
5786 iv => $salt_buf,
5787 literal_key => 1,
5788 header => "none",
5789 keysize => 32,
5790 padding => "null",
5791 });
5792
5793 my $cipher2 = Crypt::CBC->new ({
5794 key => $key2,
5795 cipher => "Crypt::Rijndael",
5796 iv => $salt_buf,
5797 literal_key => 1,
5798 header => "none",
5799 keysize => 32,
5800 padding => "null",
5801 });
5802
5803 my $encdata;
5804
5805 if (defined $additional_param)
5806 {
5807 $encdata = $cipher1->decrypt (pack ("H*", $additional_param));
5808 }
5809 else
5810 {
5811 $encdata = "A" x 16; ## can be anything
5812 }
5813
5814 my $data1_buf = $encdata;
5815 my $data2_buf = sha512 (substr ($data1_buf, 0, 16));
5816
5817 my $encrypted1 = unpack ("H*", $cipher1->encrypt ($data1_buf));
5818 my $encrypted2 = unpack ("H*", $cipher2->encrypt ($data2_buf));
5819
5820 $encrypted2 = substr ($encrypted2, 0, 64);
5821
5822 $tmp_hash = sprintf ("\$office\$*%d*%d*%d*%d*%s*%s*%s", 2013, 100000, 256, 16, unpack ("H*", $salt_buf), $encrypted1, $encrypted2);
5823 }
5824 elsif ($mode == 9700)
5825 {
5826 $salt_buf = pack ("H*", $salt_buf);
5827
5828 my $tmp = md5 (encode ("UTF-16LE", $word_buf));
5829
5830 $tmp = substr ($tmp, 0, 5);
5831
5832 my $data;
5833
5834 for (my $i = 0; $i < 16; $i++)
5835 {
5836 $data .= $tmp;
5837 $data .= $salt_buf;
5838 }
5839
5840 $tmp = md5 ($data);
5841
5842 $tmp = substr ($tmp, 0, 5);
5843
5844 my $version;
5845
5846 if (defined $additional_param2)
5847 {
5848 $version = $additional_param2;
5849 }
5850 else
5851 {
5852 $version = (unpack ("L", $tmp) & 1) ? 0 : 1;
5853 }
5854
5855 my $rc4_key = md5 ($tmp . "\x00\x00\x00\x00");
5856
5857 my $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5858
5859 my $encdata;
5860
5861 if (defined $additional_param)
5862 {
5863 $encdata = $m->RC4 (pack ("H*", $additional_param));
5864 }
5865 else
5866 {
5867 $encdata = "A" x 16; ## can be anything
5868 }
5869
5870 my $data1_buf = $encdata;
5871 my $data2_buf = md5 (substr ($data1_buf, 0, 16));
5872
5873 $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5874
5875 my $encrypted1 = $m->RC4 ($data1_buf);
5876 my $encrypted2 = $m->RC4 ($data2_buf);
5877
5878 $tmp_hash = sprintf ("\$oldoffice\$%d*%s*%s*%s", $version, unpack ("H*", $salt_buf), unpack ("H*", $encrypted1), unpack ("H*", $encrypted2));
5879 }
5880 elsif ($mode == 9800)
5881 {
5882 $salt_buf = pack ("H*", $salt_buf);
5883
5884 my $tmp = sha1 ($salt_buf. encode ("UTF-16LE", $word_buf));
5885
5886 my $version;
5887
5888 if (defined $additional_param2)
5889 {
5890 $version = $additional_param2;
5891 }
5892 else
5893 {
5894 $version = (unpack ("L", $tmp) & 1) ? 3 : 4;
5895 }
5896
5897 my $rc4_key = sha1 ($tmp . "\x00\x00\x00\x00");
5898
5899 if ($version == 3)
5900 {
5901 $rc4_key = substr ($rc4_key, 0, 5) . "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
5902 }
5903
5904 my $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5905
5906 my $encdata;
5907
5908 if (defined $additional_param)
5909 {
5910 $encdata = $m->RC4 (pack ("H*", $additional_param));
5911 }
5912 else
5913 {
5914 $encdata = "A" x 16; ## can be anything
5915 }
5916
5917 my $data1_buf = $encdata;
5918 my $data2_buf = sha1 (substr ($data1_buf, 0, 16));
5919
5920 $m = Crypt::RC4->new (substr ($rc4_key, 0, 16));
5921
5922 my $encrypted1 = $m->RC4 ($data1_buf);
5923 my $encrypted2 = $m->RC4 ($data2_buf);
5924
5925 $tmp_hash = sprintf ("\$oldoffice\$%d*%s*%s*%s", $version, unpack ("H*", $salt_buf), unpack ("H*", $encrypted1), unpack ("H*", $encrypted2));
5926 }
5927 elsif ($mode == 9900)
5928 {
5929 $tmp_hash = sprintf ("%s", md5_hex ($word_buf . "\0" x (100 - length ($word_buf))));
5930 }
5931 elsif ($mode == 10000)
5932 {
5933 my $iterations = 10000;
5934
5935 if (length ($iter))
5936 {
5937 $iterations = int ($iter);
5938 }
5939
5940 my $pbkdf2 = Crypt::PBKDF2->new
5941 (
5942 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
5943 iterations => $iterations
5944 );
5945
5946 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
5947 $hash_buf =~ s/[\r\n]//g;
5948
5949 $tmp_hash = sprintf ("pbkdf2_sha256\$%i\$%s\$%s", $iterations, $salt_buf, $hash_buf);
5950 }
5951 elsif ($mode == 10100)
5952 {
5953 my $seed = pack ("H*", $salt_buf);
5954
5955 my ($hi, $lo) = siphash ($word_buf, $seed);
5956
5957 my $hi_s = sprintf ("%08x", $hi);
5958 my $lo_s = sprintf ("%08x", $lo);
5959
5960 $hi_s =~ s/^(..)(..)(..)(..)$/$4$3$2$1/;
5961 $lo_s =~ s/^(..)(..)(..)(..)$/$4$3$2$1/;
5962
5963 $tmp_hash = sprintf ("%s%s:2:4:%s", $hi_s, $lo_s, $salt_buf);
5964 }
5965 elsif ($mode == 10200)
5966 {
5967 my $challengeb64 = encode_base64 ($salt_buf);
5968 $challengeb64 =~ s/[\r\n]//g;
5969
5970 my $username;
5971
5972 if (defined $additional_param)
5973 {
5974 $username = $additional_param;
5975 }
5976 else
5977 {
5978 $username = "user";
5979 }
5980
5981 $hash_buf = hmac_hex ($salt_buf, $word_buf, \&md5);
5982
5983 my $responseb64 = encode_base64 ($username . " " . $hash_buf);
5984 $responseb64 =~ s/[\r\n]//g;
5985
5986 $tmp_hash = sprintf ('$cram_md5$%s$%s', $challengeb64, $responseb64);
5987 }
5988 elsif ($mode == 10300)
5989 {
5990 my $iterations = 1024;
5991
5992 if (length ($iter))
5993 {
5994 $iterations = int ($iter);
5995 }
5996
5997 my $hash_buf = $salt_buf;
5998
5999 for (my $pos = 0; $pos < $iterations; $pos++)
6000 {
6001 $hash_buf = sha1 ($word_buf . $hash_buf);
6002 }
6003
6004 $hash_buf = encode_base64 ($hash_buf . $salt_buf);
6005 $hash_buf =~ s/[\r\n]//g;
6006
6007 $tmp_hash = sprintf ("{x-issha, %i}%s", $iterations, $hash_buf);
6008 }
6009 elsif ($mode == 10400)
6010 {
6011 my $id = $salt_buf;
6012 my $u = $additional_param;
6013 my $o = $additional_param2;
6014 my $P = $additional_param3;
6015
6016 if (defined $u == 0)
6017 {
6018 $u = "0" x 64;
6019 }
6020
6021 if (defined $o == 0)
6022 {
6023 $o = "0" x 64;
6024 }
6025
6026 if (defined $P == 0)
6027 {
6028 $P = -1;
6029 }
6030
6031 my $padding;
6032
6033 for (my $i = 0; $i < 32; $i++)
6034 {
6035 $padding .= pack ("C", $pdf_padding[$i]);
6036 }
6037
6038 my $res = pdf_compute_encryption_key ($word_buf, $padding, $id, $u, $o, $P, 1, 2, 0);
6039
6040 my $m = Crypt::RC4->new (substr ($res, 0, 5));
6041
6042 $u = $m->RC4 ($padding);
6043
6044 $tmp_hash = sprintf ('$pdf$%d*%d*40*%d*%d*16*%s*32*%s*32*%s', 1, 2, $P, 0, $id, unpack ("H*", $u), $o);
6045 }
6046 elsif ($mode == 10500)
6047 {
6048 my $id = $salt_buf;
6049 my $u = $additional_param;
6050 my $o = $additional_param2;
6051 my $P = $additional_param3;
6052 my $V = $additional_param4;
6053 my $R = $additional_param5;
6054 my $enc = $additional_param6;
6055
6056 if (defined $u == 0)
6057 {
6058 $u = "0" x 64;
6059 }
6060
6061 my $u_save = $u;
6062
6063 if (defined $o == 0)
6064 {
6065 $o = "0" x 64;
6066 }
6067
6068 if (defined $R == 0)
6069 {
6070 $R = get_random_num (3, 5);
6071 }
6072
6073 if (defined $V == 0)
6074 {
6075 $V = ($R == 3) ? 2 : 4;
6076 }
6077
6078 if (defined $P == 0)
6079 {
6080 $P = ($R == 3) ? -4 : -1028;
6081 }
6082
6083 if (defined $enc == 0)
6084 {
6085 $enc = ($R == 3) ? 1 : get_random_num (0, 2);
6086 }
6087
6088 my $padding;
6089
6090 for (my $i = 0; $i < 32; $i++)
6091 {
6092 $padding .= pack ("C", $pdf_padding[$i]);
6093 }
6094
6095 my $res = pdf_compute_encryption_key ($word_buf, $padding, $id, $u, $o, $P, $V, $R, $enc);
6096
6097 my $digest = md5 ($padding . pack ("H*", $id));
6098
6099 my $m = Crypt::RC4->new ($res);
6100
6101 $u = $m->RC4 ($digest);
6102
6103 my @ress = split "", $res;
6104
6105 for (my $x = 1; $x <= 19; $x++)
6106 {
6107 my @xor;
6108
6109 for (my $i = 0; $i < 16; $i++)
6110 {
6111 $xor[$i] = chr (ord ($ress[$i]) ^ $x);
6112 }
6113
6114 my $s = join ("", @xor);
6115
6116 my $m2 = Crypt::RC4->new ($s);
6117
6118 $u = $m2->RC4 ($u);
6119 }
6120
6121 $u .= substr (pack ("H*", $u_save), 16, 16);
6122
6123 $tmp_hash = sprintf ('$pdf$%d*%d*128*%d*%d*16*%s*32*%s*32*%s', $V, $R, $P, $enc, $id, unpack ("H*", $u), $o);
6124 }
6125 elsif ($mode == 10600)
6126 {
6127 my $id = $salt_buf;
6128 my $rest = $additional_param;
6129
6130 if (defined $id == 0)
6131 {
6132 $id = "0" x 32;
6133 }
6134
6135 if (defined $rest == 0)
6136 {
6137 $rest = "127*";
6138 $rest .= "0" x 64;
6139 $rest .= $id;
6140 $rest .= "0" x 158;
6141 $rest .= "*127*00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000";
6142 }
6143
6144 my @data = split /\*/, $rest;
6145
6146 my $u = pack ("H*", $data[1]);
6147
6148 my $h = sha256 ($word_buf . substr ($u, 32, 8));
6149
6150 $data[1] = unpack ("H*", $h . substr ($u, 32));
6151
6152 $rest = join ("*", @data);
6153
6154 $tmp_hash = sprintf ('$pdf$5*5*256*-1028*1*16*%s*%s', $id, $rest);
6155 }
6156 elsif ($mode == 10700)
6157 {
6158 my $id = $salt_buf;
6159 my $rest = $additional_param;
6160
6161 if (defined $id == 0)
6162 {
6163 $id = "0" x 32;
6164 }
6165
6166 if (defined $rest == 0)
6167 {
6168 $rest = "127*";
6169 $rest .= "0" x 64;
6170 $rest .= $id;
6171 $rest .= "0" x 158;
6172 $rest .= "*127*00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000";
6173 }
6174
6175 my @datax = split /\*/, $rest;
6176
6177 my $u = pack ("H*", $datax[1]);
6178
6179 my $block = sha256 ($word_buf . substr ($u, 32, 8));
6180
6181 my $block_size = 32;
6182
6183 my $data = 0x00 x 64;
6184
6185 my $data_len = 1;
6186
6187 my $data63 = 0;
6188
6189 for (my $i = 0; $i < 64 || $i < $data63 + 32; $i++)
6190 {
6191 $data = $word_buf . $block;
6192
6193 $data_len = length ($data);
6194
6195 for (my $k = 1; $k < 64; $k++)
6196 {
6197 $data .= $word_buf . $block;
6198 }
6199
6200 my $aes = Crypt::CBC->new ({
6201 key => substr ($block, 0, 16),
6202 cipher => "Crypt::Rijndael",
6203 iv => substr ($block, 16, 16),
6204 literal_key => 1,
6205 header => "none",
6206 keysize => 16,
6207 padding => "null",
6208 });
6209
6210 my $data = $aes->encrypt ($data);
6211
6212 my $sum = 0;
6213
6214 for (my $j = 0; $j < 16; $j++)
6215 {
6216 $sum += ord (substr ($data, $j, 1));
6217 }
6218
6219 $block_size = 32 + ($sum % 3) * 16;
6220
6221 if ($block_size == 32)
6222 {
6223 $block = sha256 (substr ($data, 0, $data_len * 64));
6224 }
6225 elsif ($block_size == 48)
6226 {
6227 $block = sha384 (substr ($data, 0, $data_len * 64));
6228 }
6229 elsif ($block_size == 64)
6230 {
6231 $block = sha512 (substr ($data, 0, $data_len * 64));
6232 }
6233
6234 $data63 = ord (substr ($data, $data_len * 64 - 1, 1));
6235 }
6236
6237 $datax[1] = unpack ("H*", substr ($block, 0, 32) . substr ($u, 32));
6238
6239 $rest = join ("*", @datax);
6240
6241 $tmp_hash = sprintf ('$pdf$5*6*256*-1028*1*16*%s*%s', $id, $rest);
6242 }
6243 elsif ($mode == 10800)
6244 {
6245 $hash_buf = sha384_hex ($word_buf);
6246
6247 $tmp_hash = sprintf ("%s", $hash_buf);
6248 }
6249 elsif ($mode == 10900)
6250 {
6251 my $iterations = 1000;
6252
6253 if (length ($iter))
6254 {
6255 $iterations = int ($iter);
6256 }
6257
6258 my $out_len = 24;
6259
6260 if (defined $additional_param)
6261 {
6262 $out_len = $additional_param;
6263 }
6264
6265 my $pbkdf2 = Crypt::PBKDF2->new
6266 (
6267 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6268 iterations => $iterations,
6269 output_len => $out_len
6270 );
6271
6272 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6273 $hash_buf =~ s/[\r\n]//g;
6274
6275 my $base64_salt_buf = encode_base64 ($salt_buf);
6276
6277 chomp ($base64_salt_buf);
6278
6279 $tmp_hash = sprintf ("sha256:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6280 }
6281 elsif ($mode == 11000)
6282 {
6283 $hash_buf = md5_hex ($salt_buf . $word_buf);
6284
6285 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
6286 }
6287 elsif ($mode == 11100)
6288 {
6289 my $user = "postgres";
6290
6291 if (defined $additional_param)
6292 {
6293 $user = $additional_param;
6294 }
6295
6296 $hash_buf = md5_hex (md5_hex ($word_buf . $user) . pack ("H*", $salt_buf));
6297
6298 $tmp_hash = sprintf ("\$postgres\$%s*%s*%s", $user, $salt_buf, $hash_buf);
6299 }
6300 elsif ($mode == 11200)
6301 {
6302 my $sha1_pass = sha1 ($word_buf);
6303 my $double_sha1 = sha1 ($sha1_pass);
6304
6305 my $xor_part1 = $sha1_pass;
6306 my $xor_part2 = sha1 (pack ("H*", $salt_buf) . $double_sha1);
6307
6308 my $hash_buf = "";
6309
6310 for (my $i = 0; $i < 20; $i++)
6311 {
6312 my $first_byte = substr ($xor_part1, $i, 1);
6313 my $second_byte = substr ($xor_part2, $i, 1);
6314
6315 my $xor_result = $first_byte ^ $second_byte;
6316
6317 $hash_buf .= unpack ("H*", $xor_result);
6318 }
6319
6320 $tmp_hash = sprintf ("\$mysqlna\$%s*%s", $salt_buf, $hash_buf);
6321 }
6322 elsif ($mode == 11300)
6323 {
6324 my $ckey_buf = get_random_string (96);
6325
6326 if (length ($additional_param))
6327 {
6328 $ckey_buf = $additional_param;
6329 }
6330
6331 my $public_key_buf = get_random_string (66);
6332
6333 if (length ($additional_param2))
6334 {
6335 $public_key_buf = $additional_param2;
6336 }
6337
6338 my $salt_iter = get_random_num (150000, 250000);
6339
6340 if (length ($iter))
6341 {
6342 $salt_iter = int ($iter);
6343 }
6344
6345 my $hash_buf = sha512 ($word_buf . pack ("H*", $salt_buf));
6346
6347 for (my $i = 1; $i < $salt_iter; $i++)
6348 {
6349 $hash_buf = sha512 ($hash_buf);
6350 }
6351
6352 my $data = get_random_string (32);
6353
6354 my $aes = Crypt::CBC->new ({
6355 key => substr ($hash_buf, 0, 32),
6356 cipher => "Crypt::Rijndael",
6357 iv => substr ($hash_buf, 32, 16),
6358 literal_key => 1,
6359 header => "none",
6360 keysize => 32,
6361 padding => "standard",
6362 });
6363
6364 my $cry_master_buf = (unpack ("H*", $aes->encrypt ($data)));
6365
6366 $tmp_hash = sprintf ('$bitcoin$%d$%s$%d$%s$%d$%d$%s$%d$%s',
6367 length ($cry_master_buf),
6368 $cry_master_buf,
6369 length ($salt_buf),
6370 $salt_buf,
6371 $salt_iter,
6372 length ($ckey_buf),
6373 $ckey_buf,
6374 length ($public_key_buf),
6375 $public_key_buf);
6376 }
6377 elsif ($mode == 11400)
6378 {
6379 my ($directive, $URI_server, $URI_client, $user, $realm, $nonce, $nonce_count, $nonce_client, $qop, $method, $URI, $URI_prefix, $URI_resource, $URI_suffix);
6380
6381 $directive = "MD5"; # only directive currently supported
6382
6383 if (defined ($additional_param))
6384 {
6385 $user = $additional_param;
6386 $realm = $additional_param2;
6387 $nonce = $salt_buf;
6388 $nonce_count = $additional_param3;
6389 $nonce_client = $additional_param4;
6390 $qop = $additional_param5;
6391 $method = $additional_param6;
6392
6393 $URI_prefix = $additional_param7;
6394 $URI_resource = $additional_param8;
6395 $URI_suffix = $additional_param9;
6396
6397 # not needed information
6398
6399 $URI_server = $additional_param10;
6400 $URI_client = $additional_param11;
6401 }
6402 else
6403 {
6404 $user = get_random_string (get_random_num (0, 12 + 1));
6405
6406 # special limit: (user_len + 1 + realm_len + 1 + word_buf_len) < 56
6407 my $realm_max_len = 55 - length ($user) - 1 - length ($word_buf) - 1;
6408
6409 if ($realm_max_len < 1) # should never happen
6410 {
6411 $realm_max_len = 1;
6412 }
6413
6414 $realm_max_len = min (20, $realm_max_len);
6415
6416 $realm = get_random_string (get_random_num (0, $realm_max_len + 1));
6417
6418 $nonce = $salt_buf;
6419
6420 if (get_random_num (0, 1 + 1) == 1)
6421 {
6422 $qop = "auth";
6423
6424 $nonce_count = get_random_string (get_random_num (0, 10 + 1));
6425 $nonce_client = get_random_string (get_random_num (0, 12 + 1));
6426 }
6427 else
6428 {
6429 $qop = "";
6430
6431 $nonce_count = "";
6432 $nonce_client = "";
6433 }
6434
6435 $method = get_random_string (get_random_num (0, 24 + 1));
6436
6437 $URI_prefix = get_random_string (get_random_num (0, 10 + 1));
6438 $URI_resource = get_random_string (get_random_num (1, 32 + 1));
6439 $URI_suffix = get_random_string (get_random_num (0, 32 + 1));
6440
6441 # not needed information
6442
6443 $URI_server = get_random_string (get_random_num (0, 32 + 1));
6444 $URI_client = $URI_resource; # simplification
6445 }
6446
6447 # start
6448
6449 $URI = "";
6450
6451 if (length ($URI_prefix) > 0)
6452 {
6453 $URI = $URI_prefix . ":";
6454 }
6455
6456 $URI .= $URI_resource;
6457
6458 if (length ($URI_suffix) > 0)
6459 {
6460 $URI .= ":" . $URI_suffix;
6461 }
6462
6463 my $HA2 = md5_hex ($method . ":" . $URI);
6464
6465 my $HA1 = md5_hex ($user . ":" . $realm . ":" . $word_buf);
6466
6467 my $tmp_buf;
6468
6469 if (($qop eq "auth") || ($qop eq "auth-int"))
6470 {
6471 $tmp_buf = $nonce . ":" . $nonce_count . ":" . $nonce_client . ":" . $qop;
6472 }
6473 else
6474 {
6475 $tmp_buf = $nonce;
6476 }
6477
6478 my $hash_buf = md5_hex ($HA1 . ":" . $tmp_buf . ":" . $HA2);
6479
6480 $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);
6481 }
6482 elsif ($mode == 11500)
6483 {
6484 $hash_buf = crc32 ($word_buf);
6485
6486 $tmp_hash = sprintf ("%08x:00000000", $hash_buf);
6487 }
6488 elsif ($mode == 11600)
6489 {
6490 my ($p, $num_cycle_power, $seven_zip_salt_len, $seven_zip_salt_buf, $salt_len, $data_len, $unpack_size, $data_buf);
6491
6492 $p = 0; # is fixed
6493
6494 my $validation_only = 0;
6495
6496 $validation_only = 1 if (defined ($additional_param));
6497
6498 if ($validation_only == 1)
6499 {
6500 $num_cycle_power = int ($iter);
6501 $seven_zip_salt_len = $additional_param;
6502 $seven_zip_salt_buf = $additional_param2;
6503 $salt_len = $additional_param3;
6504 # $salt_buf set in parser
6505 # $hash_buf (resulting crc)
6506 $data_len = $additional_param4;
6507 $unpack_size = $additional_param5;
6508 $data_buf = $additional_param6;
6509 }
6510 else
6511 {
6512 $num_cycle_power = 14; # by default it is 19
6513 $seven_zip_salt_len = 0;
6514 $seven_zip_salt_buf = "";
6515 $salt_len = length ($salt_buf);
6516 # $salt_buf set automatically
6517 # $hash_buf (resulting crc)
6518 # $data_len will be set when encrypting
6519 $unpack_size = get_random_num (1, 32 + 1);
6520 $data_buf = get_random_string ($unpack_size);
6521 }
6522
6523 #
6524 # 2 ^ NumCyclesPower "iterations" of SHA256 (only one final SHA256)
6525 #
6526
6527 $word_buf = encode ("UTF-16LE", $word_buf);
6528
6529 my $rounds = 1 << $num_cycle_power;
6530
6531 my $pass_buf = "";
6532
6533 for (my $i = 0; $i < $rounds; $i++)
6534 {
6535 my $num_buf = "";
6536
6537 $num_buf .= pack ("V", $i);
6538 $num_buf .= "\x00" x 4;
6539
6540 # this would be better but only works on 64-bit systems:
6541 # $num_buf = pack ("q", $i);
6542
6543 $pass_buf .= sprintf ("%s%s", $word_buf, $num_buf);
6544 }
6545
6546 my $key = sha256 ($pass_buf);
6547
6548 # the salt_buf is our IV for AES CBC
6549 # pad the salt_buf
6550
6551 my $salt_buf_len = length ($salt_buf);
6552 my $salt_padding_len = 0;
6553
6554 if ($salt_buf_len < 16)
6555 {
6556 $salt_padding_len = 16 - $salt_buf_len;
6557 }
6558
6559 $salt_buf .= "\x00" x $salt_padding_len;
6560
6561 my $aes = Crypt::CBC->new ({
6562 cipher => "Crypt::Rijndael",
6563 key => $key,
6564 keysize => 32,
6565 literal_key => 1,
6566 iv => $salt_buf,
6567 header => "none",
6568 });
6569
6570 if ($validation_only == 1)
6571 {
6572 # decrypt
6573
6574 my $decrypted_data = $aes->decrypt ($data_buf);
6575
6576 $decrypted_data = substr ($decrypted_data, 0, $unpack_size);
6577
6578 $hash_buf = crc32 ($decrypted_data);
6579 }
6580 else
6581 {
6582 # encrypt
6583
6584 $hash_buf = crc32 ($data_buf);
6585
6586 $data_buf = $aes->encrypt ($data_buf);
6587
6588 $data_len = length ($data_buf);
6589 }
6590
6591 $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));
6592 }
6593 elsif ($mode == 11900)
6594 {
6595 my $iterations = 1000;
6596
6597 if (length ($iter))
6598 {
6599 $iterations = int ($iter);
6600 }
6601
6602 my $out_len = 32;
6603
6604 if (defined $additional_param)
6605 {
6606 $out_len = $additional_param;
6607 }
6608
6609 #
6610 # call PHP here - WTF
6611 #
6612
6613 # sanitize $word_buf and $salt_buf:
6614
6615 my $word_buf_base64 = encode_base64 ($word_buf);
6616 $word_buf_base64 =~ s/[\r\n]//g;
6617
6618 my $salt_buf_base64 = encode_base64 ($salt_buf);
6619 $salt_buf_base64 =~ s/[\r\n]//g;
6620
6621 # sanitize lenghs
6622
6623 $out_len = int ($out_len);
6624
6625 # output is in hex encoding, otherwise it could be screwed (but shouldn't)
6626
6627 my $php_code = <<'END_CODE';
6628
6629 function pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
6630 {
6631 $algorithm = strtolower ($algorithm);
6632
6633 if (! in_array ($algorithm, hash_algos (), true))
6634 {
6635 trigger_error ("PBKDF2 ERROR: Invalid hash algorithm.", E_USER_ERROR);
6636 }
6637
6638 if ($count <= 0 || $key_length <= 0)
6639 {
6640 trigger_error ("PBKDF2 ERROR: Invalid parameters.", E_USER_ERROR);
6641 }
6642
6643 if (function_exists ("hash_pbkdf2"))
6644 {
6645 if (!$raw_output)
6646 {
6647 $key_length = $key_length * 2;
6648 }
6649
6650 return hash_pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output);
6651 }
6652
6653 $hash_length = strlen (hash ($algorithm, "", true));
6654 $block_count = ceil ($key_length / $hash_length);
6655
6656 $output = "";
6657
6658 for ($i = 1; $i <= $block_count; $i++)
6659 {
6660 $last = $salt . pack ("N", $i);
6661
6662 $last = $xorsum = hash_hmac ($algorithm, $last, $password, true);
6663
6664 for ($j = 1; $j < $count; $j++)
6665 {
6666 $xorsum ^= ($last = hash_hmac ($algorithm, $last, $password, true));
6667 }
6668
6669 $output .= $xorsum;
6670 }
6671
6672 if ($raw_output)
6673 {
6674 return substr ($output, 0, $key_length);
6675 }
6676 else
6677 {
6678 return bin2hex (substr ($output, 0, $key_length));
6679 }
6680 }
6681
6682 print pbkdf2 ("md5", base64_decode ("$word_buf_base64"), base64_decode ("$salt_buf_base64"), $iterations, $out_len, False);
6683
6684 END_CODE
6685
6686 # replace with these command line arguments
6687
6688 $php_code =~ s/\$word_buf_base64/$word_buf_base64/;
6689 $php_code =~ s/\$salt_buf_base64/$salt_buf_base64/;
6690 $php_code =~ s/\$iterations/$iterations/;
6691 $php_code =~ s/\$out_len/$out_len/;
6692
6693 my $php_output = `php -r '$php_code'`;
6694
6695 $hash_buf = pack ("H*", $php_output);
6696
6697 $hash_buf = encode_base64 ($hash_buf);
6698 $hash_buf =~ s/[\r\n]//g;
6699
6700 my $base64_salt_buf = encode_base64 ($salt_buf);
6701
6702 chomp ($base64_salt_buf);
6703
6704 $tmp_hash = sprintf ("md5:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6705 }
6706 elsif ($mode == 12000)
6707 {
6708 my $iterations = 1000;
6709
6710 if (length ($iter))
6711 {
6712 $iterations = int ($iter);
6713 }
6714
6715 my $out_len = 16;
6716
6717 if (defined $additional_param)
6718 {
6719 $out_len = $additional_param;
6720 }
6721
6722 my $pbkdf2 = Crypt::PBKDF2->new
6723 (
6724 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1'),
6725 iterations => $iterations,
6726 output_len => $out_len
6727 );
6728
6729 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6730 $hash_buf =~ s/[\r\n]//g;
6731
6732 my $base64_salt_buf = encode_base64 ($salt_buf);
6733
6734 chomp ($base64_salt_buf);
6735
6736 $tmp_hash = sprintf ("sha1:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6737 }
6738 elsif ($mode == 12100)
6739 {
6740 my $iterations = 1000;
6741
6742 if (length ($iter))
6743 {
6744 $iterations = int ($iter);
6745 }
6746
6747 my $out_len = 16;
6748
6749 if (defined $additional_param)
6750 {
6751 $out_len = $additional_param;
6752 }
6753
6754 my $pbkdf2 = Crypt::PBKDF2->new
6755 (
6756 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512),
6757 iterations => $iterations,
6758 output_len => $out_len
6759 );
6760
6761 $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt_buf, $word_buf));
6762 $hash_buf =~ s/[\r\n]//g;
6763
6764 my $base64_salt_buf = encode_base64 ($salt_buf);
6765
6766 chomp ($base64_salt_buf);
6767
6768 $tmp_hash = sprintf ("sha512:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
6769 }
6770 elsif ($mode == 12200)
6771 {
6772 my $iterations = 65536;
6773
6774 my $default_salt = 0;
6775
6776 if (defined $additional_param)
6777 {
6778 $default_salt = int ($additional_param);
6779 }
6780
6781 if ($default_salt == 1)
6782 {
6783 $salt_buf = "0011223344556677";
6784 }
6785
6786 $hash_buf = sha512 (pack ("H*", $salt_buf) . $word_buf);
6787
6788 for (my $i = 0; $i < $iterations; $i++)
6789 {
6790 $hash_buf = sha512 ($hash_buf);
6791 }
6792
6793 $hash_buf = unpack ("H*", $hash_buf);
6794 $hash_buf = substr ($hash_buf, 0, 16);
6795
6796 if ($default_salt == 0)
6797 {
6798 $tmp_hash = sprintf ("\$ecryptfs\$0\$1\$%s\$%s", $salt_buf, $hash_buf);
6799 }
6800 else
6801 {
6802 $tmp_hash = sprintf ("\$ecryptfs\$0\$%s", $hash_buf);
6803 }
6804 }
6805 elsif ($mode == 12300)
6806 {
6807 my $iterations = 4096;
6808
6809 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512);
6810
6811 my $pbkdf2 = Crypt::PBKDF2->new (
6812 hasher => $hasher,
6813 iterations => $iterations,
6814 output_len => 64
6815 );
6816
6817 my $salt_bin = pack ("H*", $salt_buf);
6818
6819 my $key = $pbkdf2->PBKDF2 ($salt_bin. "AUTH_PBKDF2_SPEEDY_KEY", $word_buf);
6820
6821 $hash_buf = sha512_hex ($key . $salt_bin);
6822
6823 $tmp_hash = sprintf ("%s%s", uc ($hash_buf), uc ($salt_buf));
6824 }
6825 elsif ($mode == 12400)
6826 {
6827 my $iterations;
6828
6829 if (length ($iter))
6830 {
6831 $iterations = int ($iter);
6832 }
6833 else
6834 {
6835 $iterations = get_random_num (1, 5001 + 1);
6836 }
6837
6838 my $key_value = fold_password ($word_buf);
6839
6840 my $data = "\x00\x00\x00\x00\x00\x00\x00\x00";
6841 my $salt_value = base64_to_int24 ($salt_buf);
6842
6843 $hash_buf = crypt_rounds ($key_value, $iterations, $salt_value, $data);
6844
6845 $tmp_hash = sprintf ("_%s%s%s", int24_to_base64 ($iterations), $salt_buf, block_to_base64 ($hash_buf));
6846 }
6847 elsif ($mode == 12600)
6848 {
6849 $hash_buf = sha1_hex ($word_buf);
6850
6851 $hash_buf = sha256_hex ($salt_buf . uc $hash_buf);
6852
6853 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
6854 }
6855 elsif ($mode == 12700)
6856 {
6857 my $iterations = 10;
6858
6859 my $data = qq|{
6860 "guid" : "00000000-0000-0000-0000-000000000000",
6861 "sharedKey" : "00000000-0000-0000-0000-000000000000",
6862 "options" : {"pbkdf2_iterations":10,"fee_policy":0,"html5_notifications":false,"logout_time":600000,"tx_display":0,"always_keep_local_backup":false}|;
6863
6864 my $salt_buf_bin = pack ("H*", $salt_buf);
6865
6866 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
6867
6868 my $pbkdf2 = Crypt::PBKDF2->new (
6869 hasher => $hasher,
6870 iterations => $iterations,
6871 output_len => 32
6872 );
6873
6874 my $key = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6875
6876 my $cipher = Crypt::CBC->new ({
6877 key => $key,
6878 cipher => "Crypt::Rijndael",
6879 iv => $salt_buf_bin,
6880 literal_key => 1,
6881 header => "none",
6882 keysize => 32
6883 });
6884
6885 my $encrypted = unpack ("H*", $cipher->encrypt ($data));
6886
6887 $tmp_hash = sprintf ("\$blockchain\$%s\$%s", length ($salt_buf . $encrypted) / 2, $salt_buf . $encrypted);
6888 }
6889 elsif ($mode == 12800)
6890 {
6891 my $iterations = 100;
6892
6893 if (length ($iter))
6894 {
6895 $iterations = int ($iter);
6896 }
6897
6898 my $nt = md4_hex (encode ("UTF-16LE", $word_buf));
6899
6900 my $pbkdf2 = Crypt::PBKDF2->new
6901 (
6902 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6903 iterations => $iterations,
6904 output_len => 32
6905 );
6906
6907 my $salt_buf_bin = pack ("H*", $salt_buf);
6908
6909 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, uc (encode ("UTF-16LE", $nt)));
6910
6911 $tmp_hash = sprintf ("v1;PPH1_MD4,%s,%d,%s", $salt_buf, $iterations, unpack ("H*", $hash));
6912 }
6913 elsif ($mode == 12900)
6914 {
6915 my $iterations = 4096;
6916
6917 if (length ($iter))
6918 {
6919 $iterations = int ($iter);
6920 }
6921
6922 my $salt2 = $salt_buf . $salt_buf;
6923
6924 if (defined $additional_param)
6925 {
6926 $salt2 = $additional_param;
6927 }
6928
6929 my $pbkdf2 = Crypt::PBKDF2->new
6930 (
6931 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6932 iterations => $iterations,
6933 output_len => 32
6934 );
6935
6936 my $salt_buf_bin = pack ("H*", $salt_buf);
6937
6938 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6939
6940 my $salt2_bin = pack ("H*", $salt2);
6941
6942 my $hash_hmac = hmac_hex ($salt2_bin, $hash, \&sha256, 64);
6943
6944 $tmp_hash = sprintf ("%s%s%s", $salt2, $hash_hmac, $salt_buf);
6945 }
6946 elsif ($mode == 13000)
6947 {
6948 my $iterations = 15;
6949
6950 if (length ($iter))
6951 {
6952 $iterations = int ($iter);
6953 }
6954
6955 my $iv = "0" x 32;
6956
6957 if (defined $additional_param)
6958 {
6959 $iv = $additional_param;
6960 }
6961
6962 my $pbkdf2 = Crypt::PBKDF2->new
6963 (
6964 hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
6965 iterations => (1 << $iterations) + 32,
6966 output_len => 32
6967 );
6968
6969 my $salt_buf_bin = pack ("H*", $salt_buf);
6970
6971 my $hash = $pbkdf2->PBKDF2 ($salt_buf_bin, $word_buf);
6972
6973 my $hash_final = substr ($hash, 0, 8)
6974 ^ substr ($hash, 8, 8)
6975 ^ substr ($hash, 16, 8)
6976 ^ substr ($hash, 24, 8);
6977
6978 $tmp_hash = sprintf ('$rar5$16$%s$%d$%s$8$%s', $salt_buf, $iterations, $iv, unpack ("H*", $hash_final));
6979 }
6980 elsif ($mode == 13100)
6981 {
6982 my @salt_arr = split ('\$', $salt_buf);
6983
6984 my $user = $salt_arr[0];
6985
6986 my $realm = $salt_arr[1];
6987
6988 my $spn = $salt_arr[2];
6989
6990 my $nonce = $salt_arr[3];
6991
6992 my $cleartext_ticket = '6381b03081ada00703050050a00000a11b3019a003020117a1'.
6993 '12041058e0d77776e8b8e03991f2966939222aa2171b154d594b5242544553542e434f4e5'.
6994 '44f534f2e434f4da3133011a003020102a10a30081b067472616e6365a40b3009a0030201'.
6995 '01a1020400a511180f32303136303231353134343735305aa611180f32303136303231353'.
6996 '134343735305aa711180f32303136303231363030343735305aa811180f32303136303232'.
6997 '323134343735305a';
6998
6999 $cleartext_ticket = $nonce . $cleartext_ticket;
7000
7001 my $k = md4 (encode ("UTF-16LE", $word_buf));
7002
7003 my $k1 = hmac_md5 ("\x02\x00\x00\x00", $k);
7004
7005 my $checksum = hmac_md5 (pack ("H*", $cleartext_ticket), $k1);
7006
7007 my $k3 = hmac_md5 ($checksum, $k1);
7008
7009 my $cipher = Crypt::RC4->new ($k3);
7010
7011 my $edata2 = $cipher->RC4 (pack ("H*", $cleartext_ticket));
7012
7013 $tmp_hash = sprintf ('$krb5tgs$23$*%s$%s$%s*$%s$%s', $user, $realm, $spn, unpack ("H*", $checksum), unpack ("H*", $edata2));
7014 }
7015 elsif ($mode == 13200)
7016 {
7017 my @salt_arr = split ('\*', $salt_buf);
7018
7019 my $iteration = $salt_arr[0];
7020
7021 my $mysalt = $salt_arr[1];
7022
7023 $mysalt = pack ("H*", $mysalt);
7024
7025 my $DEK = randbytes (16);
7026
7027 my $iv = "a6a6a6a6a6a6a6a6";
7028
7029 my $KEK = sha1($word_buf);
7030
7031 $KEK = substr ($KEK ^ $mysalt, 0, 16);
7032
7033 my $aes = Crypt::Mode::ECB->new ('AES');
7034
7035 my @R = ('', substr(pack ("H*",$DEK),0,8), substr(pack ("H*",$DEK),8,16));
7036
7037 my $B;
7038
7039 my $A = pack ("H*", $iv);
7040
7041 for (my $j = 0; $j < $iteration; $j++)
7042 {
7043 $B = $aes->encrypt ($A . $R[1], $KEK);
7044
7045 $A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 1));
7046
7047 $R[1] = substr ($B, 8, 16);
7048
7049 $B = $aes->encrypt ($A . $R[2], $KEK);
7050
7051 $A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 2));
7052
7053 $R[2] = substr ($B, 8, 16);
7054 }
7055
7056 my $wrapped_key = unpack ("H*", $A . substr ($R[1], 0 ,8) . substr ($R[2], 0 ,8));
7057
7058 $mysalt = unpack ("H*", $mysalt);
7059
7060 $tmp_hash = sprintf ('$axcrypt$*1*%s*%s*%s', $iteration, $mysalt, $wrapped_key);
7061 }
7062 elsif ($mode == 13300)
7063 {
7064 $hash_buf = sha1_hex ($word_buf);
7065
7066 $tmp_hash = sprintf ('$axcrypt_sha1$%s', substr ($hash_buf, 0, 32));
7067 }
7068 elsif ($mode == 13400)
7069 {
7070 my @salt_arr = split ('\*', $salt_buf);
7071
7072 my $version = $salt_arr[0];
7073
7074 my $iteration = $salt_arr[1];
7075
7076 my $algorithm = $salt_arr[2];
7077
7078 my $final_random_seed = $salt_arr[3];
7079
7080 my $transf_random_seed = $salt_arr[4];
7081
7082 my $enc_iv = $salt_arr[5];
7083
7084 my $contents_hash;
7085
7086 # specific to version 1
7087 my $inline_flag;
7088 my $contents_len;
7089 my $contents;
7090
7091 # specific to version 2
7092 my $expected_bytes;
7093
7094 # specific to keyfile handling
7095 my $inline_keyfile_flag;
7096 my $keyfile_len;
7097 my $keyfile_content;
7098 my $keyfile_attributes = "";
7099
7100 $final_random_seed = pack ("H*", $final_random_seed);
7101
7102 $transf_random_seed = pack ("H*", $transf_random_seed);
7103
7104 $enc_iv = pack ("H*", $enc_iv);
7105
7106 my $intermediate_hash = sha256 ($word_buf);
7107
7108 if ($version == 1)
7109 {
7110 $contents_hash = $salt_arr[6];
7111 $contents_hash = pack ("H*", $contents_hash);
7112
7113 $inline_flag = $salt_arr[7];
7114
7115 $contents_len = $salt_arr[8];
7116
7117 $contents = $salt_arr[9];
7118 $contents = pack ("H*", $contents);
7119
7120 # keyfile handling
7121 if (scalar @salt_arr == 13)
7122 {
7123 $inline_keyfile_flag = $salt_arr[10];
7124
7125 $keyfile_len = $salt_arr[11];
7126
7127 $keyfile_content = $salt_arr[12];
7128
7129 $keyfile_attributes = $keyfile_attributes
7130 . "*" . $inline_keyfile_flag
7131 . "*" . $keyfile_len
7132 . "*" . $keyfile_content;
7133
7134 $intermediate_hash = $intermediate_hash . pack ("H*", $keyfile_content);
7135 $intermediate_hash = sha256 ($intermediate_hash);
7136 }
7137 }
7138 elsif ($version == 2)
7139 {
7140 # keyfile handling
7141 if (scalar @salt_arr == 11)
7142 {
7143 $inline_keyfile_flag = $salt_arr[8];
7144
7145 $keyfile_len = $salt_arr[9];
7146
7147 $keyfile_content = $salt_arr[10];
7148
7149 $intermediate_hash = $intermediate_hash . pack ("H*", $keyfile_content);
7150
7151 $keyfile_attributes = $keyfile_attributes
7152 . "*" . $inline_keyfile_flag
7153 . "*" . $keyfile_len
7154 . "*" . $keyfile_content;
7155
7156 }
7157 $intermediate_hash = sha256 ($intermediate_hash);
7158 }
7159
7160 my $aes = Crypt::Mode::ECB->new ('AES', 1);
7161
7162 for (my $j = 0; $j < $iteration; $j++)
7163 {
7164 $intermediate_hash = $aes->encrypt ($intermediate_hash, $transf_random_seed);
7165
7166 $intermediate_hash = substr ($intermediate_hash, 0, 32);
7167 }
7168
7169 $intermediate_hash = sha256 ($intermediate_hash);
7170
7171 my $final_key = sha256 ($final_random_seed . $intermediate_hash);
7172
7173 my $final_algorithm;
7174
7175 if ($version == 1 && $algorithm == 1)
7176 {
7177 $final_algorithm = "Crypt::Twofish";
7178 }
7179 else
7180 {
7181 $final_algorithm = "Crypt::Rijndael";
7182 }
7183
7184 my $cipher = Crypt::CBC->new ({
7185 key => $final_key,
7186 cipher => $final_algorithm,
7187 iv => $enc_iv,
7188 literal_key => 1,
7189 header => "none",
7190 keysize => 32
7191 });
7192
7193 if ($version == 1)
7194 {
7195 $contents_hash = sha256 ($contents);
7196
7197 $contents = $cipher->encrypt($contents);
7198
7199 $tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%d*%d*%s%s',
7200 $version,
7201 $iteration,
7202 $algorithm,
7203 unpack ("H*", $final_random_seed),
7204 unpack ("H*", $transf_random_seed),
7205 unpack ("H*", $enc_iv),
7206 unpack ("H*", $contents_hash),
7207 $inline_flag,
7208 $contents_len,
7209 unpack ("H*", $contents),
7210 $keyfile_attributes);
7211 }
7212 if ($version == 2)
7213 {
7214 $expected_bytes = $salt_arr[6];
7215
7216 $contents_hash = $salt_arr[7];
7217 $contents_hash = pack ("H*", $contents_hash);
7218
7219 $expected_bytes = $cipher->decrypt($contents_hash);
7220
7221 $tmp_hash = sprintf ('$keepass$*%d*%d*%d*%s*%s*%s*%s*%s%s',
7222 $version,
7223 $iteration,
7224 $algorithm,
7225 unpack ("H*", $final_random_seed),
7226 unpack ("H*", $transf_random_seed),
7227 unpack ("H*", $enc_iv),
7228 unpack ("H*", $expected_bytes),
7229 unpack ("H*", $contents_hash),
7230 $keyfile_attributes);
7231 }
7232 }
7233 elsif ($mode == 13500)
7234 {
7235 $hash_buf = sha1_hex (pack ("H*", $salt_buf) . encode ("UTF-16LE", $word_buf));
7236
7237 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
7238 }
7239 elsif ($mode == 13600)
7240 {
7241 my $iterations = 1000;
7242
7243 my $type = 0;
7244
7245 if (defined $additional_param)
7246 {
7247 $type = $additional_param;
7248 }
7249
7250 my $mode = 1 + int rand (3);
7251
7252 if (defined $additional_param2)
7253 {
7254 $mode = $additional_param2;
7255 }
7256
7257 my $magic = 0;
7258
7259 if (defined $additional_param3)
7260 {
7261 $magic = $additional_param3;
7262 }
7263
7264 if (defined $additional_param4)
7265 {
7266 $salt_buf = $additional_param4;
7267 }
7268
7269 $salt_buf = substr ($salt_buf, 0, 8 + ($mode * 8));
7270
7271 my $compress_length = 0;
7272
7273 if (defined $additional_param5)
7274 {
7275 $compress_length = $additional_param5;
7276 }
7277
7278 my $data = "";
7279
7280 if (defined $additional_param6)
7281 {
7282 $data = $additional_param6;
7283 }
7284
7285 my $key_len = (8 * ($mode & 3) + 8) * 2;
7286
7287 my $out_len = $key_len + 2;
7288
7289 my $salt_buf_bin = pack ("H*", $salt_buf);
7290
7291 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
7292
7293 my $pbkdf2 = Crypt::PBKDF2->new
7294 (
7295 hasher => $hasher,
7296 iterations => $iterations,
7297 output_len => $out_len
7298 );
7299
7300 my $key = $pbkdf2->PBKDF2_hex ($salt_buf_bin, $word_buf);
7301
7302 my $verify_bytes = substr ($key, -4); $verify_bytes =~ s/^0+//; #lol
7303
7304 $key = substr ($key, $key_len, $key_len);
7305
7306 my $key_bin = pack ("H*", $key);
7307
7308 my $auth = hmac_hex ($data, $key_bin, \&sha1, 64);
7309
7310 $tmp_hash = sprintf ('$zip2$*%u*%u*%u*%s*%s*%u*%s*%s*$/zip2$', $type, $mode, $magic, $salt_buf, $verify_bytes, $compress_length, $data, substr ($auth, 0, 20));
7311 }
7312 elsif ($mode == 13800)
7313 {
7314 my $word_buf_unicode = encode ("UTF-16LE", $word_buf);
7315
7316 my $salt_buf_bin = pack ("H*", $salt_buf);
7317
7318 $hash_buf = sha256_hex ($word_buf_unicode . $salt_buf_bin);
7319
7320 $tmp_hash = sprintf ("%s:%s", $hash_buf, $salt_buf);
7321 }
7322
7323 return ($tmp_hash);
7324 }
7325
7326 sub rnd
7327 {
7328 my $mode = shift;
7329
7330 my $word_len = shift;
7331
7332 my $salt_len = shift;
7333
7334 my $max = $MAX_LEN;
7335
7336 $max = 15 if ($mode == 2410);
7337
7338 if ($is_unicode{$mode})
7339 {
7340 if (! $allow_long_salt{$mode})
7341 {
7342 $word_len = min ($word_len, int ($max / 2) - $salt_len);
7343 }
7344 else
7345 {
7346 $word_len = min ($word_len, int ($max / 2));
7347 }
7348 }
7349 elsif ($less_fifteen{$mode})
7350 {
7351 $word_len = min ($word_len, 15);
7352
7353 if ($mode == 2410)
7354 {
7355 $salt_len = min ($salt_len, 15 - $word_len);
7356 }
7357 }
7358 else
7359 {
7360 if (! $allow_long_salt{$mode})
7361 {
7362 $word_len = min ($word_len, $max - $salt_len);
7363 }
7364 }
7365
7366 if ($word_len < 1)
7367 {
7368 $word_len = 1;
7369 }
7370
7371 ##
7372 ## gen salt
7373 ##
7374
7375 my $salt_buf;
7376
7377 if ($mode == 4800)
7378 {
7379 my @salt_arr;
7380
7381 for (my $i = 0; $i < $salt_len; $i++)
7382 {
7383 my $c = get_random_chr (0x30, 0x39);
7384
7385 push (@salt_arr, $c);
7386 }
7387
7388 $salt_buf = join ("", @salt_arr);
7389
7390 $salt_buf = get_random_md5chap_salt ($salt_buf);
7391 }
7392 elsif ($mode == 5300 || $mode == 5400)
7393 {
7394 $salt_buf = get_random_ike_salt ();
7395 }
7396 elsif ($mode == 5500)
7397 {
7398 $salt_buf = get_random_netntlmv1_salt ($salt_len, $salt_len);
7399 }
7400 elsif ($mode == 5600)
7401 {
7402 $salt_buf = get_random_netntlmv2_salt ($salt_len, $salt_len);
7403 }
7404 elsif ($mode == 6600)
7405 {
7406 $salt_buf = get_random_agilekeychain_salt ();
7407 }
7408 elsif ($mode == 8200)
7409 {
7410 $salt_buf = get_random_cloudkeychain_salt ();
7411 }
7412 elsif ($mode == 8300)
7413 {
7414 $salt_buf = get_random_dnssec_salt ();
7415 }
7416 elsif ($mode == 13100)
7417 {
7418 $salt_buf = get_random_kerberos5_tgs_salt ();
7419 }
7420 elsif ($mode == 13200)
7421 {
7422 $salt_buf = get_random_axcrypt_salt ();
7423 }
7424 elsif ($mode == 13400)
7425 {
7426 $salt_buf = get_random_keepass_salt ();
7427 }
7428 elsif ($mode == 13500)
7429 {
7430 $salt_buf = get_pstoken_salt ();
7431 }
7432 else
7433 {
7434 my @salt_arr;
7435
7436 for (my $i = 0; $i < $salt_len; $i++)
7437 {
7438 my $c = get_random_chr (0x30, 0x39);
7439
7440 push (@salt_arr, $c);
7441 }
7442
7443 $salt_buf = join ("", @salt_arr);
7444
7445 if ($mode == 7500)
7446 {
7447 $salt_buf = get_random_kerberos5_salt ($salt_buf);
7448 }
7449 }
7450
7451 ##
7452 ## gen plain
7453 ##
7454
7455 my @word_arr;
7456
7457 for (my $i = 0; $i < $word_len; $i++)
7458 {
7459 my $c = get_random_chr (0x30, 0x39);
7460
7461 push (@word_arr, $c);
7462 }
7463
7464 my $word_buf = join ("", @word_arr);
7465
7466 ##
7467 ## gen hash
7468 ##
7469
7470 my $tmp_hash = gen_hash ($mode, $word_buf, $salt_buf);
7471
7472 ##
7473 ## run
7474 ##
7475
7476 my @cmd =
7477 (
7478 $hashcat,
7479 "-a 0 -m", $mode,
7480 $tmp_hash
7481 );
7482
7483 print sprintf ("echo -n %-20s | %s \${OPTS} %s %4d '%s'\n", $word_buf, @cmd);
7484 }
7485
7486 ##
7487 ## subs
7488 ##
7489
7490 sub min
7491 {
7492 $_[$_[0] > $_[1]];
7493 }
7494
7495 sub get_random_string
7496 {
7497 my $len = shift;
7498
7499 my @arr;
7500
7501 for (my $i = 0; $i < $len; $i++)
7502 {
7503 my $c = get_random_chr (0x30, 0x39);
7504
7505 push (@arr, $c);
7506 }
7507
7508 my $buf = join ("", @arr);
7509
7510 return $buf;
7511 }
7512
7513 sub get_random_num
7514 {
7515 my $min = shift;
7516 my $max = shift;
7517
7518 return int ((rand ($max - $min)) + $min);
7519 }
7520
7521 sub get_random_chr
7522 {
7523 return chr get_random_num (@_);
7524 }
7525
7526 sub domino_decode
7527 {
7528 my $str = shift;
7529
7530 my $decoded = "";
7531
7532 for (my $i = 0; $i < length ($str); $i += 4)
7533 {
7534 my $num = domino_base64_decode (substr ($str, $i, 4), 4);
7535
7536 $decoded .= chr (($num >> 16) & 0xff) . chr (($num >> 8) & 0xff) . chr ($num & 0xff);
7537 }
7538
7539 my $salt;
7540 my $digest;
7541 my $char;
7542
7543 $salt = substr ($decoded, 0, 5);
7544
7545 my $byte10 = (ord (substr ($salt, 3, 1)) - 4);
7546
7547 if ($byte10 < 0)
7548 {
7549 $byte10 = 256 + $byte10;
7550 }
7551
7552 substr ($salt, 3, 1) = chr ($byte10);
7553
7554 $digest = substr ($decoded, 5, 9);
7555 $char = substr ($str, 18, 1);
7556
7557 return ($digest, $salt, $char);
7558 }
7559
7560 sub domino_85x_decode
7561 {
7562 my $str = shift;
7563
7564 my $decoded = "";
7565
7566 for (my $i = 0; $i < length ($str); $i += 4)
7567 {
7568 my $num = domino_base64_decode (substr ($str, $i, 4), 4);
7569
7570 $decoded .= chr (($num >> 16) & 0xff) . chr (($num >> 8) & 0xff) . chr ($num & 0xff);
7571 }
7572
7573 my $digest;
7574 my $salt;
7575 my $iterations = -1;
7576 my $chars;
7577
7578 $salt = substr ($decoded, 0, 16); # longer than -m 8700 (5 vs 16 <- new)
7579
7580 my $byte10 = (ord (substr ($salt, 3, 1)) - 4);
7581
7582 if ($byte10 < 0)
7583 {
7584 $byte10 = 256 + $byte10;
7585 }
7586
7587 substr ($salt, 3, 1) = chr ($byte10);
7588
7589 $iterations = substr ($decoded, 16, 10);
7590
7591 if ($iterations =~ /^?d*$/)
7592 {
7593 # continue
7594
7595 $iterations = $iterations + 0; # hack: make sure it is an int now (atoi ())
7596 $chars = substr ($decoded, 26, 2); # in my example it is "02"
7597 $digest = substr ($decoded, 28, 8); # only of length of 8 vs 20 SHA1 bytes
7598 }
7599
7600 return ($digest, $salt, $iterations, $chars);
7601 }
7602
7603 sub domino_base64_decode
7604 {
7605 my $v = shift;
7606 my $n = shift;
7607
7608 my $itoa64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
7609
7610 my $ret = 0;
7611
7612 my $i = 1;
7613
7614 while ($i <= $n)
7615 {
7616 my $idx = (index ($itoa64, substr ($v, $n - $i, 1))) & 0x3f;
7617
7618 $ret += ($idx << (6 * ($i - 1)));
7619
7620 $i = $i + 1;
7621 }
7622
7623 return $ret
7624 }
7625
7626 sub domino_encode
7627 {
7628 my $final = shift;
7629 my $char = shift;
7630
7631 my $byte10 = (ord (substr ($final, 3, 1)) + 4);
7632
7633 if ($byte10 > 255)
7634 {
7635 $byte10 = $byte10 - 256;
7636 }
7637
7638 substr ($final, 3, 1) = chr ($byte10);
7639
7640 my $passwd = "";
7641
7642 $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);
7643 $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);
7644 $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);
7645 $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);
7646 $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);
7647
7648 if (defined ($char))
7649 {
7650 substr ($passwd, 18, 1) = $char;
7651 }
7652 substr ($passwd, 19, 1) = "";
7653
7654 return $passwd;
7655 }
7656
7657 sub domino_85x_encode
7658 {
7659 my $final = shift;
7660 my $char = shift;
7661
7662 my $byte10 = (ord (substr ($final, 3, 1)) + 4);
7663
7664 if ($byte10 > 255)
7665 {
7666 $byte10 = $byte10 - 256;
7667 }
7668
7669 substr ($final, 3, 1) = chr ($byte10);
7670
7671 my $passwd = "";
7672
7673 $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);
7674 $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);
7675 $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);
7676 $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);
7677 $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);
7678 $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);
7679 $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);
7680 $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);
7681 $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);
7682 $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);
7683 $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);
7684 $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);
7685
7686 if (defined ($char))
7687 {
7688 substr ($passwd, 18, 1) = $char;
7689 }
7690
7691 return $passwd;
7692 }
7693
7694 sub domino_base64_encode
7695 {
7696 my $v = shift;
7697 my $n = shift;
7698
7699 my $itoa64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
7700
7701 my $ret = "";
7702
7703 while (($n - 1) >= 0)
7704 {
7705 $n = $n - 1;
7706
7707 $ret = substr ($itoa64, $v & 0x3f, 1) . $ret;
7708
7709 $v = $v >> 6;
7710 }
7711
7712 return $ret
7713 }
7714
7715 sub pseudo_base64
7716 {
7717 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7718
7719 my $md5 = shift;
7720 my $s64 = "";
7721 for my $i (0..3) {
7722 my $v = unpack "V", substr($md5, $i*4, 4);
7723 for (1..4) {
7724 $s64 .= substr($itoa64, $v & 0x3f, 1);
7725 $v >>= 6;
7726 }
7727 }
7728 return $s64;
7729 }
7730
7731 sub racf_hash
7732 {
7733 my ($username, $password) = @_;
7734
7735 $username = substr ($username . " " x 8, 0, 8);
7736 $password = substr ($password . " " x 8, 0, 8);
7737
7738 my $username_ebc = ascii2ebcdic ($username);
7739 my $password_ebc = ascii2ebcdic ($password);
7740
7741 my @pw = split ("", $password_ebc);
7742
7743 for (my $i = 0; $i < 8; $i++)
7744 {
7745 $pw[$i] = unpack ("C", $pw[$i]);
7746 $pw[$i] ^= 0x55;
7747 $pw[$i] <<= 1;
7748 $pw[$i] = pack ("C", $pw[$i] & 0xff);
7749 }
7750
7751 my $key = join ("", @pw);
7752
7753 my $cipher = new Crypt::DES $key;
7754
7755 my $ciphertext = $cipher->encrypt ($username_ebc);
7756
7757 my $ct = unpack ("H16", $ciphertext);
7758
7759 return $ct;
7760 }
7761
7762 sub oracle_hash
7763 {
7764 my ($username, $password) = @_;
7765
7766 my $userpass = pack('n*', unpack('C*', uc($username.$password)));
7767 $userpass .= pack('C', 0) while (length($userpass) % 8);
7768
7769 my $key = pack('H*', "0123456789ABCDEF");
7770 my $iv = pack('H*', "0000000000000000");
7771
7772 my $c = new Crypt::CBC(
7773 -literal_key => 1,
7774 -cipher => "DES",
7775 -key => $key,
7776 -iv => $iv,
7777 -header => "none"
7778 );
7779 my $key2 = substr($c->encrypt($userpass), length($userpass)-8, 8);
7780
7781 my $c2 = new Crypt::CBC(
7782 -literal_key => 1,
7783 -cipher => "DES",
7784 -key => $key2,
7785 -iv => $iv,
7786 -header => "none"
7787 );
7788 my $hash = substr($c2->encrypt($userpass), length($userpass)-8, 8);
7789
7790 return uc(unpack('H*', $hash));
7791 }
7792
7793 sub androidpin_hash
7794 {
7795 my $word_buf = shift;
7796
7797 my $salt_buf = shift;
7798
7799 my $w = sprintf ("%d%s%s", 0, $word_buf, $salt_buf);
7800
7801 my $digest = sha1 ($w);
7802
7803 for (my $i = 1; $i < 1024; $i++)
7804 {
7805 $w = $digest . sprintf ("%d%s%s", $i, $word_buf, $salt_buf);
7806
7807 $digest = sha1 ($w);
7808 }
7809
7810 my ($A, $B, $C, $D, $E) = unpack ("N5", $digest);
7811
7812 return sprintf ("%08x%08x%08x%08x%08x", $A, $B, $C, $D, $E);
7813 }
7814
7815 sub to64
7816 {
7817 my $v = shift;
7818 my $n = shift;
7819
7820 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7821
7822 my $ret = "";
7823
7824 while (($n - 1) >= 0)
7825 {
7826 $n = $n - 1;
7827
7828 $ret .= substr ($itoa64, $v & 0x3f, 1);
7829
7830 $v = $v >> 6;
7831 }
7832
7833 return $ret
7834 }
7835
7836 sub md5_crypt
7837 {
7838 my $magic = shift;
7839
7840 my $iter = shift;
7841 my $pass = shift;
7842 my $salt = shift;
7843
7844 my $hash = ""; # hash to be returned by this function
7845
7846 my $final = md5 ($pass . $salt . $pass);
7847
7848 $salt = substr ($salt, 0, 8);
7849
7850 my $tmp = $pass . $magic . $salt;
7851
7852 my $pass_len = length ($pass);
7853
7854 my $i;
7855
7856 for ($i = $pass_len; $i > 0; $i -= 16)
7857 {
7858 my $len = 16;
7859
7860 if ($i < $len)
7861 {
7862 $len = $i;
7863 }
7864
7865 $tmp .= substr ($final, 0, $len);
7866 }
7867
7868 $i = $pass_len;
7869
7870 while ($i > 0)
7871 {
7872 if ($i & 1)
7873 {
7874 $tmp .= chr (0);
7875 }
7876 else
7877 {
7878 $tmp .= substr ($pass, 0, 1);
7879 }
7880
7881 $i >>= 1;
7882 }
7883
7884 $final = md5 ($tmp);
7885
7886 for ($i = 0; $i < $iter; $i++)
7887 {
7888 $tmp = "";
7889
7890 if ($i & 1)
7891 {
7892 $tmp .= $pass;
7893 }
7894 else
7895 {
7896 $tmp .= $final;
7897 }
7898
7899 if ($i % 3)
7900 {
7901 $tmp .= $salt;
7902 }
7903
7904 if ($i % 7)
7905 {
7906 $tmp .= $pass;
7907 }
7908
7909 if ($i & 1)
7910 {
7911 $tmp .= $final;
7912 }
7913 else
7914 {
7915 $tmp .= $pass;
7916 }
7917
7918 $final = md5 ($tmp);
7919 }
7920
7921 # done
7922 # now format the output sting ("hash")
7923
7924 my $hash_buf;
7925
7926 $hash = to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 6, 1)) << 8) | (ord (substr ($final, 12, 1))), 4);
7927 $hash .= to64 ((ord (substr ($final, 1, 1)) << 16) | (ord (substr ($final, 7, 1)) << 8) | (ord (substr ($final, 13, 1))), 4);
7928 $hash .= to64 ((ord (substr ($final, 2, 1)) << 16) | (ord (substr ($final, 8, 1)) << 8) | (ord (substr ($final, 14, 1))), 4);
7929 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 9, 1)) << 8) | (ord (substr ($final, 15, 1))), 4);
7930 $hash .= to64 ((ord (substr ($final, 4, 1)) << 16) | (ord (substr ($final, 10, 1)) << 8) | (ord (substr ($final, 5, 1))), 4);
7931 $hash .= to64 (ord (substr ($final, 11, 1)), 2);
7932
7933 if ($iter == 1000) # default
7934 {
7935 $hash_buf = sprintf ("%s%s\$%s", $magic , $salt , $hash);
7936 }
7937 else
7938 {
7939 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
7940 }
7941
7942 return $hash_buf;
7943 }
7944
7945 sub sha512_crypt
7946 {
7947 my $iter = shift;
7948 my $pass = shift;
7949 my $salt = shift;
7950
7951 my $hash = ""; # hash to be returned by this function
7952
7953 my $final = sha512 ($pass . $salt . $pass);
7954
7955 $salt = substr ($salt, 0, 16);
7956
7957 my $tmp = $pass . $salt;
7958
7959 my $pass_len = length ($pass);
7960 my $salt_len = length ($salt);
7961
7962 my $i;
7963
7964 for ($i = $pass_len; $i > 0; $i -= 16)
7965 {
7966 my $len = 16;
7967
7968 if ($i < $len)
7969 {
7970 $len = $i;
7971 }
7972
7973 $tmp .= substr ($final, 0, $len);
7974 }
7975
7976 $i = $pass_len;
7977
7978 while ($i > 0)
7979 {
7980 if ($i & 1)
7981 {
7982 $tmp .= $final;
7983 }
7984 else
7985 {
7986 $tmp .= $pass;
7987 }
7988
7989 $i >>= 1;
7990 }
7991
7992 $final = sha512 ($tmp);
7993
7994 # p_bytes
7995
7996 my $p_bytes = "";
7997
7998 for ($i = 0; $i < $pass_len; $i++)
7999 {
8000 $p_bytes .= $pass;
8001 }
8002
8003 $p_bytes = sha512 ($p_bytes);
8004 $p_bytes = substr ($p_bytes, 0, $pass_len);
8005
8006 # s_bytes
8007
8008 my $final_first_byte = ord (substr ($final, 0, 1));
8009
8010 my $s_bytes = "";
8011
8012 for ($i = 0; $i < (16 + $final_first_byte); $i++)
8013 {
8014 $s_bytes .= $salt;
8015 }
8016
8017 $s_bytes = sha512 ($s_bytes);
8018 $s_bytes = substr ($s_bytes, 0, $salt_len);
8019
8020 for ($i = 0; $i < $iter; $i++)
8021 {
8022 $tmp = "";
8023
8024 if ($i & 1)
8025 {
8026 $tmp .= $p_bytes;
8027 }
8028 else
8029 {
8030 $tmp .= $final;
8031 }
8032
8033 if ($i % 3)
8034 {
8035 $tmp .= $s_bytes;
8036 }
8037
8038 if ($i % 7)
8039 {
8040 $tmp .= $p_bytes;
8041 }
8042
8043 if ($i & 1)
8044 {
8045 $tmp .= $final;
8046 }
8047 else
8048 {
8049 $tmp .= $p_bytes;
8050 }
8051
8052 $final = sha512 ($tmp);
8053 }
8054
8055 # done
8056 # now format the output string ("hash")
8057
8058 my $hash_buf;
8059
8060 $hash .= to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 21, 1)) << 8) | (ord (substr ($final, 42, 1))), 4);
8061 $hash .= to64 ((ord (substr ($final, 22, 1)) << 16) | (ord (substr ($final, 43, 1)) << 8) | (ord (substr ($final, 1, 1))), 4);
8062 $hash .= to64 ((ord (substr ($final, 44, 1)) << 16) | (ord (substr ($final, 2, 1)) << 8) | (ord (substr ($final, 23, 1))), 4);
8063 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 24, 1)) << 8) | (ord (substr ($final, 45, 1))), 4);
8064 $hash .= to64 ((ord (substr ($final, 25, 1)) << 16) | (ord (substr ($final, 46, 1)) << 8) | (ord (substr ($final, 4, 1))), 4);
8065 $hash .= to64 ((ord (substr ($final, 47, 1)) << 16) | (ord (substr ($final, 5, 1)) << 8) | (ord (substr ($final, 26, 1))), 4);
8066 $hash .= to64 ((ord (substr ($final, 6, 1)) << 16) | (ord (substr ($final, 27, 1)) << 8) | (ord (substr ($final, 48, 1))), 4);
8067 $hash .= to64 ((ord (substr ($final, 28, 1)) << 16) | (ord (substr ($final, 49, 1)) << 8) | (ord (substr ($final, 7, 1))), 4);
8068 $hash .= to64 ((ord (substr ($final, 50, 1)) << 16) | (ord (substr ($final, 8, 1)) << 8) | (ord (substr ($final, 29, 1))), 4);
8069 $hash .= to64 ((ord (substr ($final, 9, 1)) << 16) | (ord (substr ($final, 30, 1)) << 8) | (ord (substr ($final, 51, 1))), 4);
8070 $hash .= to64 ((ord (substr ($final, 31, 1)) << 16) | (ord (substr ($final, 52, 1)) << 8) | (ord (substr ($final, 10, 1))), 4);
8071 $hash .= to64 ((ord (substr ($final, 53, 1)) << 16) | (ord (substr ($final, 11, 1)) << 8) | (ord (substr ($final, 32, 1))), 4);
8072 $hash .= to64 ((ord (substr ($final, 12, 1)) << 16) | (ord (substr ($final, 33, 1)) << 8) | (ord (substr ($final, 54, 1))), 4);
8073 $hash .= to64 ((ord (substr ($final, 34, 1)) << 16) | (ord (substr ($final, 55, 1)) << 8) | (ord (substr ($final, 13, 1))), 4);
8074 $hash .= to64 ((ord (substr ($final, 56, 1)) << 16) | (ord (substr ($final, 14, 1)) << 8) | (ord (substr ($final, 35, 1))), 4);
8075 $hash .= to64 ((ord (substr ($final, 15, 1)) << 16) | (ord (substr ($final, 36, 1)) << 8) | (ord (substr ($final, 57, 1))), 4);
8076 $hash .= to64 ((ord (substr ($final, 37, 1)) << 16) | (ord (substr ($final, 58, 1)) << 8) | (ord (substr ($final, 16, 1))), 4);
8077 $hash .= to64 ((ord (substr ($final, 59, 1)) << 16) | (ord (substr ($final, 17, 1)) << 8) | (ord (substr ($final, 38, 1))), 4);
8078 $hash .= to64 ((ord (substr ($final, 18, 1)) << 16) | (ord (substr ($final, 39, 1)) << 8) | (ord (substr ($final, 60, 1))), 4);
8079 $hash .= to64 ((ord (substr ($final, 40, 1)) << 16) | (ord (substr ($final, 61, 1)) << 8) | (ord (substr ($final, 19, 1))), 4);
8080 $hash .= to64 ((ord (substr ($final, 62, 1)) << 16) | (ord (substr ($final, 20, 1)) << 8) | (ord (substr ($final, 41, 1))), 4);
8081 $hash .= to64 (ord (substr ($final, 63, 1)), 2);
8082
8083 my $magic = '$6$';
8084
8085 if ($iter == 5000) # default
8086 {
8087 $hash_buf = sprintf ("%s%s\$%s", $magic, $salt , $hash);
8088 }
8089 else
8090 {
8091 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
8092 }
8093
8094 return $hash_buf;
8095 }
8096
8097 sub sha256_crypt
8098 {
8099 my $iter = shift;
8100 my $pass = shift;
8101 my $salt = shift;
8102
8103 my $hash = ""; # hash to be returned by this function
8104
8105 my $final = sha256 ($pass . $salt . $pass);
8106
8107 $salt = substr ($salt, 0, 16);
8108
8109 my $tmp = $pass . $salt;
8110
8111 my $pass_len = length ($pass);
8112 my $salt_len = length ($salt);
8113
8114 my $i;
8115
8116 for ($i = $pass_len; $i > 0; $i -= 16)
8117 {
8118 my $len = 16;
8119
8120 if ($i < $len)
8121 {
8122 $len = $i;
8123 }
8124
8125 $tmp .= substr ($final, 0, $len);
8126 }
8127
8128 $i = $pass_len;
8129
8130 while ($i > 0)
8131 {
8132 if ($i & 1)
8133 {
8134 $tmp .= $final;
8135 }
8136 else
8137 {
8138 $tmp .= $pass;
8139 }
8140
8141 $i >>= 1;
8142 }
8143
8144 $final = sha256 ($tmp);
8145
8146 # p_bytes
8147
8148 my $p_bytes = "";
8149
8150 for ($i = 0; $i < $pass_len; $i++)
8151 {
8152 $p_bytes .= $pass;
8153 }
8154
8155 $p_bytes = sha256 ($p_bytes);
8156 $p_bytes = substr ($p_bytes, 0, $pass_len);
8157
8158 # s_bytes
8159
8160 my $final_first_byte = ord (substr ($final, 0, 1));
8161
8162 my $s_bytes = "";
8163
8164 for ($i = 0; $i < (16 + $final_first_byte); $i++)
8165 {
8166 $s_bytes .= $salt;
8167 }
8168
8169 $s_bytes = sha256 ($s_bytes);
8170 $s_bytes = substr ($s_bytes, 0, $salt_len);
8171
8172 for ($i = 0; $i < $iter; $i++)
8173 {
8174 $tmp = "";
8175
8176 if ($i & 1)
8177 {
8178 $tmp .= $p_bytes;
8179 }
8180 else
8181 {
8182 $tmp .= $final;
8183 }
8184
8185 if ($i % 3)
8186 {
8187 $tmp .= $s_bytes;
8188 }
8189
8190 if ($i % 7)
8191 {
8192 $tmp .= $p_bytes;
8193 }
8194
8195 if ($i & 1)
8196 {
8197 $tmp .= $final;
8198 }
8199 else
8200 {
8201 $tmp .= $p_bytes;
8202 }
8203
8204 $final = sha256 ($tmp);
8205 }
8206
8207 # done
8208 # now format the output string ("hash")
8209
8210 my $hash_buf;
8211
8212 $hash .= to64 ((ord (substr ($final, 0, 1)) << 16) | (ord (substr ($final, 10, 1)) << 8) | (ord (substr ($final, 20, 1))), 4);
8213 $hash .= to64 ((ord (substr ($final, 21, 1)) << 16) | (ord (substr ($final, 1, 1)) << 8) | (ord (substr ($final, 11, 1))), 4);
8214 $hash .= to64 ((ord (substr ($final, 12, 1)) << 16) | (ord (substr ($final, 22, 1)) << 8) | (ord (substr ($final, 2, 1))), 4);
8215 $hash .= to64 ((ord (substr ($final, 3, 1)) << 16) | (ord (substr ($final, 13, 1)) << 8) | (ord (substr ($final, 23, 1))), 4);
8216 $hash .= to64 ((ord (substr ($final, 24, 1)) << 16) | (ord (substr ($final, 4, 1)) << 8) | (ord (substr ($final, 14, 1))), 4);
8217 $hash .= to64 ((ord (substr ($final, 15, 1)) << 16) | (ord (substr ($final, 25, 1)) << 8) | (ord (substr ($final, 5, 1))), 4);
8218 $hash .= to64 ((ord (substr ($final, 6, 1)) << 16) | (ord (substr ($final, 16, 1)) << 8) | (ord (substr ($final, 26, 1))), 4);
8219 $hash .= to64 ((ord (substr ($final, 27, 1)) << 16) | (ord (substr ($final, 7, 1)) << 8) | (ord (substr ($final, 17, 1))), 4);
8220 $hash .= to64 ((ord (substr ($final, 18, 1)) << 16) | (ord (substr ($final, 28, 1)) << 8) | (ord (substr ($final, 8, 1))), 4);
8221 $hash .= to64 ((ord (substr ($final, 9, 1)) << 16) | (ord (substr ($final, 19, 1)) << 8) | (ord (substr ($final, 29, 1))), 4);
8222 $hash .= to64 ((ord (substr ($final, 31, 1)) << 8) | (ord (substr ($final, 30, 1))), 3);
8223
8224 my $magic = '$5$';
8225
8226 if ($iter == 5000) # default
8227 {
8228 $hash_buf = sprintf ("%s%s\$%s", $magic, $salt , $hash);
8229 }
8230 else
8231 {
8232 $hash_buf = sprintf ("%srounds=%i\$%s\$%s", $magic, $iter, $salt , $hash);
8233 }
8234
8235 return $hash_buf;
8236 }
8237
8238 sub aix_ssha256_pbkdf2
8239 {
8240 my $word_buf = shift;
8241 my $salt_buf = shift;
8242 my $iterations = shift;
8243
8244 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256);
8245
8246 my $pbkdf2 = Crypt::PBKDF2->new (
8247 hasher => $hasher,
8248 iterations => $iterations,
8249 output_len => 32
8250 );
8251
8252 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
8253
8254 my $tmp_hash = "";
8255
8256 $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);
8257 $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);
8258 $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);
8259 $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);
8260 $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);
8261 $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);
8262 $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);
8263 $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);
8264 $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);
8265 $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);
8266 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) , 3);
8267
8268 return $tmp_hash;
8269 }
8270
8271 sub aix_ssha512_pbkdf2
8272 {
8273 my $word_buf = shift;
8274 my $salt_buf = shift;
8275 my $iterations = shift;
8276
8277 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512);
8278
8279 my $pbkdf2 = Crypt::PBKDF2->new (
8280 hasher => $hasher,
8281 iterations => $iterations,
8282 );
8283
8284 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
8285
8286 my $tmp_hash = "";
8287
8288 $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);
8289 $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);
8290 $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);
8291 $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);
8292 $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);
8293 $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);
8294 $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);
8295 $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);
8296 $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);
8297 $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);
8298 $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);
8299 $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);
8300 $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);
8301 $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);
8302 $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);
8303 $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);
8304 $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);
8305 $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);
8306 $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);
8307 $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);
8308 $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);
8309 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 63, 1))) << 16) , 2);
8310
8311 return $tmp_hash;
8312 }
8313
8314 sub aix_ssha1_pbkdf2
8315 {
8316 my $word_buf = shift;
8317 my $salt_buf = shift;
8318 my $iterations = shift;
8319
8320 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1');
8321
8322 my $pbkdf2 = Crypt::PBKDF2->new (
8323 hasher => $hasher,
8324 iterations => $iterations,
8325 );
8326
8327 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf);
8328
8329 my $tmp_hash = "";
8330
8331 $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);
8332 $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);
8333 $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);
8334 $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);
8335 $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);
8336 $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);
8337 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) , 3);
8338
8339 return $tmp_hash;
8340 }
8341
8342 sub sapb_transcode
8343 {
8344 my $data_s = shift;
8345
8346 my @data = split "", $data_s;
8347
8348 my $transTable_s =
8349 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8350 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8351 "\x3f\x40\x41\x50\x43\x44\x45\x4b\x47\x48\x4d\x4e\x54\x51\x53\x46" .
8352 "\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x56\x55\x5c\x49\x5d\x4a" .
8353 "\x42\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" .
8354 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x58\x5b\x59\xff\x52" .
8355 "\x4c\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" .
8356 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x57\x5e\x5a\x4f\xff" .
8357 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8358 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8359 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8360 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8361 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8362 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8363 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" .
8364 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
8365
8366 my @transTable = unpack ("C256", $transTable_s);
8367
8368 my @out;
8369
8370 for (my $i = 0; $i < scalar @data; $i++)
8371 {
8372 $out[$i] = $transTable[int (ord ($data[$i]))];
8373 }
8374
8375 return pack ("C*", @out);
8376 }
8377
8378 sub sapb_waldorf
8379 {
8380 my $digest_s = shift;
8381
8382 my $w_s = shift;
8383 my $s_s = shift;
8384
8385 my @w = unpack "C*", $w_s;
8386 my @s = unpack "C*", $s_s;
8387
8388 my $bcodeTable_s =
8389 "\x14\x77\xf3\xd4\xbb\x71\x23\xd0\x03\xff\x47\x93\x55\xaa\x66\x91" .
8390 "\xf2\x88\x6b\x99\xbf\xcb\x32\x1a\x19\xd9\xa7\x82\x22\x49\xa2\x51" .
8391 "\xe2\xb7\x33\x71\x8b\x9f\x5d\x01\x44\x70\xae\x11\xef\x28\xf0\x0d";
8392
8393 my @bcodeTable = unpack ("C48", $bcodeTable_s);
8394
8395 my @abcd = unpack ("C16", $digest_s);
8396
8397 my $sum20 = ($abcd[0] & 3)
8398 + ($abcd[1] & 3)
8399 + ($abcd[2] & 3)
8400 + ($abcd[3] & 3)
8401 + ($abcd[5] & 3);
8402
8403 $sum20 |= 0x20;
8404
8405 my @out;
8406
8407 for (my $i2 = 0; $i2 < $sum20; $i2++)
8408 {
8409 $out[$i2] = 0;
8410 }
8411
8412 for (my $i1 = 0, my $i2 = 0, my $i3 = 0; $i2 < $sum20; $i2++, $i2++)
8413 {
8414 if ($i1 < length $w_s)
8415 {
8416 if ($abcd[15 - $i1] & 1)
8417 {
8418 $out[$i2] = $bcodeTable[48 - 1 - $i1];
8419
8420 $i2++;
8421 }
8422
8423 $out[$i2] = $w[$i1];
8424
8425 $i1++;
8426 $i2++;
8427 }
8428
8429 if ($i3 < length $s_s)
8430 {
8431 $out[$i2] = $s[$i3];
8432
8433 $i2++;
8434 $i3++;
8435 }
8436
8437 $out[$i2] = $bcodeTable[$i2 - $i1 - $i3];
8438 }
8439
8440 return substr (pack ("C*", @out), 0, $sum20);
8441 }
8442
8443 sub setup_des_key
8444 {
8445 my @key_56 = split (//, shift);
8446
8447 my $key = "";
8448
8449 $key = $key_56[0];
8450
8451 $key .= chr(((ord($key_56[0]) << 7) | (ord($key_56[1]) >> 1)) & 255);
8452 $key .= chr(((ord($key_56[1]) << 6) | (ord($key_56[2]) >> 2)) & 255);
8453 $key .= chr(((ord($key_56[2]) << 5) | (ord($key_56[3]) >> 3)) & 255);
8454 $key .= chr(((ord($key_56[3]) << 4) | (ord($key_56[4]) >> 4)) & 255);
8455 $key .= chr(((ord($key_56[4]) << 3) | (ord($key_56[5]) >> 5)) & 255);
8456 $key .= chr(((ord($key_56[5]) << 2) | (ord($key_56[6]) >> 6)) & 255);
8457 $key .= chr(( ord($key_56[6]) << 1) & 255);
8458
8459 return $key;
8460 }
8461
8462 sub randbytes
8463 {
8464 my $len = shift;
8465
8466 my @arr;
8467
8468 for (my $i = 0; $i < $len; $i++)
8469 {
8470 my $c = get_random_chr (0, 255);
8471
8472 push (@arr, $c);
8473 }
8474
8475 return join ("", @arr);
8476 }
8477
8478 sub get_random_netntlmv1_salt
8479 {
8480 my $len_user = shift;
8481 my $len_domain = shift;
8482
8483 my $char;
8484 my $type;
8485 my $user = "";
8486
8487 for (my $i = 0; $i < $len_user; $i++)
8488 {
8489 $type = get_random_num (1, 3);
8490
8491 if ($type == 1)
8492 {
8493 $char = get_random_chr (0x30, 0x39);
8494 }
8495 elsif ($type == 2)
8496 {
8497 $char = get_random_chr (0x41, 0x5A);
8498 }
8499 else
8500 {
8501 $char = get_random_chr (0x61, 0x7A);
8502 }
8503
8504 $user .= $char;
8505 }
8506
8507 my $domain = "";
8508
8509 for (my $i = 0; $i < $len_domain; $i++)
8510 {
8511 $type = get_random_num (1, 3);
8512
8513 if ($type == 1)
8514 {
8515 $char = get_random_chr (0x30, 0x39);
8516 }
8517 elsif ($type == 2)
8518 {
8519 $char = get_random_chr (0x41, 0x5A);
8520 }
8521 else
8522 {
8523 $char = get_random_chr (0x61, 0x7A);
8524 }
8525
8526 $domain .= $char;
8527 }
8528
8529 my $c_challenge = randbytes (8);
8530 my $s_challenge = randbytes (8);
8531
8532 my $salt_buf = $user . "::" . $domain . ":" . unpack ("H*", $c_challenge) . unpack ("H*", $s_challenge);
8533
8534 return $salt_buf;
8535 }
8536
8537 sub get_random_netntlmv2_salt
8538 {
8539 my $len_user = shift;
8540 my $len_domain = shift;
8541
8542 my $char;
8543 my $type;
8544 my $user = "";
8545
8546 if ($len_user + $len_domain > 27)
8547 {
8548 if ($len_user > $len_domain)
8549 {
8550 $len_user = 27 - $len_domain;
8551 }
8552 else
8553 {
8554 $len_domain = 27 - $len_user;
8555 }
8556 }
8557
8558 for (my $i = 0; $i < $len_user; $i++)
8559 {
8560 $type = get_random_num (1, 3);
8561
8562 if ($type == 1)
8563 {
8564 $char = get_random_chr (0x30, 0x39);
8565 }
8566 elsif ($type == 2)
8567 {
8568 $char = get_random_chr (0x41, 0x5A);
8569 }
8570 else
8571 {
8572 $char = get_random_chr (0x61, 0x7A);
8573 }
8574
8575 $user .= $char;
8576 }
8577
8578 my $domain = "";
8579
8580 for (my $i = 0; $i < $len_domain; $i++)
8581 {
8582 $type = get_random_num (1, 3);
8583
8584 if ($type == 1)
8585 {
8586 $char = get_random_chr (0x30, 0x39);
8587 }
8588 elsif ($type == 2)
8589 {
8590 $char = get_random_chr (0x41, 0x5A);
8591 }
8592 else
8593 {
8594 $char = get_random_chr (0x61, 0x7A);
8595 }
8596
8597 $domain .= $char;
8598 }
8599
8600 my $c_challenge = randbytes (8);
8601 my $s_challenge = randbytes (8);
8602
8603 my $temp = "\x01\x01" .
8604 "\x00" x 6 .
8605 randbytes (8) .
8606 $c_challenge .
8607 "\x00" x 4 .
8608 randbytes (20 * rand () + 1) .
8609 "\x00";
8610
8611 my $salt_buf = $user . "::" . $domain . ":" . unpack ("H*", $s_challenge) . unpack ("H*", $temp);
8612
8613 return $salt_buf;
8614 }
8615
8616 sub get_random_ike_salt
8617 {
8618 my $nr_buf = "";
8619
8620 for (my $i = 0; $i < 40; $i++)
8621 {
8622 $nr_buf .= get_random_chr (0, 0xff);
8623 }
8624
8625 my $msg_buf = "";
8626
8627 for (my $i = 0; $i < 440; $i++)
8628 {
8629 $msg_buf .= get_random_chr (0, 0xff);
8630 }
8631
8632 my $nr_buf_hex = unpack ("H*", $nr_buf);
8633 my $msg_buf_hex = unpack ("H*", $msg_buf);
8634
8635 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));
8636
8637 return $salt_buf;
8638 }
8639
8640 sub get_random_agilekeychain_salt
8641 {
8642 my $salt_buf = "";
8643
8644 for (my $i = 0; $i < 8; $i++)
8645 {
8646 $salt_buf .= get_random_chr (0x0, 0xff);
8647 }
8648
8649 my $iv = "";
8650
8651 for (my $i = 0; $i < 16; $i++)
8652 {
8653 $iv .= get_random_chr (0x0, 0xff);
8654 }
8655
8656 my $prefix = "\x00" x 1008;
8657
8658 my $ret = unpack ("H*", $salt_buf . $prefix . $iv);
8659
8660 return $ret;
8661 }
8662
8663 sub get_random_cloudkeychain_salt
8664 {
8665 my $salt_buf = "";
8666
8667 for (my $i = 0; $i < 16; $i++)
8668 {
8669 $salt_buf .= get_random_chr (0x0, 0xff);
8670 }
8671
8672 for (my $i = 0; $i < 304; $i++)
8673 {
8674 $salt_buf .= get_random_chr (0x0, 0xff);
8675 }
8676
8677 my $ret = unpack ("H*", $salt_buf);
8678
8679 return $ret;
8680 }
8681
8682 sub get_random_kerberos5_salt
8683 {
8684 my $custom_salt = shift;
8685
8686 my $clear_data = randbytes (14) .
8687 strftime ("%Y%m%d%H%M%S", localtime) .
8688 randbytes (8);
8689
8690 my $user = "user";
8691 my $realm = "realm";
8692 my $salt = "salt";
8693
8694 my $salt_buf = $user . "\$" . $realm . "\$" . $salt . "\$" . unpack ("H*", $custom_salt) . "\$" . unpack ("H*", $clear_data) . "\$";
8695
8696 return $salt_buf;
8697 }
8698
8699 sub get_random_kerberos5_tgs_salt
8700 {
8701 my $nonce = randbytes (8);
8702
8703 my $user = "user";
8704 my $realm = "realm";
8705 my $spn = "test/spn";
8706
8707 my $salt_buf = $user . "\$" . $realm . "\$" . $spn . "\$" . unpack ("H*",$nonce);
8708
8709 return $salt_buf;
8710 }
8711
8712 sub get_random_axcrypt_salt
8713 {
8714 my $mysalt = randbytes (16);
8715
8716 $mysalt = unpack ("H*", $mysalt);
8717
8718 my $iteration = get_random_num (6, 100000);
8719
8720 my $salt_buf = $iteration . '*' . $mysalt;
8721
8722 return $salt_buf;
8723 }
8724
8725 sub get_random_keepass_salt
8726 {
8727 my $version = get_random_num (1, 3);
8728
8729 my $algorithm;
8730
8731 my $iteration;
8732
8733 my $final_random_seed;
8734
8735 if ($version == 1)
8736 {
8737 $algorithm = get_random_num (0, 2);
8738
8739 $iteration = get_random_num (50000, 100000);
8740
8741 $final_random_seed = randbytes (16);
8742 $final_random_seed = unpack ("H*", $final_random_seed);
8743 }
8744 elsif ($version == 2)
8745 {
8746 $algorithm = 0;
8747
8748 $iteration = get_random_num (6000, 100000);
8749
8750 $final_random_seed = randbytes (32);
8751 $final_random_seed = unpack ("H*", $final_random_seed);
8752 }
8753
8754 my $transf_random_seed = randbytes (32);
8755 $transf_random_seed = unpack ("H*", $transf_random_seed);
8756
8757 my $enc_iv = randbytes (16);
8758 $enc_iv = unpack ("H*", $enc_iv);
8759
8760 my $contents_hash = randbytes (32);
8761 $contents_hash = unpack ("H*", $contents_hash);
8762
8763 my $inline_flag = 1;
8764
8765 my $contents_len = get_random_num (128, 500);
8766
8767 my $contents = randbytes ($contents_len);
8768
8769 $contents_len += 16 - $contents_len % 16;
8770
8771 $contents = unpack ("H*", $contents);
8772
8773 my $salt_buf;
8774
8775 my $is_keyfile = get_random_num (0, 2);
8776
8777 my $keyfile_attributes = "";
8778
8779 if ($is_keyfile == 1)
8780 {
8781 $keyfile_attributes = $keyfile_attributes
8782 . "1*64*"
8783 . unpack ("H*", randbytes (32));
8784 }
8785
8786 if ($version == 1)
8787 {
8788 $salt_buf = $version . '*' .
8789 $iteration . '*' .
8790 $algorithm . '*' .
8791 $final_random_seed . '*' .
8792 $transf_random_seed . '*' .
8793 $enc_iv . '*' .
8794 $contents_hash . '*' .
8795 $inline_flag . '*' .
8796 $contents_len . '*' .
8797 $contents . '*' .
8798 $keyfile_attributes;
8799 }
8800 elsif ($version == 2)
8801 {
8802 $contents = randbytes (32);
8803 $contents = unpack ("H*", $contents);
8804
8805 $salt_buf = $version . '*' .
8806 $iteration . '*' .
8807 $algorithm . '*' .
8808 $final_random_seed . '*' .
8809 $transf_random_seed . '*' .
8810 $enc_iv . '*' .
8811 $contents_hash . '*' .
8812 $contents . '*' .
8813 $keyfile_attributes;
8814 }
8815
8816 return $salt_buf;
8817 }
8818
8819 sub get_pstoken_salt
8820 {
8821 my $pstoken_length = get_random_num (16, 256);
8822
8823 ## not a valid pstoken but a better test
8824 ## because of random length
8825
8826 my $pstoken_const = randbytes ($pstoken_length);
8827
8828 return unpack ("H*", $pstoken_const);
8829 }
8830
8831 sub get_random_md5chap_salt
8832 {
8833 my $salt_buf = shift;
8834
8835 my $salt = unpack ("H*", $salt_buf);
8836
8837 $salt .= ":";
8838
8839 $salt .= unpack ("H*", randbytes (1));
8840
8841 return $salt;
8842 }
8843
8844 sub get_random_dnssec_salt
8845 {
8846 my $salt_buf = "";
8847
8848 $salt_buf .= ".";
8849
8850 for (my $i = 0; $i < 8; $i++)
8851 {
8852 $salt_buf .= get_random_chr (0x61, 0x7a);
8853 }
8854
8855 $salt_buf .= ".net";
8856
8857 $salt_buf .= ":";
8858
8859 for (my $i = 0; $i < 8; $i++)
8860 {
8861 $salt_buf .= get_random_chr (0x30, 0x39);
8862 }
8863
8864 return $salt_buf;
8865 }
8866
8867 sub md5bit
8868 {
8869 my $digest = shift;
8870 my $bit = shift;
8871
8872 $bit %= 128;
8873
8874 my $byte_off = int ($bit / 8);
8875 my $bit_off = int ($bit % 8);
8876
8877 my $char = substr ($digest, $byte_off, 1);
8878 my $num = ord ($char);
8879
8880 return (($num & (1 << $bit_off)) ? 1 : 0);
8881 }
8882
8883 sub sun_md5
8884 {
8885 my $pw = shift;
8886 my $salt = shift;
8887 my $iter = shift;
8888
8889 my $constant_phrase =
8890 "To be, or not to be,--that is the question:--\n" .
8891 "Whether 'tis nobler in the mind to suffer\n" .
8892 "The slings and arrows of outrageous fortune\n" .
8893 "Or to take arms against a sea of troubles,\n" .
8894 "And by opposing end them?--To die,--to sleep,--\n" .
8895 "No more; and by a sleep to say we end\n" .
8896 "The heartache, and the thousand natural shocks\n" .
8897 "That flesh is heir to,--'tis a consummation\n" .
8898 "Devoutly to be wish'd. To die,--to sleep;--\n" .
8899 "To sleep! perchance to dream:--ay, there's the rub;\n" .
8900 "For in that sleep of death what dreams may come,\n" .
8901 "When we have shuffled off this mortal coil,\n" .
8902 "Must give us pause: there's the respect\n" .
8903 "That makes calamity of so long life;\n" .
8904 "For who would bear the whips and scorns of time,\n" .
8905 "The oppressor's wrong, the proud man's contumely,\n" .
8906 "The pangs of despis'd love, the law's delay,\n" .
8907 "The insolence of office, and the spurns\n" .
8908 "That patient merit of the unworthy takes,\n" .
8909 "When he himself might his quietus make\n" .
8910 "With a bare bodkin? who would these fardels bear,\n" .
8911 "To grunt and sweat under a weary life,\n" .
8912 "But that the dread of something after death,--\n" .
8913 "The undiscover'd country, from whose bourn\n" .
8914 "No traveller returns,--puzzles the will,\n" .
8915 "And makes us rather bear those ills we have\n" .
8916 "Than fly to others that we know not of?\n" .
8917 "Thus conscience does make cowards of us all;\n" .
8918 "And thus the native hue of resolution\n" .
8919 "Is sicklied o'er with the pale cast of thought;\n" .
8920 "And enterprises of great pith and moment,\n" .
8921 "With this regard, their currents turn awry,\n" .
8922 "And lose the name of action.--Soft you now!\n" .
8923 "The fair Ophelia!--Nymph, in thy orisons\n" .
8924 "Be all my sins remember'd.\n\x00";
8925
8926 my $constant_len = length ($constant_phrase);
8927
8928 my $hash_buf = md5 ($pw . $salt);
8929
8930 my $W;
8931
8932 my $to_hash;
8933
8934 for (my $round = 0; $round < $iter; $round++)
8935 {
8936 my $shift_a = md5bit ($hash_buf, $round + 0);
8937 my $shift_b = md5bit ($hash_buf, $round + 64);
8938
8939 my @shift_4;
8940 my @shift_7;
8941
8942 for (my $k = 0; $k < 16; $k++)
8943 {
8944 my $s7shift = ord (substr ($hash_buf, $k, 1)) % 8;
8945
8946 my $l = ($k + 3) % 16;
8947
8948 my $num = ord (substr ($hash_buf, $l, 1));
8949
8950 $shift_4[$k] = $num % 5;
8951
8952 $shift_7[$k] = ($num >> $s7shift) & 1;
8953 }
8954
8955 my @indirect_4;
8956
8957 for (my $k = 0; $k < 16; $k++)
8958 {
8959 $indirect_4[$k] = (ord (substr ($hash_buf, $k, 1)) >> $shift_4[$k]) & 0xf;
8960 }
8961
8962 my @indirect_7;
8963
8964 for (my $k = 0; $k < 16; $k++)
8965 {
8966 $indirect_7[$k] = (ord (substr ($hash_buf, $indirect_4[$k], 1)) >> $shift_7[$k]) & 0x7f;
8967 }
8968
8969 my $indirect_a = 0;
8970 my $indirect_b = 0;
8971
8972 for (my $k = 0; $k < 8; $k++)
8973 {
8974 $indirect_a |= md5bit ($hash_buf, $indirect_7[$k + 0]) << $k;
8975
8976 $indirect_b |= md5bit ($hash_buf, $indirect_7[$k + 8]) << $k;
8977 }
8978
8979 $indirect_a = ($indirect_a >> $shift_a) & 0x7f;
8980 $indirect_b = ($indirect_b >> $shift_b) & 0x7f;
8981
8982 my $bit_a = md5bit ($hash_buf, $indirect_a);
8983 my $bit_b = md5bit ($hash_buf, $indirect_b);
8984
8985 $W = $hash_buf;
8986
8987 my $pos = 16;
8988
8989 my $total = $pos;
8990
8991 $to_hash = "";
8992
8993 if ($bit_a ^ $bit_b)
8994 {
8995 substr ($W, 16, 48) = substr ($constant_phrase, 0, 48);
8996
8997 $total += 48;
8998
8999 $to_hash .= substr ($W, 0, 64);
9000
9001 my $constant_off;
9002
9003 for ($constant_off = 48; $constant_off < $constant_len - 64; $constant_off += 64)
9004 {
9005 substr ($W, 0, 64) = substr ($constant_phrase, $constant_off, 64);
9006
9007 $total += 64;
9008
9009 $to_hash .= substr ($W, 0, 64);
9010 }
9011
9012 $pos = $constant_len - $constant_off;
9013
9014 $total += $pos;
9015
9016 substr ($W, 0, $pos) = substr ($constant_phrase, $constant_off, $pos);
9017 }
9018
9019 my $a_len = 0;
9020
9021 my @a_buf;
9022 $a_buf[0] = 0;
9023 $a_buf[1] = 0;
9024 $a_buf[2] = 0;
9025 $a_buf[3] = 0;
9026
9027 my $tmp = $round;
9028
9029 do
9030 {
9031 my $round_div = int ($tmp / 10);
9032 my $round_mod = int ($tmp % 10);
9033
9034 $tmp = $round_div;
9035
9036 $a_buf[int ($a_len / 4)] = (($round_mod + 0x30) | ($a_buf[int ($a_len / 4)] << 8));
9037
9038 $a_len++;
9039
9040 } while ($tmp);
9041
9042 my $tmp_str = "";
9043
9044 my $g;
9045
9046 for ($g = 0; $g < $a_len; $g++)
9047 {
9048 my $remainder = $a_buf[$g];
9049 my $factor = 7;
9050 my $started = 1;
9051
9052 my $sub;
9053
9054 while ($remainder > 0)
9055 {
9056 $sub = $remainder >> (8 * $factor);
9057
9058 if ($started != 1 || $sub > 0)
9059 {
9060 $started = 0;
9061
9062 $tmp_str = chr ($sub) . $tmp_str;
9063
9064 $remainder -= ($sub << (8 * $factor));
9065 }
9066
9067 $factor--;
9068 }
9069
9070 }
9071
9072 substr ($W, $pos, $a_len) = $tmp_str;
9073
9074 $pos += $a_len;
9075
9076 $total += $a_len;
9077
9078 $to_hash .= substr ($W, 0, $pos);
9079
9080 $to_hash = substr ($to_hash, 0, $total);
9081
9082 $hash_buf = md5 ($to_hash);
9083 }
9084
9085 my $passwd = "";
9086
9087 $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);
9088 $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);
9089 $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);
9090 $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);
9091 $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);
9092 $passwd .= to64 ((int (ord (substr ($hash_buf, 11, 1)))), 2);
9093
9094 return $passwd;
9095 }
9096
9097 sub usage_die
9098 {
9099 die ("usage: $0 single|passthrough| [mode] [len]\n" .
9100 " or\n" .
9101 " $0 verify [mode] [hashfile] [cracks] [outfile]\n");
9102 }
9103
9104 sub pad16
9105 {
9106 my $block_ref = shift;
9107
9108 my $offset = shift;
9109
9110 my $value = 16 - $offset;
9111
9112 for (my $i = $offset; $i < 16; $i++)
9113 {
9114 push @{$block_ref}, $value;
9115 }
9116 }
9117
9118 sub lotus_mix
9119 {
9120 my $in_ref = shift;
9121
9122 my $p = 0;
9123
9124 for (my $i = 0; $i < 18; $i++)
9125 {
9126 for (my $j = 0; $j < 48; $j++)
9127 {
9128 $p = ($p + 48 - $j) & 0xff;
9129
9130 my $c = $lotus_magic_table[$p];
9131
9132 $p = $in_ref->[$j] ^ $c;
9133
9134 $in_ref->[$j] = $p;
9135 }
9136 }
9137 }
9138
9139 sub lotus_transform_password
9140 {
9141 my $in_ref = shift;
9142 my $out_ref = shift;
9143
9144 my $t = $out_ref->[15];
9145
9146 for (my $i = 0; $i < 16; $i++)
9147 {
9148 $t ^= $in_ref->[$i];
9149
9150 my $c = $lotus_magic_table[$t];
9151
9152 $out_ref->[$i] ^= $c;
9153
9154 $t = $out_ref->[$i];
9155 }
9156 }
9157
9158 sub mdtransform_norecalc
9159 {
9160 my $state_ref = shift;
9161 my $block_ref = shift;
9162
9163 my @x;
9164
9165 push (@x, @{$state_ref});
9166 push (@x, @{$block_ref});
9167
9168 for (my $i = 0; $i < 16; $i++)
9169 {
9170 push (@x, $x[0 + $i] ^ $x[16 + $i]);
9171 }
9172
9173 lotus_mix (\@x);
9174
9175 for (my $i = 0; $i < 16; $i++)
9176 {
9177 $state_ref->[$i] = $x[$i];
9178 }
9179 }
9180
9181 sub mdtransform
9182 {
9183 my $state_ref = shift;
9184 my $checksum_ref = shift;
9185 my $block_ref = shift;
9186
9187 mdtransform_norecalc ($state_ref, $block_ref);
9188
9189 lotus_transform_password ($block_ref, $checksum_ref);
9190 }
9191
9192 sub domino_big_md
9193 {
9194 my $saved_key_ref = shift;
9195
9196 my $size = shift;
9197
9198 @{$saved_key_ref} = splice (@{$saved_key_ref}, 0, $size);
9199
9200 my @state = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
9201
9202 my @checksum;
9203
9204 my $curpos;
9205
9206 for ($curpos = 0; $curpos + 16 < $size; $curpos += 16)
9207 {
9208 my $curpos16 = $curpos + 16;
9209
9210 my @block = splice (@{$saved_key_ref}, 0, 16);
9211
9212 mdtransform (\@state, \@checksum, \@block);
9213 }
9214
9215 my $left = $size - $curpos;
9216
9217 my @block = splice (@{$saved_key_ref}, 0, 16);
9218
9219 pad16 (\@block, $left);
9220
9221 mdtransform (\@state, \@checksum, \@block);
9222
9223 mdtransform_norecalc (\@state, \@checksum);
9224
9225 return @state;
9226 }
9227
9228 sub pdf_compute_encryption_key
9229 {
9230 my $word_buf = shift;
9231 my $padding = shift;
9232 my $id = shift;
9233 my $u = shift;
9234 my $o = shift;
9235 my $P = shift;
9236 my $V = shift;
9237 my $R = shift;
9238 my $enc = shift;
9239
9240 ## start
9241
9242 my $data;
9243
9244 $data .= $word_buf;
9245
9246 $data .= substr ($padding, 0, 32 - length $word_buf);
9247
9248 $data .= pack ("H*", $o);
9249
9250 $data .= pack ("I", $P);
9251
9252 $data .= pack ("H*", $id);
9253
9254 if ($R >= 4)
9255 {
9256 if (!$enc)
9257 {
9258 $data .= pack ("I", -1);
9259 }
9260 }
9261
9262 my $res = md5 ($data);
9263
9264 if ($R >= 3)
9265 {
9266 for (my $i = 0; $i < 50; $i++)
9267 {
9268 $res = md5 ($res);
9269 }
9270 }
9271
9272 return $res;
9273 }
9274
9275 sub gen_random_wpa_eapol
9276 {
9277 my $keyver = shift;
9278 my $snonce = shift;
9279
9280 my $ret = "";
9281
9282 # version
9283
9284 my $version = 1; # 802.1X-2001
9285
9286 $ret .= pack ("C*", $version);
9287
9288 my $type = 3; # means that this EAPOL frame is used to transfer key information
9289
9290 $ret .= pack ("C*", $type);
9291
9292 my $length; # length of remaining data
9293
9294 if ($keyver == 1)
9295 {
9296 $length = 119;
9297 }
9298 else
9299 {
9300 $length = 117;
9301 }
9302
9303 $ret .= pack ("n*", $length);
9304
9305 my $descriptor_type;
9306
9307 if ($keyver == 1)
9308 {
9309 $descriptor_type = 254; # EAPOL WPA key
9310 }
9311 else
9312 {
9313 $descriptor_type = 1; # EAPOL RSN key
9314 }
9315
9316 $ret .= pack ("C*", $descriptor_type);
9317
9318 # key_info is a bit vector:
9319 # generated from these 13 bits: encrypted key data, request, error, secure, key mic, key ack, install, key index (2), key type, key descriptor (3)
9320
9321 my $key_info = 0;
9322
9323 $key_info |= 1 << 8; # set key MIC
9324 $key_info |= 1 << 3; # set if it is a pairwise key
9325
9326 if ($keyver == 1)
9327 {
9328 $key_info |= 1 << 0; # RC4 Cipher, HMAC-MD5 MIC
9329 }
9330 else
9331 {
9332 $key_info |= 1 << 1; # AES Cipher, HMAC-SHA1 MIC
9333 }
9334
9335 $ret .= pack ("n*", $key_info);
9336
9337 my $key_length;
9338
9339 if ($keyver == 1)
9340 {
9341 $key_length = 32;
9342 }
9343 else
9344 {
9345 $key_length = 0;
9346 }
9347
9348 $ret .= pack ("n*", $key_length);
9349
9350 my $replay_counter = 1;
9351
9352 $ret .= pack ("Q>*", $replay_counter);
9353
9354 $ret .= $snonce;
9355
9356 my $key_iv = "\x00" x 16;
9357
9358 $ret .= $key_iv;
9359
9360 my $key_rsc = "\x00" x 8;
9361
9362 $ret .= $key_rsc;
9363
9364 my $key_id = "\x00" x 8;
9365
9366 $ret .= $key_id;
9367
9368 my $key_mic = "\x00" x 16;
9369
9370 $ret .= $key_mic;
9371
9372 my $key_data_len;
9373
9374 if ($keyver == 1)
9375 {
9376 $key_data_len = 24; # length of the key_data (== WPA info)
9377 }
9378 else
9379 {
9380 $key_data_len = 22; # length of the key_data (== RSN info)
9381 }
9382
9383 $ret .= pack ("n*", $key_data_len);
9384
9385 my $key_data = "";
9386
9387 if ($keyver == 1)
9388 {
9389 # wpa info
9390
9391 my $wpa_info = "";
9392
9393 my $vendor_specific_data = "";
9394
9395 my $tag_number = 221; # means it is a vendor specific tag
9396
9397 $vendor_specific_data .= pack ("C*", $tag_number);
9398
9399 my $tag_len = 22; # length of the remaining "tag data"
9400
9401 $vendor_specific_data .= pack ("C*", $tag_len);
9402
9403 my $vendor_specific_oui = pack ("H*", "0050f2"); # microsoft
9404
9405 $vendor_specific_data .= $vendor_specific_oui;
9406
9407 my $vendor_specific_oui_type = 1; # WPA Information Element
9408
9409 $vendor_specific_data .= pack ("C*", $vendor_specific_oui_type);
9410
9411 my $vendor_specific_wpa_version = 1;
9412
9413 $vendor_specific_data .= pack ("v*", $vendor_specific_wpa_version);
9414
9415 # multicast
9416
9417 my $vendor_specific_multicast_oui = pack ("H*", "0050f2");
9418
9419 $vendor_specific_data .= $vendor_specific_multicast_oui;
9420
9421 my $vendor_specific_multicast_type = 2; # TKIP
9422
9423 $vendor_specific_data .= pack ("C*", $vendor_specific_multicast_type);
9424
9425 # unicast
9426
9427 my $vendor_specific_unicast_count = 1;
9428
9429 $vendor_specific_data .= pack ("v*", $vendor_specific_unicast_count);
9430
9431 my $vendor_specific_unicast_oui = pack ("H*", "0050f2");
9432
9433 $vendor_specific_data .= $vendor_specific_multicast_oui;
9434
9435 my $vendor_specific_unicast_type = 2; # TKIP
9436
9437 $vendor_specific_data .= pack ("C*", $vendor_specific_unicast_type);
9438
9439 # Auth Key Management (AKM)
9440
9441 my $auth_key_management_count = 1;
9442
9443 $vendor_specific_data .= pack ("v*", $auth_key_management_count);
9444
9445 my $auth_key_management_oui = pack ("H*", "0050f2");
9446
9447 $vendor_specific_data .= $auth_key_management_oui;
9448
9449 my $auth_key_management_type = 2; # Pre-Shared Key (PSK)
9450
9451 $vendor_specific_data .= pack ("C*", $auth_key_management_type);
9452
9453 $wpa_info = $vendor_specific_data;
9454
9455 $key_data = $wpa_info;
9456 }
9457 else
9458 {
9459 # rsn info
9460
9461 my $rsn_info = "";
9462
9463 my $tag_number = 48; # RSN info
9464
9465 $rsn_info .= pack ("C*", $tag_number);
9466
9467 my $tag_len = 20; # length of the remaining "tag_data"
9468
9469 $rsn_info .= pack ("C*", $tag_len);
9470
9471 my $rsn_version = 1;
9472
9473 $rsn_info .= pack ("v*", $rsn_version);
9474
9475 # group cipher suite
9476
9477 my $group_cipher_suite_oui = pack ("H*", "000fac"); # Ieee8021
9478
9479 $rsn_info .= $group_cipher_suite_oui;
9480
9481 my $group_cipher_suite_type = 4; # AES (CCM)
9482
9483 $rsn_info .= pack ("C*", $group_cipher_suite_type);
9484
9485 # pairwise cipher suite
9486
9487 my $pairwise_cipher_suite_count = 1;
9488
9489 $rsn_info .= pack ("v*", $pairwise_cipher_suite_count);
9490
9491 my $pairwise_cipher_suite_oui = pack ("H*", "000fac"); # Ieee8021
9492
9493 $rsn_info .= $pairwise_cipher_suite_oui;
9494
9495 my $pairwise_cipher_suite_type = 4; # AES (CCM)
9496
9497 $rsn_info .= pack ("C*", $pairwise_cipher_suite_type);
9498
9499 # Auth Key Management (AKM)
9500
9501 my $auth_key_management_count = 1;
9502
9503 $rsn_info .= pack ("v*", $auth_key_management_count);
9504
9505 my $auth_key_management_oui = pack ("H*", "000fac"); # Ieee8021
9506
9507 $rsn_info .= $auth_key_management_oui;
9508
9509 my $auth_key_management_type = 2; # Pre-Shared Key (PSK)
9510
9511 $rsn_info .= pack ("C*", $auth_key_management_type);
9512
9513 # RSN Capabilities
9514
9515 # bit vector of these 9 bits: peerkey enabled, management frame protection (MFP) capable, MFP required,
9516 # RSN GTKSA Capabilities (2), RSN PTKSA Capabilities (2), no pairwise Capabilities, Pre-Auth Capabilities
9517
9518 my $rsn_capabilities = pack ("H*", "0000");
9519
9520 $rsn_info .= $rsn_capabilities;
9521
9522 $key_data = $rsn_info;
9523 }
9524
9525 $ret .= $key_data;
9526
9527 return $ret;
9528 }
9529
9530 sub wpa_prf_512
9531 {
9532 my $pmk = shift;
9533 my $stmac = shift;
9534 my $bssid = shift;
9535 my $snonce = shift;
9536 my $anonce = shift;
9537
9538 my $data = "Pairwise key expansion";
9539
9540 $data .= "\x00";
9541
9542 #
9543 # Min(AA, SPA) || Max(AA, SPA)
9544 #
9545
9546 # compare if greater: Min()/Max() on the MACs (6 bytes)
9547
9548 if (memcmp ($stmac, $bssid, 6) < 0)
9549 {
9550 $data .= $stmac;
9551 $data .= $bssid;
9552 }
9553 else
9554 {
9555 $data .= $bssid;
9556 $data .= $stmac;
9557 }
9558
9559 #
9560 # Min(ANonce,SNonce) || Max(ANonce,SNonce)
9561 #
9562
9563 # compare if greater: Min()/Max() on the nonces (32 bytes)
9564
9565 if (memcmp ($snonce, $anonce, 32) < 0)
9566 {
9567 $data .= $snonce;
9568 $data .= $anonce;
9569 }
9570 else
9571 {
9572 $data .= $anonce;
9573 $data .= $snonce;
9574 }
9575
9576 $data .= "\x00";
9577
9578 my $prf_buf = hmac ($data, $pmk, \&sha1);
9579
9580 $prf_buf = substr ($prf_buf, 0, 16);
9581
9582 return $prf_buf;
9583 }
9584
9585 sub memcmp
9586 {
9587 my $str1 = shift;
9588 my $str2 = shift;
9589 my $len = shift;
9590
9591 my $len_str1 = length ($str1);
9592 my $len_str2 = length ($str2);
9593
9594 if (($len > $len_str1) || ($len > $len_str2))
9595 {
9596 print "ERROR: memcmp () lengths wrong";
9597
9598 exit (1);
9599 }
9600
9601 for (my $i = 0; $i < $len; $i++)
9602 {
9603 my $c_1 = ord (substr ($str1, $i, 1));
9604 my $c_2 = ord (substr ($str2, $i, 1));
9605
9606 return -1 if ($c_1 < $c_2);
9607 return 1 if ($c_1 > $c_2);
9608 }
9609
9610 return 0;
9611 }