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