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