Created
June 3, 2014 03:17
-
-
Save vdudouyt/7ecc130a6cc6464bb133 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
=pod | |
Ensures that the password matches against NTLM challenge & response. | |
Synopsis: | |
./src/curl --ntlm -uAdministrator:atomic http://192.168.56.101:/WebDav/ -v | |
WWW-Authenticate: NTLM TlRMTVNTUAACAAAABAAEADgAAAAGgokCv9L+7WR398wAAAAAAAAAAIYAhgA8AAAABQLODgAAAA9ETlMxAgAIAEQATgBTADEAAQAIAEQARQBMAEwABAAcAGQAbgBzADEALgBsAG8AYwBhAGwAaABvAHMAdAADACYAZABlAGwAbAAuAGQAbgBzADEALgBsAG8AYwBhAGwAaABvAHMAdAAFABwAZABuAHMAMQAuAGwAbwBjAGEAbABoAG8AcwB0AAAAAAA= | |
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAADQANAHAAAAAEAAQAfQAAAAAAAAAAAAAABoKJAtF4FmQok6yvAAAAAAAAAAAAAAAAAAAAAD9xuQoSt6XlCNB3NXHcuv3CQLGP6YgYQUFkbWluaXN0cmF0b3Job21l | |
perl ntlm_check_passwd.pl TlRMTVNTUAACAAAABAAEADgAAAAGgokCv9L+7WR398wAAAAAAAAAAIYAhgA8AAAABQLODgAAAA9ETlMxAgAIAEQATgBTADEAAQAIAEQARQBMAEwABAAcAGQAbgBzADEALgBsAG8AYwBhAGwAaABvAHMAdAADACYAZABlAGwAbAAuAGQAbgBzADEALgBsAG8AYwBhAGwAaABvAHMAdAAFABwAZABuAHMAMQAuAGwAbwBjAGEAbABoAG8AcwB0AAAAAAA= TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAADQANAHAAAAAEAAQAfQAAAAAAAAAAAAAABoKJAtF4FmQok6yvAAAAAAAAAAAAAAAAAAAAAD9xuQoSt6XlCNB3NXHcuv3CQLGP6YgYQUFkbWluaXN0cmF0b3Job21l atomic | |
1 | |
=cut | |
use strict; | |
use Crypt::DES; | |
use MIME::Base64; | |
use Authen::NTLM::HTTP; | |
use Digest::MD4 qw(md4 md4_hex); | |
use Digest::MD5 qw(md5 md5_hex); | |
use Encode qw(from_to decode encode); | |
use Data::Dumper; | |
sub base16 { | |
join('', map { sprintf('%02x', ord($_)) } split('', $_[0])); | |
} | |
sub unbase16 { | |
my ($hex) = @_; | |
my @out; | |
for(my $i = 0; $i < length($hex); $i+=2) { | |
$out[$i/2] = chr(hex(substr($hex, $i, 2))); | |
} | |
return join('', @out); | |
} | |
sub des_encrypt { Crypt::DES->new($_[0])->encrypt($_[1]) } | |
sub des_decrypt { Crypt::DES->new($_[0])->decrypt($_[1]) } | |
sub key_56_to_64 { | |
my @in = map { ord($_) } split('', $_[0]); | |
my @out; | |
$out[0] = $in[0]; | |
$out[1] = ((($in[0] << 7) & 0xFF) | ($in[1] >> 1)); | |
$out[2] = ((($in[1] << 6) & 0xFF) | ($in[2] >> 2)); | |
$out[3] = ((($in[2] << 5) & 0xFF) | ($in[3] >> 3)); | |
$out[4] = ((($in[3] << 4) & 0xFF) | ($in[4] >> 4)); | |
$out[5] = ((($in[4] << 3) & 0xFF) | ($in[5] >> 5)); | |
$out[6] = ((($in[5] << 2) & 0xFF) | ($in[6] >> 6)); | |
$out[7] = (($in[6] << 1) & 0xFF); | |
return join('', map { chr($_) } @out); | |
} | |
sub zip_to_hash { | |
my ($keys, @values) = @_; | |
my $ret; | |
$ret->{$_} = shift(@values) for @$keys; | |
return $ret; | |
} | |
sub get_server { | |
return new_server Authen::NTLM::HTTP('NTLMSSP_HTTP_WWW', 'localhost'); | |
} | |
sub parse_challenge { | |
zip_to_hash([qw(domain flags nonce ctx_upper ctx_lower)], get_server->http_parse_challenge($_[0])); | |
} | |
sub parse_auth { | |
zip_to_hash([qw(flags lm_resp nt_resp user_domain username machine)], get_server->http_parse_auth($_[0])); | |
} | |
sub build_md5sum { | |
my ($challenge, $auth) = @_; | |
md5($challenge->{nonce}, substr($auth->{lm_resp}, 0, 8)); | |
} | |
sub decode_md5sum { | |
my ($pass, $auth) = @_; | |
my $nthash = md4($pass); | |
my $keys = substr($nthash, 0, 8); | |
my $resp = substr($auth->{nt_resp}, 0, 8); | |
des_decrypt(key_56_to_64($keys), $resp); | |
} | |
sub check_pass { | |
my ($pass, $challenge, $auth) = @_; | |
my $pass_utf16 = encode('UTF-16le', decode('UTF-8', $pass)); | |
my $md5sum = build_md5sum($challenge, $auth); | |
my $answer = decode_md5sum($pass_utf16, $auth); | |
substr($md5sum, 0, 8) eq $answer; | |
} | |
sub print_help_and_exit { | |
print STDERR "Usage: $0 <challenge_base64> <auth_base64> <password>\n"; | |
exit(-1); | |
} | |
&print_help_and_exit() if @ARGV != 3; | |
my ($challenge, $auth, $pass) = (parse_challenge($ARGV[0]), | |
parse_auth($ARGV[1]), | |
$ARGV[2]); | |
print check_pass($pass, $challenge, $auth); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment