Update test_modules and test.pl to respect valid password and salt length ranges per hash mode

pull/1842/head
Jens Steube 5 years ago
parent b20591fb89
commit 5717fcd1a6

@ -15,6 +15,8 @@ use FindBin;
# allows require by filename
use lib "$FindBin::Bin/test_modules";
my $IS_OPTIMIZED = 1;
my $TYPES = [ 'single', 'passthrough', 'verify' ];
my $TYPE = shift @ARGV;
@ -28,6 +30,7 @@ my $MODULE_FILE = sprintf ("m%05d.pm", $MODE);
eval { require $MODULE_FILE } or die "Could not load test module: $MODULE_FILE\n$@";
exists &{module_constraints} or die "Module function 'module_constraints' not found\n";
exists &{module_generate_hash} or die "Module function 'module_generate_hash' not found\n";
exists &{module_verify_hash} or die "Module function 'module_verify_hash' not found\n";
@ -57,35 +60,109 @@ sub single
# fallback to incrementing length
undef $len unless is_count ($len);
my $format = "echo -n %-31s | ./hashcat \${OPTS} -a 0 -m %d '%s'\n";
my $constraints = module_constraints ();
for (my $i = 1; $i <= 31; $i++)
{
# requested or incrementing length
my $cur_len = $len // $i;
my $format = "echo -n %-56s | ./hashcat \${OPTS} -a 0 -m %d '%s'\n";
my $word = random_numeric_string ($cur_len);
my $idx = 0;
my $hash = module_generate_hash ($word);
while ($idx < 8)
{
my $word_len = 0;
if (defined $len)
{
if ($IS_OPTIMIZED == 0)
{
last if $len < $constraints->[0]->[0];
last if $len > $constraints->[0]->[1];
}
else
{
last if $len < $constraints->[2]->[0];
last if $len > $constraints->[2]->[1];
}
$word_len = $len;
}
else
{
$word_len = random_number (($IS_OPTIMIZED == 0) ? $constraints->[0]->[0] : $constraints->[2]->[0],
($IS_OPTIMIZED == 0) ? $constraints->[0]->[1] : $constraints->[2]->[1]);
}
my $salt_len = random_number (($IS_OPTIMIZED == 0) ? $constraints->[1]->[0] : $constraints->[3]->[0],
($IS_OPTIMIZED == 0) ? $constraints->[1]->[1] : $constraints->[3]->[1]);
my $comb_len = $word_len + $salt_len;
if ($IS_OPTIMIZED == 1)
{
my $comb_min = $constraints->[4]->[0];
my $comb_max = $constraints->[4]->[1];
if (($comb_min != -1) && ($comb_max != -1))
{
next if $comb_len < $comb_min;
next if $comb_len > $comb_max;
}
}
$idx++;
my $word = random_numeric_string ($word_len) || "";
my $salt = random_numeric_string ($salt_len) || "";
my $hash = module_generate_hash ($word, $salt);
# possible if the requested length is not supported by algorithm
next unless defined $hash;
print sprintf ($format, $word, $MODE, $hash);
printf ($format, $word, $MODE, $hash);
}
}
sub passthrough
{
my $constraints = module_constraints ();
while (my $word = <>)
{
chomp $word;
my $hash = module_generate_hash ($word);
my $word_len = length $word;
next unless defined $hash;
my $idx = 0;
while ($idx < 1)
{
my $salt_len = random_number (($IS_OPTIMIZED == 0) ? $constraints->[1]->[0] : $constraints->[3]->[0],
($IS_OPTIMIZED == 0) ? $constraints->[1]->[1] : $constraints->[3]->[1]);
my $comb_len = $word_len + $salt_len;
if ($IS_OPTIMIZED == 1)
{
my $comb_min = $constraints->[4]->[0];
my $comb_max = $constraints->[4]->[1];
if (($comb_min != -1) && ($comb_max != -1))
{
next if $comb_len < $comb_min;
next if $comb_len > $comb_max;
}
}
$idx++;
my $salt = random_numeric_string ($salt_len) || "";
my $hash = module_generate_hash ($word, $salt);
next unless defined $hash;
print "$hash\n";
print "$hash\n";
}
}
}
@ -181,9 +258,7 @@ sub random_number
my $min = shift;
my $max = shift;
return unless is_int ($min);
return unless is_int ($max);
return unless $min lt $max;
return if $min > $max;
return int ((rand ($max - $min)) + $min);
}

