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