mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-25 09:28:20 +00:00
Add unit tests for multiple modules:
15500, 15600, 15700, 16000, 16100, 16200, 16300, 16400, 16500, 16600 & 16700
This commit is contained in:
parent
158b93832c
commit
e085177e58
100
tools/test_modules/m15500.pm
Normal file
100
tools/test_modules/m15500.pm
Normal file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::SHA qw (sha1);
|
||||
use Encode;
|
||||
|
||||
sub module_constraints { [[0, 16], [-1, -1], [0, 16], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $iv = shift || random_hex_string (40);
|
||||
my $enc_key = shift || random_hex_string (random_number (1, 1500));
|
||||
my $alias = shift || "test";
|
||||
|
||||
if (length $iv)
|
||||
{
|
||||
$iv = pack ("H*", $iv);
|
||||
}
|
||||
|
||||
if (length $enc_key)
|
||||
{
|
||||
$enc_key = pack ("H*", $enc_key);
|
||||
}
|
||||
|
||||
my $word_utf16be = encode ("UTF-16BE", $word);
|
||||
|
||||
my $digest = sha1 ($word_utf16be . $iv);
|
||||
|
||||
my $DER1 = substr ($digest, 0, 1);
|
||||
my $DER2 = substr ($digest, 6, 14);
|
||||
|
||||
my @enc_key_data = split "", $enc_key;
|
||||
|
||||
my $enc_key_data_length = scalar @enc_key_data;
|
||||
|
||||
my @key_data = ();
|
||||
|
||||
for (my $i = 0; $i < scalar $enc_key_data_length; $i += 20)
|
||||
{
|
||||
my @digest_data = split "", $digest;
|
||||
|
||||
for (my $j = 0; $j < 20; $j++)
|
||||
{
|
||||
last if (($i + $j) >= $enc_key_data_length);
|
||||
|
||||
$key_data[$i + $j] = $enc_key_data[$i + $j] ^ $digest_data[$j];
|
||||
}
|
||||
|
||||
$digest = sha1 ($word_utf16be . $digest);
|
||||
}
|
||||
|
||||
my $key = join "", @key_data;
|
||||
|
||||
$digest = sha1 ($word_utf16be . $key);
|
||||
|
||||
my $hash = sprintf ("\$jksprivk\$*%s*%s*%s*%s*%s*%s", uc unpack ("H*", $digest), uc unpack ("H*", $iv), uc unpack ("H*", $enc_key), uc unpack ("H*", $DER1), uc unpack ("H*", $DER2), $alias);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split ('\*', $hash);
|
||||
|
||||
return unless scalar @data == 7;
|
||||
|
||||
my $signature = shift @data;
|
||||
|
||||
return unless ($signature eq '$jksprivk$');
|
||||
|
||||
my $checksum = shift @data;
|
||||
my $iv = shift @data;
|
||||
my $enc_key = shift @data;
|
||||
my $DER1 = shift @data;
|
||||
my $DER2 = shift @data;
|
||||
my $alias = shift @data;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $iv, $enc_key, $alias);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
71
tools/test_modules/m15600.pm
Normal file
71
tools/test_modules/m15600.pm
Normal file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Crypt::PBKDF2;
|
||||
use Digest::Keccak qw (keccak_256_hex);
|
||||
|
||||
sub module_constraints { [[0, 255], [32, 32], [0, 55], [32, 32], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $salt = shift;
|
||||
my $iterations = shift || 1024; # 262144 originally
|
||||
my $ciphertext = shift || random_bytes (32);
|
||||
|
||||
my $pbkdf2 = Crypt::PBKDF2->new
|
||||
(
|
||||
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
||||
iterations => $iterations,
|
||||
out_len => 32
|
||||
);
|
||||
|
||||
my $derived_key = $pbkdf2->PBKDF2 ($salt, $word);
|
||||
|
||||
my $derived_key_cropped = substr ($derived_key, 16, 16);
|
||||
|
||||
my $digest = keccak_256_hex ($derived_key_cropped . $ciphertext);
|
||||
|
||||
my $hash = sprintf ("\$ethereum\$p*%i*%s*%s*%s", $iterations, unpack ("H*", $salt), unpack ("H*", $ciphertext), $digest);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my $signature = substr ($hash, 0, 12);
|
||||
|
||||
return unless ($signature eq "\$ethereum\$p\*");
|
||||
|
||||
my @data = split ('\*', $hash);
|
||||
|
||||
return unless scalar (@data) == 5;
|
||||
|
||||
shift @data;
|
||||
|
||||
my $iterations = shift @data;
|
||||
my $salt = pack ("H*", shift @data);
|
||||
my $ciphertext = pack ("H*", shift @data);
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $salt, $iterations, $ciphertext);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
68
tools/test_modules/m15700.pm
Normal file
68
tools/test_modules/m15700.pm
Normal file
@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Crypt::ScryptKDF qw (scrypt_raw);
|
||||
use Digest::Keccak qw (keccak_256_hex);
|
||||
|
||||
sub module_constraints { [[0, 255], [32, 32], [0, 55], [32, 32], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $salt = shift;
|
||||
my $scrypt_N = shift || 1024 ; # 262144 originally
|
||||
my $scrypt_r = shift || 1; # 8 originally
|
||||
my $scrypt_p = shift || 1;
|
||||
my $ciphertext = shift || random_bytes (32);
|
||||
|
||||
my $derived_key = scrypt_raw ($word, $salt, $scrypt_N, $scrypt_r, $scrypt_p, 32);
|
||||
|
||||
my $derived_key_cropped = substr ($derived_key, 16, 16);
|
||||
|
||||
my $digest = keccak_256_hex ($derived_key_cropped . $ciphertext);
|
||||
|
||||
my $hash = sprintf ("\$ethereum\$s*%i*%i*%i*%s*%s*%s", $scrypt_N, $scrypt_r, $scrypt_p, unpack ("H*", $salt), unpack ("H*", $ciphertext), $digest);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my $signature = substr ($hash, 0, 12);
|
||||
|
||||
return unless ($signature eq "\$ethereum\$s\*");
|
||||
|
||||
my @data = split ('\*', $hash);
|
||||
|
||||
return unless scalar (@data) == 7;
|
||||
|
||||
shift @data;
|
||||
|
||||
my $scrypt_N = shift @data;
|
||||
my $scrypt_r = shift @data;
|
||||
my $scrypt_p = shift @data;
|
||||
my $salt = pack ("H*", shift @data);
|
||||
my $ciphertext = pack ("H*", shift @data);
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $salt, $scrypt_N, $scrypt_r, $scrypt_p, $ciphertext);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
54
tools/test_modules/m16000.pm
Normal file
54
tools/test_modules/m16000.pm
Normal file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Text::Iconv;
|
||||
|
||||
sub module_constraints { [[0, 8], [-1, -1], [0, 8], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
|
||||
my $converter = Text::Iconv->new ("utf-8", "shift-jis");
|
||||
|
||||
$word = $converter->convert ($word);
|
||||
|
||||
my $salt = substr ($word . '..', 1, 2);
|
||||
|
||||
$salt =~ s/[^\.-z]/\./go;
|
||||
|
||||
$salt =~ tr/:;<=>?@[\\]^_`/A-Ga-f/;
|
||||
|
||||
my $digest = crypt ($word, $salt);
|
||||
|
||||
$digest = substr ($digest, -10);
|
||||
|
||||
my $hash = sprintf ("%s", $digest);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
104
tools/test_modules/m16100.pm
Normal file
104
tools/test_modules/m16100.pm
Normal file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::MD5 qw (md5);
|
||||
|
||||
sub module_constraints { [[0, 243], [-1, -1], [0, 43], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $session_id = shift || random_bytes (8);
|
||||
my $encrypted_data = shift;
|
||||
my $sequence = shift || "c006";
|
||||
|
||||
$session_id = pack ("H*", $session_id);
|
||||
|
||||
if (defined $encrypted_data)
|
||||
{
|
||||
$encrypted_data = pack ("H*", $encrypted_data);
|
||||
}
|
||||
|
||||
$sequence = pack ("H*", $sequence);
|
||||
|
||||
my $key = md5 ($session_id . $word . $sequence);
|
||||
|
||||
if (defined $encrypted_data)
|
||||
{
|
||||
## verify case
|
||||
|
||||
my $encrypted_data_len = length $encrypted_data;
|
||||
|
||||
my $plain_data = substr ($encrypted_data, 0, 6) ^ substr ($key, 0, 6);
|
||||
|
||||
my ($status, $flags, $server_msg_len, $data_len) = unpack ("CCnn", $plain_data);
|
||||
|
||||
if ((($status >= 0x01 && $status <= 0x07) || $status == 0x21)
|
||||
&& ($flags == 0x01 || $flags == 0x00)
|
||||
&& (6 + $server_msg_len + $data_len == $encrypted_data_len))
|
||||
{
|
||||
## ok
|
||||
}
|
||||
else
|
||||
{
|
||||
$encrypted_data = ""; # some invalid data
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my $plain_data = "\x01\x00\x00\x00\x00\x00";
|
||||
|
||||
my $plain_data_len = length $plain_data;
|
||||
|
||||
my $shortest = ($plain_data_len > 16) ? 16 : $plain_data_len;
|
||||
|
||||
$encrypted_data = substr ($plain_data, 0, $shortest) ^ substr ($key, 0, $shortest);
|
||||
}
|
||||
|
||||
my $hash = sprintf ('$tacacs-plus$0$%s$%s$%s', unpack ("H*", $session_id), unpack ("H*", $encrypted_data), unpack ("H*", $sequence));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split ('\$', $hash);
|
||||
|
||||
return unless scalar @data == 6;
|
||||
|
||||
shift @data;
|
||||
|
||||
my $signature = shift @data;
|
||||
|
||||
return unless ($signature eq "tacacs-plus");
|
||||
|
||||
my $auth_version = shift @data;
|
||||
|
||||
return unless ($auth_version eq "0");
|
||||
|
||||
my $session_id = shift @data;
|
||||
my $encrypted_data = shift @data;
|
||||
my $sequence = shift @data;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $session_id, $encrypted_data, $sequence);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
164
tools/test_modules/m16200.pm
Normal file
164
tools/test_modules/m16200.pm
Normal file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Crypt::PBKDF2;
|
||||
use Crypt::Mode::ECB;
|
||||
|
||||
sub module_constraints { [[0, 255], [32, 32], [0, 55], [32, 32], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $salt = shift;
|
||||
my $iterations = shift || 20000;
|
||||
my $Z_PK = shift || 1;
|
||||
my $ZCRYPTOWRAPPEDKEY = shift;
|
||||
|
||||
my $salt_bin = pack ("H*", $salt);
|
||||
|
||||
my $pbkdf2 = Crypt::PBKDF2->new
|
||||
(
|
||||
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
||||
iterations => $iterations,
|
||||
output_len => 16,
|
||||
);
|
||||
|
||||
my $KEK = $pbkdf2->PBKDF2 ($salt_bin, $word);
|
||||
|
||||
my $aes = Crypt::Mode::ECB->new ('AES', 0);
|
||||
|
||||
my $blob_bin;
|
||||
|
||||
my $A;
|
||||
my $B;
|
||||
my $P1;
|
||||
my $P2;
|
||||
|
||||
if (defined $ZCRYPTOWRAPPEDKEY)
|
||||
{
|
||||
$blob_bin = pack ("H*", $ZCRYPTOWRAPPEDKEY);
|
||||
|
||||
$A = substr ($blob_bin, 0, 8);
|
||||
$P1 = substr ($blob_bin, 8, 8);
|
||||
$P2 = substr ($blob_bin, 16, 8);
|
||||
|
||||
for (my $j = 5; $j >= 0; $j--)
|
||||
{
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B ^= pack ("Q>", (2 * $j + 2));
|
||||
$B .= $P2;
|
||||
$B = $aes->decrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$P2 = substr ($B, 8, 8);
|
||||
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B ^= pack ("Q>", (2 * $j + 1));
|
||||
$B .= $P1;
|
||||
$B = $aes->decrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$P1 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
if ($A eq "\xa6" x 8)
|
||||
{
|
||||
for (my $j = 0; $j <= 5; $j++)
|
||||
{
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B .= $P1;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 1));
|
||||
$P1 = substr ($B, 8, 8);
|
||||
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B .= $P2;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 2));
|
||||
$P2 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
$blob_bin = $A . $P1 . $P2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$blob_bin = "\xff" x 24;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$A = "\xa6" x 8;
|
||||
$P1 = "\xff" x 8;
|
||||
$P2 = "\xff" x 8;
|
||||
|
||||
for (my $j = 0; $j <= 5; $j++)
|
||||
{
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B .= $P1;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 1));
|
||||
$P1 = substr ($B, 8, 8);
|
||||
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B .= $P2;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 2));
|
||||
$P2 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
$blob_bin = $A . $P1 . $P2;
|
||||
}
|
||||
|
||||
my $hash = sprintf ('$ASN$*%d*%d*%s*%s', $Z_PK, $iterations, unpack ("H*", $salt_bin), unpack ("H*", $blob_bin));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split ('\*', $hash);
|
||||
|
||||
return unless scalar @data == 5;
|
||||
|
||||
my $signature = shift @data;
|
||||
|
||||
return unless ($signature eq '$ASN$');
|
||||
|
||||
my ($Z_PK, $ZCRYPTOITERATIONCOUNT, $ZCRYPTOSALT, $ZCRYPTOWRAPPEDKEY) = @data;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $ZCRYPTOSALT, $ZCRYPTOITERATIONCOUNT, $Z_PK, $ZCRYPTOWRAPPEDKEY);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
111
tools/test_modules/m16300.pm
Normal file
111
tools/test_modules/m16300.pm
Normal file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Crypt::CBC;
|
||||
use Crypt::PBKDF2;
|
||||
use Digest::Keccak qw (keccak_256_hex);
|
||||
|
||||
sub module_constraints { [[0, 255], [40, 40], [0, 55], [40, 40], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $ethaddr = shift;
|
||||
my $encseed = shift;
|
||||
|
||||
my $iv = "";
|
||||
my $seed = "";
|
||||
|
||||
# setup pbkdf2 params:
|
||||
|
||||
my $pbkdf2 = Crypt::PBKDF2->new
|
||||
(
|
||||
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
||||
iterations => 2000,
|
||||
output_len => 16
|
||||
);
|
||||
|
||||
my $key = $pbkdf2->PBKDF2 ($word, $word);
|
||||
|
||||
if (defined $encseed)
|
||||
{
|
||||
$iv = substr ($encseed, 0, 16);
|
||||
$encseed = substr ($encseed, 16);
|
||||
|
||||
# AES-128-CBC decrypt:
|
||||
|
||||
my $aes_cbc = Crypt::CBC->new ({
|
||||
key => $key,
|
||||
cipher => "Crypt::Rijndael",
|
||||
iv => $iv,
|
||||
literal_key => 1,
|
||||
header => "none",
|
||||
keysize => 16
|
||||
});
|
||||
|
||||
$seed = $aes_cbc->decrypt ($encseed);
|
||||
}
|
||||
else
|
||||
{
|
||||
$iv = random_bytes (16);
|
||||
$seed = random_bytes (592);
|
||||
|
||||
# AES-128-CBC encrypt:
|
||||
|
||||
my $aes_cbc = Crypt::CBC->new ({
|
||||
key => $key,
|
||||
cipher => "Crypt::Rijndael",
|
||||
iv => $iv,
|
||||
literal_key => 1,
|
||||
header => "none",
|
||||
keysize => 16
|
||||
});
|
||||
|
||||
$encseed = $aes_cbc->encrypt ($seed);
|
||||
}
|
||||
|
||||
my $digest = keccak_256_hex ($seed . "\x02");
|
||||
|
||||
my $hash = sprintf ("\$ethereum\$w*%s*%s*%s", unpack ("H*", $iv . $encseed), $ethaddr, substr ($digest, 0, 32));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my $signature = substr ($hash, 0, 12);
|
||||
|
||||
return unless ($signature eq "\$ethereum\$w\*");
|
||||
|
||||
my @data = split ('\*', $hash);
|
||||
|
||||
return unless scalar (@data) == 4;
|
||||
|
||||
shift @data;
|
||||
|
||||
my $encseed = pack ("H*", shift @data);
|
||||
my $ethaddr = shift @data;
|
||||
my $bpk = pack ("H*", shift @data);
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $ethaddr, $encseed, $bpk);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
55
tools/test_modules/m16400.pm
Normal file
55
tools/test_modules/m16400.pm
Normal file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::Perl::MD5;
|
||||
|
||||
sub module_constraints { [[0, 64], [-1, -1], [0, 55], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
|
||||
my $md5 = Digest::Perl::MD5->new;
|
||||
my $length = length ($word);
|
||||
|
||||
$md5->{_data} = $word ^ ("\x5c" x $length);
|
||||
$md5->{_data} .= "\x5c" x (64 - $length);
|
||||
$md5->add();
|
||||
|
||||
my $digest = unpack ("H*", pack ('V4', @{$md5->{_state}}));
|
||||
|
||||
my $hash = sprintf ("{CRAM-MD5}%s00000000000000000000000000000000", $digest);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($digest, $word) = split (':', $line);
|
||||
|
||||
return unless defined $digest;
|
||||
return unless defined $word;
|
||||
|
||||
my $signature = substr ($digest, 0, 10);
|
||||
|
||||
return unless ($signature eq "{CRAM-MD5}");
|
||||
|
||||
my $hash = substr ($digest, 10);
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
123
tools/test_modules/m16500.pm
Normal file
123
tools/test_modules/m16500.pm
Normal file
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::SHA qw (sha256 sha384 sha512);
|
||||
use Digest::HMAC qw (hmac);
|
||||
use MIME::Base64 qw (encode_base64url decode_base64url);
|
||||
use JSON qw (encode_json decode_json);
|
||||
|
||||
sub module_constraints { [[0, 64], [-1, -1], [0, 55], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $salt = shift || get_random_jwt_salt ();
|
||||
|
||||
my ($header_base64) = split (/\./, $salt);
|
||||
|
||||
my $header_jwt = decode_base64url ($header_base64);
|
||||
|
||||
my $header = decode_json ($header_jwt);
|
||||
|
||||
my $alg = $header->{"alg"};
|
||||
|
||||
my $digest;
|
||||
|
||||
if ($alg eq "HS256")
|
||||
{
|
||||
$digest = hmac ($salt, $word, \&sha256, 64);
|
||||
}
|
||||
elsif ($alg eq "HS384")
|
||||
{
|
||||
$digest = hmac ($salt, $word, \&sha384, 128);
|
||||
}
|
||||
elsif ($alg eq "HS512")
|
||||
{
|
||||
$digest = hmac ($salt, $word, \&sha512, 128);
|
||||
}
|
||||
else
|
||||
{
|
||||
die "not supported hash\n";
|
||||
}
|
||||
|
||||
my $hash = sprintf ("%s.%s", $salt, encode_base64url ($digest, ""));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split (/\./, $hash);
|
||||
|
||||
return unless scalar @data == 3;
|
||||
|
||||
my ($header, $payload, $signature) = @data;
|
||||
|
||||
my $salt = $header . "." . $payload;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $salt);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
sub get_random_jwt_salt
|
||||
{
|
||||
my @hashes =
|
||||
(
|
||||
"HS256",
|
||||
#"HS384", #this is support in hashcat, but commented out here to prevent mixed hash output files in single mode
|
||||
#"HS512", #this is support in hashcat, but commented out here to prevent mixed hash output files in single mode
|
||||
#"RS256", #not supported by hashcat
|
||||
#"RS384",
|
||||
#"RS512",
|
||||
#"PS256",
|
||||
#"PS384",
|
||||
#"PS512",
|
||||
#"ES256",
|
||||
#"ES384",
|
||||
#"ES512",
|
||||
);
|
||||
|
||||
my $rnd = random_number (0, scalar @hashes - 1);
|
||||
|
||||
my $hash = $hashes[$rnd];
|
||||
|
||||
my $header =
|
||||
{
|
||||
"alg" => $hash
|
||||
};
|
||||
|
||||
my $random_key = random_number (1, 100000000);
|
||||
my $random_val = random_number (1, 100000000);
|
||||
|
||||
my $payload =
|
||||
{
|
||||
$random_key => $random_val
|
||||
};
|
||||
|
||||
my $header_json = encode_json ($header);
|
||||
my $payload_json = encode_json ($payload);
|
||||
|
||||
my $header_base64 = encode_base64url ($header_json, "");
|
||||
my $payload_base64 = encode_base64url ($payload_json, "");
|
||||
|
||||
return $header_base64 . "." . $payload_base64;
|
||||
}
|
||||
|
||||
1;
|
140
tools/test_modules/m16600.pm
Normal file
140
tools/test_modules/m16600.pm
Normal file
@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Digest::SHA qw (sha256);
|
||||
use Crypt::CBC;
|
||||
|
||||
sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $iv = shift || random_hex_string (32);
|
||||
my $salt_type = shift || 1;
|
||||
my $plain_bin = shift;
|
||||
|
||||
if ($salt_type ne "1") { die "currently only salt_type 1 supported\n"; }
|
||||
|
||||
my $key_bin = sha256 (sha256 ($word));
|
||||
|
||||
my $iv_bin = pack ("H*", $iv);
|
||||
|
||||
my $cipher = Crypt::CBC->new ({
|
||||
key => $key_bin,
|
||||
cipher => "Crypt::Rijndael",
|
||||
iv => $iv_bin,
|
||||
literal_key => 1,
|
||||
header => "none",
|
||||
keysize => 32,
|
||||
padding => "null",
|
||||
});
|
||||
|
||||
if (defined $plain_bin)
|
||||
{
|
||||
my $encrypted_bin = pack ("H*", $plain_bin);
|
||||
|
||||
my $test = $cipher->decrypt ($encrypted_bin);
|
||||
|
||||
if ($test =~ /^[0-9a-f]+$/)
|
||||
{
|
||||
$plain_bin = $test;
|
||||
}
|
||||
else
|
||||
{
|
||||
$plain_bin = "\xff" x 16;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my $plain = "30313233343536373839616263646566";
|
||||
|
||||
$plain_bin = pack ("H*", $plain);
|
||||
}
|
||||
|
||||
my $encrypted_bin = $cipher->encrypt ($plain_bin);
|
||||
|
||||
my $encrypted = unpack ("H*", $encrypted_bin);
|
||||
|
||||
my $hash = sprintf ("\$electrum\$%d*%s*%s", $salt_type, $iv, $encrypted);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split (/\*/, $hash);
|
||||
|
||||
return unless scalar @data == 3;
|
||||
|
||||
my ($mode, $iv, $encrypted) = @data;
|
||||
|
||||
my (undef, $signature, $salt_type) = split ('\$', $mode);
|
||||
|
||||
return unless ($signature eq "electrum");
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $iv, $salt_type, $encrypted);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
sub get_random_jwt_salt
|
||||
{
|
||||
my @hashes =
|
||||
(
|
||||
"HS256",
|
||||
#"HS384", #this is support in hashcat, but commented out here to prevent mixed hash output files in single mode
|
||||
#"HS512", #this is support in hashcat, but commented out here to prevent mixed hash output files in single mode
|
||||
#"RS256", #not supported by hashcat
|
||||
#"RS384",
|
||||
#"RS512",
|
||||
#"PS256",
|
||||
#"PS384",
|
||||
#"PS512",
|
||||
#"ES256",
|
||||
#"ES384",
|
||||
#"ES512",
|
||||
);
|
||||
|
||||
my $rnd = random_number (0, scalar @hashes - 1);
|
||||
|
||||
my $hash = $hashes[$rnd];
|
||||
|
||||
my $header =
|
||||
{
|
||||
"alg" => $hash
|
||||
};
|
||||
|
||||
my $random_key = random_number (1, 100000000);
|
||||
my $random_val = random_number (1, 100000000);
|
||||
|
||||
my $payload =
|
||||
{
|
||||
$random_key => $random_val
|
||||
};
|
||||
|
||||
my $header_json = encode_json ($header);
|
||||
my $payload_json = encode_json ($payload);
|
||||
|
||||
my $header_base64 = encode_base64url ($header_json, "");
|
||||
my $payload_base64 = encode_base64url ($payload_json, "");
|
||||
|
||||
return $header_base64 . "." . $payload_base64;
|
||||
}
|
||||
|
||||
1;
|
172
tools/test_modules/m16700.pm
Normal file
172
tools/test_modules/m16700.pm
Normal file
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##
|
||||
## Author......: See docs/credits.txt
|
||||
## License.....: MIT
|
||||
##
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Crypt::PBKDF2;
|
||||
use Crypt::Mode::ECB;
|
||||
|
||||
sub module_constraints { [[0, 255], [32, 32], [0, 55], [32, 32], [-1, -1]] }
|
||||
|
||||
sub module_generate_hash
|
||||
{
|
||||
my $word = shift;
|
||||
my $salt = shift;
|
||||
my $iterations = shift || 20000;
|
||||
my $Z_PK = shift || 1;
|
||||
my $blob_bin = shift;
|
||||
|
||||
my $salt_bin = pack ("H*", $salt);
|
||||
|
||||
my $pbkdf2 = Crypt::PBKDF2->new
|
||||
(
|
||||
hasher => Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256),
|
||||
iterations => $iterations,
|
||||
output_len => 16,
|
||||
);
|
||||
|
||||
my $KEK = $pbkdf2->PBKDF2 ($salt_bin, $word);
|
||||
|
||||
my $aes = Crypt::Mode::ECB->new ('AES', 0);
|
||||
|
||||
my $A;
|
||||
my $B;
|
||||
my $P1;
|
||||
my $P2;
|
||||
|
||||
if (defined $blob_bin)
|
||||
{
|
||||
$blob_bin = pack ("H*", $blob_bin);
|
||||
|
||||
$A = substr ($blob_bin, 0, 8);
|
||||
$P1 = substr ($blob_bin, 8, 8);
|
||||
$P2 = substr ($blob_bin, 16, 8);
|
||||
|
||||
for (my $j = 5; $j >= 0; $j--)
|
||||
{
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B ^= pack ("Q>", (2 * $j + 2));
|
||||
$B .= $P2;
|
||||
$B = $aes->decrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$P2 = substr ($B, 8, 8);
|
||||
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B ^= pack ("Q>", (2 * $j + 1));
|
||||
$B .= $P1;
|
||||
$B = $aes->decrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$P1 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
if ($A eq "\xa6" x 8)
|
||||
{
|
||||
for (my $j = 0; $j <= 5; $j++)
|
||||
{
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B .= $P1;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 1));
|
||||
$P1 = substr ($B, 8, 8);
|
||||
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B .= $P2;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 2));
|
||||
$P2 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
$blob_bin = $A . $P1 . $P2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$blob_bin = "\xff" x 24;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$A = "\xa6" x 8;
|
||||
$P1 = "\xff" x 8;
|
||||
$P2 = "\xff" x 8;
|
||||
|
||||
for (my $j = 0; $j <= 5; $j++)
|
||||
{
|
||||
# N = 1
|
||||
|
||||
$B = $A;
|
||||
$B .= $P1;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 1));
|
||||
$P1 = substr ($B, 8, 8);
|
||||
|
||||
# N = 2
|
||||
|
||||
$B = $A;
|
||||
$B .= $P2;
|
||||
$B = $aes->encrypt ($B, $KEK);
|
||||
$A = substr ($B, 0, 8);
|
||||
$A ^= pack ("Q>", (2 * $j + 2));
|
||||
$P2 = substr ($B, 8, 8);
|
||||
}
|
||||
|
||||
$blob_bin = $A . $P1 . $P2;
|
||||
}
|
||||
|
||||
my $hash = sprintf ('$fvde$%d$%d$%s$%d$%s', $Z_PK, length ($salt_bin), unpack ("H*", $salt_bin), $iterations, unpack ("H*", $blob_bin));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
sub module_verify_hash
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
my ($hash, $word) = split (':', $line);
|
||||
|
||||
return unless defined $hash;
|
||||
return unless defined $word;
|
||||
|
||||
my @data = split ('\$', $hash);
|
||||
|
||||
return unless scalar @data == 7;
|
||||
|
||||
shift @data;
|
||||
|
||||
my $signature = shift @data;
|
||||
|
||||
return unless ($signature eq 'fvde');
|
||||
|
||||
my $Z_PK = shift @data;
|
||||
|
||||
return unless ($Z_PK eq '1');
|
||||
|
||||
my $salt_length = shift @data;
|
||||
|
||||
return unless ($salt_length eq '16');
|
||||
|
||||
my ($ZCRYPTOSALT, $ZCRYPTOITERATIONCOUNT, $ZCRYPTOWRAPPEDKEY) = @data;
|
||||
|
||||
my $word_packed = pack_if_HEX_notation ($word);
|
||||
|
||||
my $new_hash = module_generate_hash ($word_packed, $ZCRYPTOSALT, $ZCRYPTOITERATIONCOUNT, $Z_PK, $ZCRYPTOWRAPPEDKEY);
|
||||
|
||||
return ($new_hash, $word);
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user