mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-27 02:18:21 +00:00
148 lines
2.8 KiB
Perl
148 lines
2.8 KiB
Perl
|
#!/usr/bin/env perl
|
||
|
|
||
|
##
|
||
|
## Author......: See docs/credits.txt
|
||
|
## License.....: MIT
|
||
|
##
|
||
|
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
|
||
|
use Encode;
|
||
|
use Crypt::RC4;
|
||
|
use Digest::HMAC_MD5 qw (hmac_md5);
|
||
|
use Digest::MD4 qw (md4);
|
||
|
use Digest::MD5 qw (md5_hex);
|
||
|
use POSIX qw (strftime);
|
||
|
|
||
|
sub get_random_kerberos5_salt
|
||
|
{
|
||
|
my $custom_salt = shift;
|
||
|
|
||
|
my $clear_data = random_bytes (14) .
|
||
|
strftime ("%Y%m%d%H%M%S", localtime) .
|
||
|
random_bytes (8);
|
||
|
|
||
|
my $user = "user";
|
||
|
my $realm = "realm";
|
||
|
my $salt = "salt";
|
||
|
|
||
|
my $salt_buf = $user . "\$" . $realm . "\$" . $salt . "\$" . unpack ("H*", $custom_salt) . "\$" . unpack ("H*", $clear_data) . "\$";
|
||
|
|
||
|
return $salt_buf;
|
||
|
}
|
||
|
|
||
|
sub module_constraints { [[0, 255], [16, 16], [0, 27], [16, 16], [-1, -1]] }
|
||
|
|
||
|
sub module_generate_hash
|
||
|
{
|
||
|
my $word_buf = shift;
|
||
|
my $salt_buf = shift;
|
||
|
|
||
|
if ($salt_buf !~ /\$/)
|
||
|
{
|
||
|
$salt_buf = get_random_kerberos5_salt ($salt_buf);
|
||
|
}
|
||
|
|
||
|
my @salt_arr = split ("\\\$", $salt_buf);
|
||
|
|
||
|
my $user = $salt_arr[0];
|
||
|
|
||
|
my $realm = $salt_arr[1];
|
||
|
|
||
|
my $salt = $salt_arr[2];
|
||
|
|
||
|
my $hmac_salt = $salt_arr[3];
|
||
|
my $hmac_salt_bin = pack ("H*", $hmac_salt);
|
||
|
|
||
|
my $clear_data = $salt_arr[4];
|
||
|
|
||
|
my $k = md4 (encode ("UTF-16LE", $word_buf));
|
||
|
|
||
|
my $k1 = hmac_md5 ("\x01\x00\x00\x00", $k);
|
||
|
|
||
|
my $k3 = hmac_md5 ($hmac_salt_bin, $k1);
|
||
|
|
||
|
my $hash_buf;
|
||
|
|
||
|
if (length ($clear_data) > 1)
|
||
|
{
|
||
|
my $clear_data_bin = pack ("H*", $clear_data);
|
||
|
|
||
|
$hash_buf = RC4 ($k3, $clear_data_bin);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
my $hash = $salt_arr[5];
|
||
|
|
||
|
my $hash_bin = pack ("H*", $hash);
|
||
|
|
||
|
my $clear_data = RC4 ($k3, $hash_bin);
|
||
|
|
||
|
my $timestamp = substr ($clear_data, 14, 14);
|
||
|
|
||
|
my $is_numeric = 1;
|
||
|
|
||
|
if ($timestamp !~ /^[[:digit:]]{14}$/)
|
||
|
{
|
||
|
$is_numeric = 0;
|
||
|
}
|
||
|
|
||
|
if (! $is_numeric)
|
||
|
{
|
||
|
$hash_buf = "\x00" x 36;
|
||
|
|
||
|
if ($hash_buf eq $hash_bin)
|
||
|
{
|
||
|
$hash_buf = "\x01" x 36;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$hash_buf = $hash_bin;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
my $tmp_hash = sprintf ("\$krb5pa\$23\$%s\$%s\$%s\$%s%s", $user, $realm, $salt, unpack ("H*", $hash_buf), $hmac_salt);
|
||
|
|
||
|
return $tmp_hash;
|
||
|
}
|
||
|
|
||
|
sub module_verify_hash
|
||
|
{
|
||
|
my $line = shift;
|
||
|
|
||
|
my $index1 = index ($line, "\$", 11);
|
||
|
|
||
|
return if $index1 < 1;
|
||
|
|
||
|
my $index2 = index ($line, "\$", $index1 + 1);
|
||
|
|
||
|
return if $index2 < 1;
|
||
|
|
||
|
my $index3 = index ($line, "\$", $index2 + 1);
|
||
|
|
||
|
return if $index3 < 1;
|
||
|
|
||
|
$index2 = index ($line, ":", $index3 + 1);
|
||
|
|
||
|
return if $index2 < 1;
|
||
|
|
||
|
my $hash_in = substr ($line, 0, $index2);
|
||
|
my $word = substr ($line, $index2 + 1);
|
||
|
|
||
|
my $salt;
|
||
|
|
||
|
$salt = substr ($hash_in, 11, $index3 - 10);
|
||
|
$salt .= substr ($hash_in, $index2 - 32) . "\$\$";
|
||
|
$salt .= substr ($hash_in, $index3 + 1, $index2 - $index3 - 32 - 1);
|
||
|
|
||
|
my $word_packed = pack_if_HEX_notation ($word);
|
||
|
|
||
|
my $new_hash = module_generate_hash ($word_packed, $salt);
|
||
|
|
||
|
return ($new_hash, $word);
|
||
|
}
|
||
|
|
||
|
1;
|