mirror of
https://github.com/hashcat/hashcat
synced 2024-12-09 02:13:10 +01:00
105 lines
2.2 KiB
Perl
105 lines
2.2 KiB
Perl
|
#!/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;
|