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