You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hashcat/tools/test_modules/m13200.pm

171 lines
3.2 KiB

#!/usr/bin/env perl
##
## Author......: See docs/credits.txt
## License.....: MIT
##
use strict;
use warnings;
use Crypt::Mode::ECB;
use Digest::SHA qw (sha1);
sub module_constraints { [[0, 256], [-1, -1], [-1, -1], [-1, -1], [-1, -1]] }
sub get_random_axcrypt_salt
{
my $mysalt = random_bytes (16);
$mysalt = unpack ("H*", $mysalt);
my $iteration = random_number (6, 99999);
my $salt_buf = $iteration . '*' . $mysalt;
return $salt_buf;
}
sub module_generate_hash
{
my $word = shift;
my $salt = shift;
my $param = shift;
if (length $salt == 0)
{
$salt = get_random_axcrypt_salt ();
}
my @salt_arr = split ('\*', $salt);
my $iteration = $salt_arr[0];
my $mysalt = $salt_arr[1];
$mysalt = pack ("H*", $mysalt);
my $iv = "a6a6a6a6a6a6a6a6";
my $KEK = sha1 ($word);
$KEK = substr ($KEK ^ $mysalt, 0, 16);
my $aes = Crypt::Mode::ECB->new ('AES', 0);
my $B;
my $A;
my @R = ();
if (defined $param)
{
$param = pack ("H*", $param);
$A = substr ($param, 0, 8);
$B = 0x00 x 8;
$R[1] = substr ($param, 8, 8);
$R[2] = substr ($param, 16, 8);
for (my $j = $iteration - 1; $j >= 0; $j--)
{
$A = substr ($A, 0, 8) ^ pack ("l", (2 * $j + 2));
$B = $R[2];
$A = $aes->decrypt (substr ($A . $B . "\x00" x 16, 0, 16), $KEK);
$R[2] = substr ($A, 8, 16);
$A = substr ($A, 0, 8) ^ pack ("l", (2 * $j + 1));
$B = $R[1];
$A = $aes->decrypt (substr ($A . $B . "\x00" x 16, 0, 16), $KEK);
$R[1] = substr ($A, 8, 16);
}
# check if valid
if (index ($A, "\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6") != 0)
{
# fake wrong @R and $A values
@R = ('', "\x00" x 8, "\x00" x 8);
$A = "\x00" x 16;
}
}
else
{
my $DEK = random_hex_string (32);
@R = ('', substr (pack ("H*", $DEK), 0, 8), substr (pack ("H*", $DEK), 8, 16));
$A = pack ("H*", $iv);
}
for (my $j = 0; $j < $iteration; $j++)
{
$B = $aes->encrypt (substr ($A . $R[1] . "\x00" x 16, 0, 16), $KEK);
$A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 1));
$R[1] = substr ($B, 8, 16);
$B = $aes->encrypt (substr ($A . $R[2] . "\x00" x 16, 0, 16), $KEK);
$A = substr ($B, 0, 8) ^ pack ("q", (2 * $j + 2));
$R[2] = substr ($B, 8, 16);
}
my $wrapped_key = unpack ("H*", $A . substr ($R[1], 0 ,8) . substr ($R[2], 0 ,8));
$mysalt = unpack ("H*", $mysalt);
my $hash = sprintf ('$axcrypt$*1*%s*%s*%s', $iteration, $mysalt, $wrapped_key);
return $hash;
}
sub module_verify_hash
{
my $line = shift;
my ($hash_in, $word) = split ":", $line;
return unless defined $hash_in;
return unless defined $word;
my @data = split ('\*', $hash_in);
return unless scalar @data == 5;
my $signature = shift @data;
my $version = shift @data;
my $iteration = shift @data;
my $mysalt = shift @data;
my $digest = shift @data;
return unless ($signature eq '$axcrypt$');
return unless (length ($mysalt) == 32);
return unless (length ($digest) == 48);
my $salt = $iteration . '*' . $mysalt;
my $param = $digest;
return unless defined $salt;
return unless defined $param;
$word = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word, $salt, $param);
return ($new_hash, $word);
}
1;