mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-23 15:08:37 +00:00
Merge pull request #4329 from matrix/install_modules
Unit tests: Updated install_modules.sh
This commit is contained in:
commit
fb70746f5f
@ -165,6 +165,9 @@
|
|||||||
- Unit tests: Updated install_modules.sh with Crypt::Argon2
|
- Unit tests: Updated install_modules.sh with Crypt::Argon2
|
||||||
- Unit tests: Updated install_modules.sh with Crypt::Passwd::XS, to test suite works also on Apple (ex: 1800)
|
- Unit tests: Updated install_modules.sh with Crypt::Passwd::XS, to test suite works also on Apple (ex: 1800)
|
||||||
- Unit tests: Updated install_modules.sh to use an external module for Digest::BLAKE2, due to maintenance being discontinued
|
- Unit tests: Updated install_modules.sh to use an external module for Digest::BLAKE2, due to maintenance being discontinued
|
||||||
|
- Unit tests: Updated install_modules.sh to use an external package for pygost, due to not available anymore
|
||||||
|
- Unit tests: Updated install_modules.sh to use cpanm instead of cpan
|
||||||
|
- Unit tests: Updated install_modules.sh to remove php and Crypt::GCrypt (updated relative test modules)
|
||||||
- User Options: Added error message when mixing --username and --show to warn users of exponential delay
|
- User Options: Added error message when mixing --username and --show to warn users of exponential delay
|
||||||
- MetaMask: update extraction tool to support MetaMask Mobile wallets
|
- MetaMask: update extraction tool to support MetaMask Mobile wallets
|
||||||
- SecureCRT MasterPassphrase v2: update module, pure kernels and test unit. Add optimized kernels.
|
- SecureCRT MasterPassphrase v2: update module, pure kernels and test unit. Add optimized kernels.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
##
|
##
|
||||||
## Author......: See docs/credits.txt
|
## Author......: See docs/credits.txt
|
||||||
@ -7,108 +7,169 @@
|
|||||||
|
|
||||||
## Test suite installation helper script
|
## Test suite installation helper script
|
||||||
|
|
||||||
|
IS_APPLE=0
|
||||||
|
IS_APPLE_SILICON=0
|
||||||
|
|
||||||
|
UNAME=$(uname -s)
|
||||||
|
if [ "${UNAME}" == "Darwin" ]; then
|
||||||
|
IS_APPLE=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${IS_APPLE} -eq 1 ]; then
|
||||||
|
if [ "$(sysctl -in hw.optional.arm64 2>/dev/null)" == "1" ]; then
|
||||||
|
IS_APPLE_SILICON=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Sum of all exit codes
|
# Sum of all exit codes
|
||||||
ERRORS=0
|
ERRORS=0
|
||||||
|
|
||||||
cpan install Authen::Passphrase::LANManager \
|
echo "> Installing perl deps ..."
|
||||||
Authen::Passphrase::MySQL323 \
|
|
||||||
Authen::Passphrase::NTHash \
|
if [ ${IS_APPLE} -eq 1 ]; then
|
||||||
Authen::Passphrase::PHPass \
|
# workaround for test failed with Net::SSLeay on Apple
|
||||||
Bitcoin::Crypto \
|
cpanm --notest Net::SSLeay
|
||||||
Bitcoin::Crypto::Base58 \
|
else
|
||||||
Compress::Zlib \
|
cpanm Net::SSLeay
|
||||||
Convert::EBCDIC \
|
fi
|
||||||
Crypt::Argon2 \
|
|
||||||
Crypt::AuthEnc::GCM \
|
ERRORS=$((ERRORS+$?))
|
||||||
Crypt::Camellia \
|
|
||||||
Crypt::CBC \
|
cpanm Authen::Passphrase::LANManager \
|
||||||
Crypt::Cipher::Serpent \
|
Authen::Passphrase::MySQL323 \
|
||||||
Crypt::DES \
|
Authen::Passphrase::NTHash \
|
||||||
Crypt::DES_EDE3 \
|
Authen::Passphrase::PHPass \
|
||||||
Crypt::Digest::BLAKE2s_256 \
|
Bitcoin::Crypto \
|
||||||
Crypt::Digest::RIPEMD160 \
|
Bitcoin::Crypto::Base58 \
|
||||||
Crypt::Digest::Whirlpool \
|
Compress::Zlib \
|
||||||
Crypt::ECB \
|
Convert::EBCDIC \
|
||||||
Crypt::Eksblowfish::Bcrypt \
|
Crypt::Argon2 \
|
||||||
Crypt::GCrypt \
|
Crypt::AuthEnc::GCM \
|
||||||
Crypt::Mode::CBC \
|
Crypt::Blowfish \
|
||||||
Crypt::Mode::ECB \
|
Crypt::Camellia \
|
||||||
Crypt::MySQL \
|
Crypt::CBC \
|
||||||
Crypt::OpenSSH::ChachaPoly \
|
Crypt::Cipher::Serpent \
|
||||||
Crypt::OpenSSL::EC \
|
Crypt::DES \
|
||||||
Crypt::OpenSSL::Bignum::CTX \
|
Crypt::DES_EDE3 \
|
||||||
Crypt::Passwd::XS \
|
Crypt::Digest::BLAKE2s_256 \
|
||||||
Crypt::PBKDF2 \
|
Crypt::Digest::RIPEMD160 \
|
||||||
Crypt::RC4 \
|
Crypt::Digest::Whirlpool \
|
||||||
Crypt::Rijndael \
|
Crypt::ECB \
|
||||||
Crypt::ScryptKDF \
|
Crypt::Eksblowfish::Bcrypt \
|
||||||
Crypt::Skip32 \
|
Crypt::Mode::CBC \
|
||||||
Crypt::Twofish \
|
Crypt::Mode::ECB \
|
||||||
Crypt::UnixCrypt_XS \
|
Crypt::MySQL \
|
||||||
Data::Types \
|
Crypt::OpenSSH::ChachaPoly \
|
||||||
Digest::CMAC \
|
Crypt::OpenSSL::EC \
|
||||||
Digest::CRC \
|
Crypt::OpenSSL::Bignum::CTX \
|
||||||
Digest::GOST \
|
Crypt::Passwd::XS \
|
||||||
Digest::HMAC \
|
Crypt::PBKDF2 \
|
||||||
Digest::HMAC_MD5 \
|
Crypt::RC4 \
|
||||||
Digest::Keccak \
|
Crypt::Rijndael \
|
||||||
Digest::MD4 \
|
Crypt::ScryptKDF \
|
||||||
Digest::MD5 \
|
Crypt::Skip32 \
|
||||||
Digest::MurmurHash3 \
|
Crypt::Twofish \
|
||||||
Digest::Perl::MD5 \
|
Crypt::UnixCrypt_XS \
|
||||||
Digest::SHA \
|
CryptX \
|
||||||
Digest::SHA1 \
|
Data::Types \
|
||||||
Digest::SHA3 \
|
Digest::CMAC \
|
||||||
Digest::SipHash \
|
Digest::CRC \
|
||||||
Encode \
|
Digest::GOST \
|
||||||
JSON \
|
Digest::HMAC \
|
||||||
Math::BigInt \
|
Digest::HMAC_MD5 \
|
||||||
MIME::Base64 \
|
Digest::Keccak \
|
||||||
Net::DNS::RR::NSEC3 \
|
Digest::MD4 \
|
||||||
Net::DNS::SEC \
|
Digest::MD5 \
|
||||||
POSIX \
|
Digest::MurmurHash3 \
|
||||||
Text::Iconv \
|
Digest::Perl::MD5 \
|
||||||
;
|
Digest::SHA \
|
||||||
|
Digest::SHA1 \
|
||||||
|
Digest::SHA3 \
|
||||||
|
Digest::SipHash \
|
||||||
|
Encode \
|
||||||
|
JSON \
|
||||||
|
Math::BigInt \
|
||||||
|
MIME::Base64 \
|
||||||
|
Module::Build \
|
||||||
|
Module::Build::Pluggable::XSUtil \
|
||||||
|
Net::DNS::RR::NSEC3 \
|
||||||
|
Net::DNS::SEC \
|
||||||
|
POSIX \
|
||||||
|
Text::Iconv \
|
||||||
|
;
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
cpanm https://github.com/matrix/p5-Digest-BLAKE2.git
|
cpanm https://github.com/matrix/p5-Digest-BLAKE2.git
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
pip3 install pygost
|
# checks for pyenv
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
pyenv_enabled=0
|
||||||
|
|
||||||
# pip3 uninstall -y pycryptoplus pycrypto pycryptodome
|
which pyenv &>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
|
||||||
pip3 install pycryptoplus
|
if [[ $(pyenv version-name) != "system" ]]; then
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
# active session detected
|
||||||
|
pyenv_enabled=1
|
||||||
|
|
||||||
# pip3 uninstall -y pycryptodome # latest versions do not require this work around anymore
|
else
|
||||||
pip3 install pycrypto
|
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
# enum last version available
|
||||||
|
latest=$(pyenv install --list | grep -E "^\s*3\.[0-9]+\.[0-9]$" | tail -n 1)
|
||||||
|
|
||||||
pip3 install cryptography
|
if [ $IS_APPLE -eq 1 ]; then
|
||||||
|
if [ $IS_APPLE_SILICON -eq 0 ]; then
|
||||||
|
# workaround but with pyenv and Apple Intel with brew binutils in path
|
||||||
|
remove_path="$(brew --prefix)/opt/binutils/bin"
|
||||||
|
PATH=$(echo "$PATH" | tr ':' '\n' | awk '$0 != "${remove_path}"' | xargs | sed 's/ /:/g')
|
||||||
|
export $PATH
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
ERRORS=$((ERRORS+$?))
|
# install the latest version or skip it if it is already present
|
||||||
|
pyenv install -s ${latest}
|
||||||
|
|
||||||
php --version > /dev/null 2> /dev/null
|
# enable
|
||||||
|
pyenv local $latest
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
pyenv_enabled=1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$?" -ne 0 ]
|
fi
|
||||||
then
|
fi
|
||||||
echo '[ ERROR ] php must be installed for some unit tests'
|
|
||||||
|
if [ ${pyenv_enabled} -eq 0 ]; then
|
||||||
|
|
||||||
|
echo "! something is wrong with pyenv. Please setup latest version manually and re-run this script."
|
||||||
|
(( ERRORS++ ))
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "> Installing python3 deps ..."
|
||||||
|
|
||||||
|
pip3 install git+https://github.com/matrix/pygost
|
||||||
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
|
pip3 install pycryptoplus
|
||||||
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
|
pip3 install pycryptodome
|
||||||
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
|
pip3 install cryptography
|
||||||
|
ERRORS=$((ERRORS+$?))
|
||||||
|
|
||||||
ERRORS=$((ERRORS+1))
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
if [ $ERRORS -eq 0 ]; then
|
|
||||||
echo '[ OK ] All commands were successful'
|
if [ $ERRORS -gt 0 ]; then
|
||||||
exit 0
|
echo "[ FAIL ] Some commands were not successful"
|
||||||
else
|
|
||||||
echo '[ FAIL ] Some commands were not successful'
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "[ OK ] All commands were successful"
|
||||||
|
exit 0
|
||||||
|
@ -10,9 +10,44 @@ use warnings;
|
|||||||
|
|
||||||
use Crypt::PBKDF2;
|
use Crypt::PBKDF2;
|
||||||
use MIME::Base64 qw (encode_base64 decode_base64);
|
use MIME::Base64 qw (encode_base64 decode_base64);
|
||||||
|
use Digest::HMAC qw(hmac);
|
||||||
|
use Digest::MD5 qw(md5);
|
||||||
|
|
||||||
sub module_constraints { [[0, 256], [1, 15], [-1, -1], [-1, -1], [-1, -1]] }
|
sub module_constraints { [[0, 256], [1, 15], [-1, -1], [-1, -1], [-1, -1]] }
|
||||||
|
|
||||||
|
sub pbkdf2_md5
|
||||||
|
{
|
||||||
|
my ($password, $salt, $iterations, $key_length) = @_;
|
||||||
|
$iterations ||= 1000;
|
||||||
|
$key_length ||= 32;
|
||||||
|
|
||||||
|
my $hash_length = 16; # MD5 outputs 16 bytes
|
||||||
|
my $block_count = int( ($key_length + $hash_length - 1) / $hash_length );
|
||||||
|
|
||||||
|
my $output = '';
|
||||||
|
|
||||||
|
for my $i (1 .. $block_count)
|
||||||
|
{
|
||||||
|
# pack N = big endian 32-bit
|
||||||
|
my $block_index = pack('N', $i);
|
||||||
|
|
||||||
|
# Initial U1 = HMAC(password, salt || block_index)
|
||||||
|
my $u = hmac($salt . $block_index, $password, \&md5);
|
||||||
|
|
||||||
|
my $t = $u;
|
||||||
|
|
||||||
|
for (my $j = 1; $j < $iterations; $j++)
|
||||||
|
{
|
||||||
|
$u = hmac($u, $password, \&md5);
|
||||||
|
$t ^= $u;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= $t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return substr($output, 0, $key_length);
|
||||||
|
}
|
||||||
|
|
||||||
sub module_generate_hash
|
sub module_generate_hash
|
||||||
{
|
{
|
||||||
my $word = shift;
|
my $word = shift;
|
||||||
@ -20,98 +55,15 @@ sub module_generate_hash
|
|||||||
my $iterations = shift // 1000;
|
my $iterations = shift // 1000;
|
||||||
my $out_len = shift // 32;
|
my $out_len = shift // 32;
|
||||||
|
|
||||||
#
|
# Generate derived key (binary)
|
||||||
# call PHP here - WTF
|
my $derived_key = pbkdf2_md5($word, $salt, $iterations, $out_len);
|
||||||
#
|
|
||||||
|
|
||||||
# sanitize $word_buf and $salt_buf:
|
# base64 encode salt and derived key
|
||||||
|
my $base64_salt = encode_base64($salt, '');
|
||||||
|
my $base64_key = encode_base64($derived_key, '');
|
||||||
|
|
||||||
my $word_buf_base64 = encode_base64 ($word, "");
|
# Format output string
|
||||||
my $salt_buf_base64 = encode_base64 ($salt, "");
|
return sprintf("md5:%d:%s:%s", $iterations, $base64_salt, $base64_key);
|
||||||
|
|
||||||
# sanitize lengths
|
|
||||||
|
|
||||||
$out_len = int ($out_len);
|
|
||||||
|
|
||||||
# output is in hex encoding, otherwise it could be screwed (but shouldn't)
|
|
||||||
|
|
||||||
my $php_code = <<'END_CODE';
|
|
||||||
|
|
||||||
function pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
|
|
||||||
{
|
|
||||||
$algorithm = strtolower ($algorithm);
|
|
||||||
|
|
||||||
if (! in_array ($algorithm, hash_algos (), true))
|
|
||||||
{
|
|
||||||
trigger_error ("PBKDF2 ERROR: Invalid hash algorithm.", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($count <= 0 || $key_length <= 0)
|
|
||||||
{
|
|
||||||
trigger_error ("PBKDF2 ERROR: Invalid parameters.", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (function_exists ("hash_pbkdf2"))
|
|
||||||
{
|
|
||||||
if (!$raw_output)
|
|
||||||
{
|
|
||||||
$key_length = $key_length * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash_pbkdf2 ($algorithm, $password, $salt, $count, $key_length, $raw_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
$hash_length = strlen (hash ($algorithm, "", true));
|
|
||||||
$block_count = ceil ($key_length / $hash_length);
|
|
||||||
|
|
||||||
$output = "";
|
|
||||||
|
|
||||||
for ($i = 1; $i <= $block_count; $i++)
|
|
||||||
{
|
|
||||||
$last = $salt . pack ("N", $i);
|
|
||||||
|
|
||||||
$last = $xorsum = hash_hmac ($algorithm, $last, $password, true);
|
|
||||||
|
|
||||||
for ($j = 1; $j < $count; $j++)
|
|
||||||
{
|
|
||||||
$xorsum ^= ($last = hash_hmac ($algorithm, $last, $password, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
$output .= $xorsum;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($raw_output)
|
|
||||||
{
|
|
||||||
return substr ($output, 0, $key_length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return bin2hex (substr ($output, 0, $key_length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print pbkdf2 ("md5", base64_decode ("$word_buf_base64"), base64_decode ("$salt_buf_base64"), $iterations, $out_len, False);
|
|
||||||
|
|
||||||
END_CODE
|
|
||||||
|
|
||||||
# replace with these command line arguments
|
|
||||||
|
|
||||||
$php_code =~ s/\$word_buf_base64/$word_buf_base64/;
|
|
||||||
$php_code =~ s/\$salt_buf_base64/$salt_buf_base64/;
|
|
||||||
$php_code =~ s/\$iterations/$iterations/;
|
|
||||||
$php_code =~ s/\$out_len/$out_len/;
|
|
||||||
|
|
||||||
my $php_output = `php -r '$php_code'`;
|
|
||||||
|
|
||||||
my $hash_buf = pack ("H*", $php_output);
|
|
||||||
|
|
||||||
$hash_buf = encode_base64 ($hash_buf, "");
|
|
||||||
|
|
||||||
my $base64_salt_buf = encode_base64 ($salt, "");
|
|
||||||
|
|
||||||
my $hash = sprintf ("md5:%i:%s:%s", $iterations, $base64_salt_buf, $hash_buf);
|
|
||||||
|
|
||||||
return $hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub module_verify_hash
|
sub module_verify_hash
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Crypt::GCrypt;
|
use Crypt::Blowfish;
|
||||||
|
use Crypt::Mode::CFB;
|
||||||
use Crypt::PBKDF2;
|
use Crypt::PBKDF2;
|
||||||
use Digest::SHA qw (sha1 sha1_hex);
|
use Digest::SHA qw (sha1 sha1_hex);
|
||||||
|
|
||||||
@ -36,20 +37,9 @@ sub module_generate_hash
|
|||||||
my $pass_hash = sha1 ($word);
|
my $pass_hash = sha1 ($word);
|
||||||
my $key = $kdf->PBKDF2 ($b_salt, $pass_hash);
|
my $key = $kdf->PBKDF2 ($b_salt, $pass_hash);
|
||||||
|
|
||||||
my $cfb = Crypt::GCrypt->new
|
my $cfb = Crypt::Mode::CFB->new('Blowfish');
|
||||||
(
|
|
||||||
type => 'cipher',
|
|
||||||
algorithm => 'blowfish',
|
|
||||||
mode => 'cfb'
|
|
||||||
);
|
|
||||||
|
|
||||||
$cfb->start ('encrypting');
|
my $b_cipher = $cfb->encrypt($b_plain, $key, $b_iv);
|
||||||
$cfb->setkey ($key);
|
|
||||||
$cfb->setiv ($b_iv);
|
|
||||||
|
|
||||||
my $b_cipher = $cfb->encrypt ($b_plain);
|
|
||||||
|
|
||||||
$cfb->finish ();
|
|
||||||
|
|
||||||
my $cipher = unpack ('H*', $b_cipher);
|
my $cipher = unpack ('H*', $b_cipher);
|
||||||
my $checksum = sha1_hex ($b_plain);
|
my $checksum = sha1_hex ($b_plain);
|
||||||
@ -113,19 +103,9 @@ sub module_verify_hash
|
|||||||
my $pass_hash = sha1 ($word);
|
my $pass_hash = sha1 ($word);
|
||||||
my $key = $kdf->PBKDF2 ($b_salt, $pass_hash);
|
my $key = $kdf->PBKDF2 ($b_salt, $pass_hash);
|
||||||
|
|
||||||
my $cfb = Crypt::GCrypt->new (
|
my $cfb = Crypt::Mode::CFB->new('Blowfish');
|
||||||
type => 'cipher',
|
|
||||||
algorithm => 'blowfish',
|
|
||||||
mode => 'cfb'
|
|
||||||
);
|
|
||||||
|
|
||||||
$cfb->start ('decrypting');
|
my $b_plain = $cfb->decrypt($b_cipher, $key, $b_iv);
|
||||||
$cfb->setkey ($key);
|
|
||||||
$cfb->setiv ($b_iv);
|
|
||||||
|
|
||||||
my $b_plain = $cfb->decrypt ($b_cipher);
|
|
||||||
|
|
||||||
$cfb->finish ();
|
|
||||||
|
|
||||||
my $plain = unpack ('H*', $b_plain);
|
my $plain = unpack ('H*', $b_plain);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user