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/m29200.pm

98 lines
2.6 KiB

#!/usr/bin/env perl
##
## Author......: See docs/credits.txt
## License.....: MIT
##
## Further credits:
## The password-storage algorithm used by Radmin 3 was analyzed and made public
## by synacktiv:
## https://www.synacktiv.com/publications/cracking-radmin-server-3-passwords.html
##
use strict;
use warnings;
use Digest::SHA qw (sha1 sha1_hex);
use Crypt::OpenSSL::Bignum::CTX;
use Encode;
sub module_constraints { [[0, 256], [32, 32], [-1, -1], [-1, -1], [-1, -1]] }
my $GENERATOR = "05";
my $MODULUS = "9847fc7e0f891dfd5d02f19d587d8f77aec0b980d4304b0113b406f23e2cec58cafca04a53e36fb68e0c3bff92cf335786b0dbe60dfe4178ef2fcd2a4dd09947ffd8df96fd0f9e2981a32da95503342eca9f08062cbdd4ac2d7cdf810db4db96db70102266261cd3f8bdd56a102fc6ceedbba5eae99e6127bdd952f7a0d18a79021c881ae63ec4b3590387f548598f2cb8f90dea36fc4f80c5473fdb6b0c6bdb0fdbaf4601f560dd149167ea125db8ad34fd0fd45350dec72cfb3b528ba2332d6091acea89dfd06c9c4d18f697245bd2ac9278b92bfe7dbafaa0c43b40a71f1930ebc4fd24c9e5a2e5a4ccf5d7f51544d70b2bca4af5b8d37b379fd7740a682f";
sub module_generate_hash
{
my $word = shift;
my $salt = shift;
my $user = shift;
if (! defined ($user))
{
$user = random_mixedcase_string (int (rand (128)));
$user = encode ('UTF16-LE', $user);
}
my $word_utf16 = encode ("UTF-16LE", $word);
my $exponent = sha1_hex ($salt . sha1 ($user . ":" . $word_utf16));
my $g = Crypt::OpenSSL::Bignum->new_from_hex ($GENERATOR);
my $m = Crypt::OpenSSL::Bignum->new_from_hex ($MODULUS);
my $e = Crypt::OpenSSL::Bignum->new_from_hex ($exponent);
my $ctx = Crypt::OpenSSL::Bignum::CTX->new ();
my $pow = $g->mod_exp ($e, $m, $ctx);
my $res = $pow->to_bin ();
# IMPORTANT step:
$res = "\x00" x (256 - length ($res)) . $res; # pad it to exactly 256 bytes
my $hash = sprintf ("\$radmin3\$%s*%s*%s", unpack ("H*", $user), unpack ("H*", $salt), unpack ("H*", $res));
return $hash;
}
sub module_verify_hash
{
my $line = shift;
my $idx = index ($line, ':');
return unless $idx >= 0;
my $hash = substr ($line, 0, $idx);
my $word = substr ($line, $idx + 1);
return unless substr ($hash, 0, 9) eq '$radmin3$';
my ($user, $salt, $verifier) = split ('\*', substr ($hash, 9));
return unless defined $user;
return unless defined $salt;
return unless defined $verifier;
return unless length ($salt) == 64;
return unless $user =~ m/^[0-9a-fA-F]*$/;
return unless $salt =~ m/^[0-9a-fA-F]*$/;
return unless $verifier =~ m/^[0-9a-fA-F]*$/;
$salt = pack ("H*", $salt);
$user = pack ("H*", $user);
my $word_packed = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word_packed, $salt, $user);
return ($new_hash, $word);
}
1;