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