lib/rex/proto/ntlm/crypt.rb in librex-0.0.7 vs lib/rex/proto/ntlm/crypt.rb in librex-0.0.12
- old
+ new
@@ -115,12 +115,11 @@
if opt[:pass_is_hash]
ntlmhash = password
else
ntlmhash = ntlm_hash(password, opt)
- end
-
+ end
# With Win 7 and maybe other OSs we sometimes get the domain not uppercased
userdomain = user.upcase + domain
unless opt[:unicode]
userdomain = Rex::Text.to_unicode(userdomain)
end
@@ -170,16 +169,16 @@
key, chal = arg[:ntlmv2_hash], arg[:challenge]
if not (key and chal)
raise ArgumentError , 'ntlmv2_hash and challenge are mandatory'
end
-
+
chal = BASE::pack_int64le(chal) if chal.is_a?(::Integer)
bb = nil
if opt[:nt_client_challenge]
- if opt[:nt_client_challenge].to_s.length <= 24
+ if opt[:nt_client_challenge].to_s.length <= 8
raise ArgumentError,"nt_client_challenge is not in a correct format "
end
bb = opt[:nt_client_challenge]
else
if not arg[:target_info]
@@ -203,11 +202,10 @@
bb = blob.serialize
end
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
-
end
def self.lmv2_response(arg, opt = {})
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
key = arg[:ntlmv2_hash]
@@ -233,9 +231,86 @@
keys = gen_keys(passwd_hash.ljust(21, "\0"))
session_hash = OpenSSL::Digest::MD5.digest(chal + cc)[0,8]
response = apply_des(session_hash, keys).join
[cc.ljust(24, "\0"), response]
end
+
+ #this function will check if the net lm response provided correspond to en empty password
+ def self.is_hash_from_empty_pwd?(arg)
+ hash_type = arg[:type]
+ raise ArgumentError,"arg[:type] is mandatory" if not hash_type
+ raise ArgumentError,"arg[:type] must be lm or ntlm" if not hash_type =~ /^((lm)|(ntlm))$/
+
+ ntlm_ver = arg[:ntlm_ver]
+ raise ArgumentError,"arg[:ntlm_ver] is mandatory" if not ntlm_ver
+
+ hash = arg[:hash]
+ raise ArgumentError,"arg[:hash] is mandatory" if not hash
+
+ srv_chall = arg[:srv_challenge]
+ raise ArgumentError,"arg[:srv_challenge] is mandatory" if not srv_chall
+ raise ArgumentError,"Server challenge length must be exactly 8 bytes" if srv_chall.length != 8
+
+ #calculate responses for empty pwd
+ case ntlm_ver
+ when CONST::NTLM_V1_RESPONSE
+ if hash.length != 24
+ raise ArgumentError,"hash length must be exactly 24 bytes "
+ end
+ case hash_type
+ when 'lm'
+ arglm = { :lm_hash => self.lm_hash(''),
+ :challenge => srv_chall}
+ calculatedhash = self.lm_response(arglm)
+ when 'ntlm'
+ argntlm = { :ntlm_hash => self.ntlm_hash(''),
+ :challenge => srv_chall }
+ calculatedhash = self.ntlm_response(argntlm)
+ end
+ when CONST::NTLM_V2_RESPONSE
+ raise ArgumentError,"hash length must be exactly 16 bytes " if hash.length != 16
+ cli_chall = arg[:cli_challenge]
+ raise ArgumentError,"arg[:cli_challenge] is mandatory in this case" if not cli_chall
+ user = arg[:user]
+ raise ArgumentError,"arg[:user] is mandatory in this case" if not user
+ domain = arg[:domain]
+ raise ArgumentError,"arg[:domain] is mandatory in this case" if not domain
+
+ case hash_type
+ when 'lm'
+ raise ArgumentError,"Client challenge length must be exactly 8 bytes " if cli_chall.length != 8
+ arglm = { :ntlmv2_hash => self.ntlmv2_hash(user,'', domain),
+ :challenge => srv_chall }
+ optlm = { :client_challenge => cli_chall}
+ calculatedhash = self.lmv2_response(arglm, optlm)[0,16]
+ when 'ntlm'
+ raise ArgumentError,"Client challenge length must be bigger then 8 bytes " if cli_chall.length <= 8
+ argntlm = { :ntlmv2_hash => self.ntlmv2_hash(user, '', domain),
+ :challenge => srv_chall }
+ optntlm = { :nt_client_challenge => cli_chall}
+ calculatedhash = self.ntlmv2_response(argntlm,optntlm)[0,16]
+ end
+ when CONST::NTLM_2_SESSION_RESPONSE
+ raise ArgumentError,"hash length must be exactly 16 bytes " if hash.length != 24
+ cli_chall = arg[:cli_challenge]
+ raise ArgumentError,"arg[:cli_challenge] is mandatory in this case" if not cli_chall
+ raise ArgumentError,"Client challenge length must be exactly 8 bytes " if cli_chall.length != 8
+ case hash_type
+ when 'lm'
+ raise ArgumentError, "ntlm2_session is incompatible with lm"
+ when 'ntlm'
+ argntlm = { :ntlm_hash => self.ntlm_hash(''),
+ :challenge => srv_chall }
+ optntlm = { :client_challenge => cli_chall}
+ end
+ calculatedhash = self.ntlm2_session(argntlm,optntlm).join[24,24]
+ else
+ raise ArgumentError,"ntlm_ver is of unknow type"
+ end
+ hash == calculatedhash
+ end
+
+
#
# Signing method added for metasploit project
#