module Watobo::NTLM
Constants
- BLOB_SIGN
- DEFAULT_FLAGS
- FLAGS
- FLAG_KEYS
- LM_MAGIC
- MAX64
- SSP_SIGN
- TIME_OFFSET
Public Class Methods
apply_des(plain, keys)
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 168 def apply_des(plain, keys) dec = OpenSSL::Cipher::DES.new keys.map {|k| dec.key = k dec.encrypt.update(plain) } end
gen_keys(str)
click to toggle source
Not sure what this is doing @param [String] str String
to generate keys for @api private
# File lib/watobo/utils/ntlm.rb, line 160 def gen_keys(str) split7(str).map{ |str7| bits = split7(str7.unpack("B*")[0]).inject('')\ {|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s } [bits].pack("B*") } end
lm_hash(password)
click to toggle source
Generates a Lan Manager Hash @param [String] password The password to base the hash on
# File lib/watobo/utils/ntlm.rb, line 178 def lm_hash(password) keys = gen_keys password.upcase.ljust(14, "\0") apply_des(LM_MAGIC, keys).join end
lm_response(arg)
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 208 def lm_response(arg) begin hash = arg[:lm_hash] chal = arg[:challenge] rescue raise ArgumentError end chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer) keys = gen_keys hash.ljust(21, "\0") apply_des(chal, keys).join end
lmv2_response(arg, opt = {})
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 262 def lmv2_response(arg, opt = {}) key = arg[:ntlmv2_hash] chal = arg[:challenge] chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer) if opt[:client_challenge] cc = opt[:client_challenge] else cc = rand(MAX64) end cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer) OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc end
ntlm2_session(arg, opt = {})
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 278 def ntlm2_session(arg, opt = {}) begin passwd_hash = arg[:ntlm_hash] chal = arg[:challenge] rescue raise ArgumentError end if opt[:client_challenge] cc = opt[:client_challenge] else cc = rand(MAX64) end cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer) keys = gen_keys passwd_hash.ljust(21, "\0") session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8) response = apply_des(session_hash, keys).join [cc.ljust(24, "\0"), response] end
ntlm_hash(password, opt = {})
click to toggle source
Generate a NTLM
Hash @param [String] password The password to base the hash on @option opt :unicode (false) Unicode encode the password
# File lib/watobo/utils/ntlm.rb, line 186 def ntlm_hash(password, opt = {}) pwd = password.dup unless opt[:unicode] pwd = EncodeUtil.encode_utf16le(pwd) end OpenSSL::Digest::MD4.digest pwd end
ntlm_response(arg)
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 220 def ntlm_response(arg) hash = arg[:ntlm_hash] chal = arg[:challenge] chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer) keys = gen_keys hash.ljust(21, "\0") apply_des(chal, keys).join end
ntlmv2_hash(user, password, target, opt={})
click to toggle source
Generate a NTLMv2 Hash @param [String] user The username @param [String] password The password @param [String] target The domain or workstaiton to authenticate to @option opt :unicode (false) Unicode encode the domain
# File lib/watobo/utils/ntlm.rb, line 199 def ntlmv2_hash(user, password, target, opt={}) ntlmhash = ntlm_hash(password, opt) userdomain = (user + target).upcase unless opt[:unicode] userdomain = EncodeUtil.encode_utf16le(userdomain) end OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain) end
ntlmv2_response(arg, opt = {})
click to toggle source
# File lib/watobo/utils/ntlm.rb, line 228 def ntlmv2_response(arg, opt = {}) begin key = arg[:ntlmv2_hash] chal = arg[:challenge] ti = arg[:target_info] rescue raise ArgumentError end chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer) if opt[:client_challenge] cc = opt[:client_challenge] else cc = rand(MAX64) end cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer) if opt[:timestamp] ts = opt[:timestamp] else ts = Time.now.to_i end # epoch -> milsec from Jan 1, 1601 ts = 10000000 * (ts + TIME_OFFSET) blob = Blob.new blob.timestamp = ts blob.challenge = cc blob.target_info = ti bb = blob.serialize OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb end
pack_int64le(val)
click to toggle source
Conver the value to a 64-Bit Little Endian Int @param [String] val The string to convert
# File lib/watobo/utils/ntlm.rb, line 142 def pack_int64le(val) [val & 0x00000000ffffffff, val >> 32].pack("V2") end
split7(str)
click to toggle source
Builds an array of strings that are 7 characters long @param [String] str The string to split @api private
# File lib/watobo/utils/ntlm.rb, line 149 def split7(str) s = str.dup until s.empty? (ret ||= []).push s.slice!(0, 7) end ret end