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