Squashed commit of the following:
commit a0b50c394962fc90afc8d6232e1875588ed7ecb3 Author: Alexandre Maloteaux <a.maloteaux@gmail.com> Date: Fri Apr 20 01:45:06 2012 +0100 enumshare: add srvsvc netshareenum request for compatibility with win 7 / 2008r2 [Closes #346]
This commit is contained in:
parent
c27fb73b53
commit
d68d832c9d
|
@ -37,6 +37,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
}
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('USE_SRVSVC_ONLY', [true, "By default a netshareenum request is done on the lanman pipe and if fails a second try is done on srvsvc", false])
|
||||
], self.class)
|
||||
|
||||
deregister_options('RPORT', 'RHOST')
|
||||
end
|
||||
|
||||
|
@ -57,17 +62,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
stypes[val]
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
[[139, false], [445, true]].each do |info|
|
||||
|
||||
datastore['RPORT'] = info[0]
|
||||
datastore['SMBDirect'] = info[1]
|
||||
|
||||
def lanman_netshareenum
|
||||
begin
|
||||
connect
|
||||
smb_login
|
||||
|
||||
res = self.simple.client.trans(
|
||||
"\\PIPE\\LANMAN",
|
||||
(
|
||||
|
@ -77,8 +73,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
[0x01, 65406].pack("vv")
|
||||
)
|
||||
)
|
||||
|
||||
shares = []
|
||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||
#STATUS_NOT_SUPPORTED
|
||||
if( e.error_code == 0xC00000BB )
|
||||
srvsvc_netshareenum
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
lerror, lconv, lentries, lcount = res['Payload'].to_s[
|
||||
res['Payload'].v['ParamOffset'],
|
||||
|
@ -99,22 +100,93 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
scomm,tmp = data[scoff, data.length - scoff].split("\x00")
|
||||
|
||||
shares << [ sname, share_type(stype), scomm]
|
||||
@shares << [ sname, share_type(stype), scomm]
|
||||
end
|
||||
end
|
||||
|
||||
if not shares.empty?
|
||||
print_status("#{ip}:#{rport} #{shares.map{|x| "#{x[0]} - #{x[2]} (#{x[1]})" }.join(", ")}")
|
||||
def srvsvc_netshareenum
|
||||
|
||||
simple.connect("IPC$")
|
||||
handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"])
|
||||
dcerpc_bind(handle)
|
||||
|
||||
stubdata =
|
||||
NDR.uwstring("\\\\#{rhost}") +
|
||||
NDR.long(1) #level
|
||||
|
||||
ref_id = stubdata[0,4].unpack("V")[0]
|
||||
ctr = [1, ref_id + 4 , 0, 0].pack("VVVV")
|
||||
|
||||
stubdata << ctr
|
||||
stubdata << NDR.align(ctr)
|
||||
stubdata << ["FFFFFFFF"].pack("H*")
|
||||
stubdata << [ref_id + 8, 0].pack("VV")
|
||||
response = dcerpc.call(0x0f, stubdata)
|
||||
res = response.dup
|
||||
win_error = res.slice!(-4, 4).unpack("V")[0]
|
||||
if win_error != 0
|
||||
raise "DCE/RPC error : Win_error = #{win_error + 0}"
|
||||
end
|
||||
#remove some uneeded data
|
||||
res.slice!(0,12) # level, CTR header, Reference ID of CTR
|
||||
share_count = res.slice!(0, 4).unpack("V")[0]
|
||||
res.slice!(0,4) # Reference ID of CTR1
|
||||
share_max_count = res.slice!(0, 4).unpack("V")[0]
|
||||
|
||||
raise "Dce/RPC error : Unknow situation encountered count != count max (#{share_count}/#{share_max_count})" if share_max_count != share_count
|
||||
|
||||
types = res.slice!(0, share_count * 12).scan(/.{12}/n).map{|a| a[4,2].unpack("v")[0]} # RerenceID / Type / ReferenceID of Comment
|
||||
|
||||
share_count.times do |t|
|
||||
length, offset, max_length = res.slice!(0, 12).unpack("VVV")
|
||||
raise "Dce/RPC error : Unknow situation encountered offset != 0 (#{offset})" if offset != 0
|
||||
raise "Dce/RPC error : Unknow situation encountered length !=max_length (#{length}/#{max_length})" if length != max_length
|
||||
name = res.slice!(0, 2 * length).gsub('\x00','')
|
||||
res.slice!(0,2) if length % 2 == 1 # pad
|
||||
|
||||
comment_length, comment_offset, comment_max_length = res.slice!(0, 12).unpack("VVV")
|
||||
raise "Dce/RPC error : Unknow situation encountered comment_offset != 0 (#{comment_offset})" if comment_offset != 0
|
||||
if comment_length != comment_max_length
|
||||
raise "Dce/RPC error : Unknow situation encountered comment_length != comment_max_length (#{comment_length}/#{comment_max_length})"
|
||||
end
|
||||
comment = res.slice!(0, 2 * comment_length).gsub('\x00','')
|
||||
res.slice!(0,2) if comment_length % 2 == 1 # pad
|
||||
|
||||
@shares << [ name, share_type(types[t]), comment]
|
||||
end
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
@shares = []
|
||||
|
||||
[[139, false], [445, true]].each do |info|
|
||||
|
||||
datastore['RPORT'] = info[0]
|
||||
datastore['SMBDirect'] = info[1]
|
||||
|
||||
begin
|
||||
connect
|
||||
smb_login
|
||||
if datastore['USE_SRVSVC_ONLY']
|
||||
srvsvc_netshareenum
|
||||
else
|
||||
#If not implemented by target, will fall back to srvsvc_netshareenum
|
||||
lanman_netshareenum
|
||||
end
|
||||
|
||||
if not @shares.empty?
|
||||
print_status("#{ip}:#{rport} #{@shares.map{|x| "#{x[0]} - #{x[2]} (#{x[1]})" }.join(", ")}")
|
||||
report_note(
|
||||
:host => ip,
|
||||
:proto => 'tcp',
|
||||
:port => rport,
|
||||
:type => 'smb.shares',
|
||||
:data => { :shares => shares },
|
||||
:data => { :shares => @shares },
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
disconnect
|
||||
return
|
||||
rescue ::Timeout::Error
|
||||
|
|
Loading…
Reference in New Issue