Adds routines/tools for cracking the NTLM hash from the plaintext case-insensive LANMAN password

git-svn-id: file:///home/svn/framework3/trunk@5779 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
HD Moore 2008-10-22 22:42:52 +00:00
parent 16612cacba
commit 65419ad206
3 changed files with 86 additions and 2 deletions

View File

@ -1017,6 +1017,20 @@ SMB_READ_RES_HDR_PKT = Rex::Struct2::CStructTemplate.new(
)
SMB_READ_RES_PKT = self.make_nbs(SMB_READ_RES_HDR_PKT)
# A SMB template for SMB Search requests
SMB_SEARCH_HDR_PKT = Rex::Struct2::CStructTemplate.new(
[ 'template', 'SMB', SMB_HDR ],
[ 'uint16v', 'MaxCount', 0 ],
[ 'uint16v', 'Attributes', 0 ],
[ 'uint16v', 'ByteCount', 0 ],
[ 'string', 'Payload', nil, '' ]
).create_restraints(
[ 'Payload', 'ByteCount', nil, true ]
)
SMB_SEARCH_PKT = self.make_nbs(SMB_SEARCH_HDR_PKT)
# NTLMSSP Message Flags
NEGOTIATE_UNICODE = 0x00000001 # Only set if Type 1 contains it - this or oem, not both
NEGOTIATE_OEM = 0x00000002 # Only set if Type 1 contains it - this or unicode, not both

View File

@ -51,7 +51,18 @@ begin
def self.md5_hash(data)
digest = OpenSSL::Digest::Digest.digest('md5', data)
end
end
def self.lm2nt(pass, ntlm)
res = nil
Rex::Text.permute_case( pass.upcase ).each do |word|
if(md4_hash(Rex::Text.to_unicode(word)) == ntlm)
res = word
break
end
end
res
end
rescue LoadError
end
@ -59,4 +70,4 @@ end
end
end
end
end
end

59
tools/lm2ntcrack.rb Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env ruby
#
# This script cracks a NTLM hash based on the case-insensitive LANMAN password
# Credit to Yannick Hamon <yannick.hamon[at]xmcopartners.com> for the idea/perl code
#
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
$:.unshift(File.join(File.dirname(msfbase), '..', 'lib'))
require 'rex'
def usage
$stderr.puts("\n" + " Usage: #{$0} <options>\n" + $args.usage)
exit
end
ntlm = pass = nil
$args = Rex::Parser::Arguments.new(
"-n" => [ true, "The encypted NTLM hash to crack" ],
"-p" => [ true, "The decrypted LANMAN password" ],
"-h" => [ false, "Display this help information" ])
$args.parse(ARGV) { |opt, idx, val|
case opt
when "-n"
ntlm = val
when "-p"
pass = val
when "-h"
usage
else
usage
end
}
if (not (ntlm and pass))
usage
end
if(ntlm.length != 32)
$stderr.puts "[*] NTLM should be exactly 32 bytes of hexadecimal"
exit
end
if(pass.length > 14)
$stderr.puts "[*] LANMAN password should be between 1 and 14 characters"
exit
end
done = Rex::Proto::SMB::Crypt.lm2nt(pass, [ntlm].pack("H*"))
if(done)
puts "[*] Cracked: LANMAN=#{pass} NTLM=#{done}"
else
puts "[*] Failed to crack password (incorrect input)"
end