@ -1,6 +1,6 @@
### Hashcat test modules ###
Each module provides the functions `module_generate_hash` and `module_verify_hash`. The first parameter to `module_generate_hash` is the password, which can be either in ASCII or binary (packed) form. The `module_verify_hash` function accepts a line from the cracks file, without the newline characters.
Each module provides the functions `module_constraints`, `module_generate_hash` and `module_verify_hash`. The `module_constraints` function should return the minimum and maximum length of the password, salt and the combination of password and salt in following order: password (pure), salt (pure), password (optimized), salt (optimized) and combination (optimized). The combination pair should be set to -1 if the hash mode is not concatinating the password and the salt in the same buffer in the kernel (typically raw hashes only). The first parameter to `module_generate_hash` is the password, which can be either in ASCII or binary (packed) form. The second parameter is the salt *which can be undefined for unsalted hash modes). The `module_verify_hash` function accepts a line from the cracks file, without the newline characters.
During `single` and `passthrough` tests the `module_generate_hash` function must provide random values (e.g. salt) for hash generation if necessary. The test.pl script offers a few handy functions like `random_hex_string`, `random_numeric_string` and `random_bytes`. You can implement your own salt generation functions, if your mode has specific requirements.

@ -10,11 +10,15 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [0, 0], [0, 55], [0, 0], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $hash = md5_hex ($word);
my $digest = md5_hex ($word);
my $hash = sprintf ("%s", $digest);
return $hash;
}
@ -30,13 +34,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift;
my $digest = md5_hex ($word . $salt);
my $hash = md5_hex ($word . $salt) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -0,0 +1,42 @@
#!/usr/bin/env perl
##
## Author......: See docs/credits.txt
## License.....: MIT
##
use strict;
use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [30, 30], [0, 55], [30, 30], [30, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift;
my $digest = md5_hex ($word . $salt);
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
sub module_verify_hash
{
my $line = shift;
my ($hash, $salt, $word) = split (':', $line);
return unless defined $hash;
return unless defined $salt;
return unless defined $word;
$word = pack_if_HEX_notation ($word);
return module_generate_hash ($word, $salt);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_string (random_count (15));
my $salt = shift;
my $digest = md5_hex ($word . $salt);
my $hash = md5_hex ($word . $salt) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift;
my $digest = md5_hex ($salt . $word);
my $hash = md5_hex ($salt . $word) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [2, 2], [0, 55], [2, 2], [2, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_hex_string (2);
my $salt = shift;
my $digest = md5_hex ($salt . $word);
my $hash = md5_hex ($salt . $word) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -10,12 +10,19 @@ use warnings;
use Digest::MD5 qw (md5_hex);
sub module_constraints { [[0, 256], [0, 248], [0, 55], [0, 47], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_hex_string (2);
my $salt = shift;
# we need to reduce the maximum salt buffer size by 8 since we
# add it here statically
my $digest = md5_hex ($salt . "\nskyper\n" . $word);
my $hash = md5_hex ($salt . "\nskyper\n" . $word) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +39,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -11,12 +11,16 @@ use warnings;
use Digest::MD5 qw (md5);
use Digest::HMAC qw (hmac hmac_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift);
my $digest = hmac_hex ($salt, $word, \&md5, 64) . ":$salt";
my $hash = hmac_hex ($salt, $word, \&md5, 64) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -33,13 +37,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -11,12 +11,16 @@ use warnings;
use Digest::MD5 qw (md5);
use Digest::HMAC qw (hmac hmac_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift;
my $digest = hmac_hex ($word, $salt, \&md5, 64) . ":$salt";
my $hash = hmac_hex ($word, $salt, \&md5, 64) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -33,13 +37,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -10,11 +10,15 @@ use warnings;
use Digest::SHA qw (sha1_hex);
sub module_constraints { [[0, 256], [0, 0], [0, 55], [0, 0], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $hash = sha1_hex ($word);
my $digest = sha1_hex ($word);
my $hash = sprintf ("%s", $digest);
return $hash;
}
@ -30,13 +34,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::SHA qw (sha1_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift;
my $digest = sha1_hex ($word . $salt);
my $hash = sha1_hex ($word . $salt) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -10,12 +10,16 @@ use warnings;
use Digest::SHA qw (sha1_hex);
sub module_constraints { [[0, 256], [0, 256], [0, 55], [0, 55], [0, 55]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (random_count (15));
my $salt = shift;
my $digest = sha1_hex ($salt . $word);
my $hash = sha1_hex ($salt . $word) . ":$salt";
my $hash = sprintf ("%s:%s", $digest, $salt);
return $hash;
}
@ -32,13 +36,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq "$hash:$salt";
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -11,15 +11,15 @@ use warnings;
use Digest::MD4 qw (md4_hex);
use Encode;
sub module_constraints { [[0, 256], [0, 0], [0, 27], [0, 27], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
return if length $word > 27;
my $hash = md4_hex (encode ('UTF-16LE', $word));
my $digest = md4_hex (encode ('UTF-16LE', $word));
return $hash;
return $digest;
}
sub module_verify_hash
@ -33,13 +33,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word);
}
1;

@ -8,12 +8,12 @@
use strict;
use warnings;
sub module_constraints { [[0, 8], [2, 2], [0, 8], [2, 2], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_numeric_string (2);
return if length $word > 8;
my $salt = shift;
my $hash = crypt ($word, $salt);
@ -33,13 +33,7 @@ sub module_verify_hash
my $salt = substr ($hash, 0, 2);
my $new_hash = module_generate_hash ($word, $salt);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word, $salt);
}
1;

@ -12,14 +12,16 @@ use Digest::HMAC qw (hmac hmac_hex);
use Digest::MD5 qw (md5);
use Encode qw (encode);
sub module_constraints { [[0, 256], [0, 256], [0, 27], [0, 27], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $user = shift;
my $user_len = random_number (0, 27);
my $user_len = length $user;
my $domain_len = 27 - $user_len;
my $user = shift // random_string ($user_len);
my $domain = shift // random_string ($domain_len);
my $srv_ch = shift // random_hex_string (2*8);
my $cli_ch = shift // random_client_challenge ();
@ -29,9 +31,9 @@ sub module_generate_hash
my $nthash = Authen::Passphrase::NTHash->new (passphrase => $word)->hash;
my $identity = encode ('UTF-16LE', uc ($user) . $domain);
my $hash_buf = hmac_hex ($b_srv_ch . $b_cli_ch, hmac ($identity, $nthash, \&md5, 64), \&md5, 64);
my $digest = hmac_hex ($b_srv_ch . $b_cli_ch, hmac ($identity, $nthash, \&md5, 64), \&md5, 64);
my $hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $srv_ch, $hash_buf, $cli_ch);
my $hash = sprintf ("%s::%s:%s:%s:%s", $user, $domain, $srv_ch, $digest, $cli_ch);
return $hash;
}
@ -95,9 +97,9 @@ sub random_client_challenge
my $ch;
$ch .= '0101000000000000';
$ch .= random_hex_string (2*16);
$ch .= random_hex_string (2 * 16);
$ch .= '00000000';
$ch .= random_hex_string(2 * random_count (20));
$ch .= random_hex_string (2 * random_count (20));
$ch .= '00';
return $ch;

@ -12,10 +12,12 @@ use Crypt::Mode::CBC;
use Crypt::PBKDF2;
use Digest::SHA qw (sha256 sha256_hex);
sub module_constraints { [[0, 256], [32, 32], [0, 55], [32, 32], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_hex_string (2*16);
my $salt = shift;
my $iter = shift // 100000;
my $iv = shift // random_hex_string (2*16);
my $plain = shift // random_hex_string (2*1024);
@ -100,13 +102,7 @@ sub module_verify_hash
my $b_plain = $cbc->decrypt ($b_cipher, $key, $b_iv);
my $plain = unpack ('H*', $b_plain);
my $new_hash = module_generate_hash ($word, $salt, $iter, $iv, $plain);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word, $salt, $iter, $iv, $plain);
}
1;

@ -8,9 +8,11 @@
use strict;
use warnings;
use Digest::MD5 qw (md5_hex);
use Digest::MD5 qw (md5_hex);
use Digest::SHA1 qw (sha1_hex);
sub module_constraints { [[0, 256], [0, 0], [0, 55], [0, 0], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
@ -31,13 +33,7 @@ sub module_verify_hash
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word);
}
1;

@ -12,10 +12,12 @@ use Crypt::GCrypt;
use Crypt::PBKDF2;
use Digest::SHA qw (sha1 sha1_hex);
sub module_constraints { [[0, 256], [32, 32], [0, 55], [32, 32], [-1, -1]] }
sub module_generate_hash
{
my $word = shift;
my $salt = shift // random_hex_string (2*16);
my $salt = shift;
my $iter = shift // 100000;
my $iv = shift // random_hex_string (2*8);
my $plain = shift // random_hex_string (2*1024);
@ -126,13 +128,7 @@ sub module_verify_hash
my $plain = unpack ('H*', $b_plain);
my $new_hash = module_generate_hash ($word, $salt, $iter, $iv, $plain);
return unless defined $new_hash;
return unless $new_hash eq $hash;
return $new_hash;
return module_generate_hash ($word, $salt, $iter, $iv, $plain);
}
1;

Loading…
Cancel
Save