Implement proto/smb/client find_next for find_files

Squashed commit of the following:

commit b5370b24d48a0b79d13cff465ef1fe53738754d0
Author: Rob Fuller <jd.mubix@gmail.com>
Date:   Sat Jul 21 01:52:31 2012 -0400

    add some documentation for smb client

commit 92438f515ef272337ce02b6deebb35f62a50f0a3
Author: Rob Fuller <jd.mubix@gmail.com>
Date:   Fri Jul 20 03:09:27 2012 -0400

    adds find_next to find_files

[Closes #627]
unstable
Rob Fuller 2012-07-21 00:03:19 -06:00 committed by James Lee
parent 99aa78a371
commit 70017511f5
1 changed files with 65 additions and 57 deletions

View File

@ -1830,7 +1830,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
files = { }
parm = [
26, # Search for ALL files
512, # Maximum search count
20, # Maximum search count
6, # Resume and Close on End of Search
260, # Level of interest
0, # Storage type is zero
@ -1838,57 +1838,67 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
begin
resp = trans2(CONST::TRANS2_FIND_FIRST2, parm, '')
search_next = 0
begin
pcnt = resp['Payload'].v['ParamCount']
dcnt = resp['Payload'].v['DataCount']
poff = resp['Payload'].v['ParamOffset']
doff = resp['Payload'].v['DataOffset']
pcnt = resp['Payload'].v['ParamCount']
dcnt = resp['Payload'].v['DataCount']
poff = resp['Payload'].v['ParamOffset']
doff = resp['Payload'].v['DataOffset']
# Get the raw packet bytes
resp_rpkt = resp.to_s
# Get the raw packet bytes
resp_rpkt = resp.to_s
# Remove the NetBIOS header
resp_rpkt.slice!(0, 4)
# Remove the NetBIOS header
resp_rpkt.slice!(0, 4)
resp_parm = resp_rpkt[poff, pcnt]
resp_data = resp_rpkt[doff, dcnt]
resp_parm = resp_rpkt[poff, pcnt]
resp_data = resp_rpkt[doff, dcnt]
# search id, search count, end of search, error offset, last name offset
sid, scnt, eos, eoff, loff = resp_parm.unpack('v5')
didx = 0
while (didx < resp_data.length)
info_buff = resp_data[didx, 70]
break if info_buff.length != 70
info = info_buff.unpack(
'V'+ # Next Entry Offset
'V'+ # File Index
'VV'+ # Time Create
'VV'+ # Time Last Access
'VV'+ # Time Last Write
'VV'+ # Time Change
'VV'+ # End of File
'VV'+ # Allocation Size
'V'+ # File Attributes
'V'+ # File Name Length
'V'+ # Extended Attr List Length
'C'+ # Short File Name Length
'C' # Reserved
)
name = resp_data[didx + 70 + 24, info[15]].sub!(/\x00+$/, '')
files[name] =
{
'type' => ((info[14] & 0x10)==0x10) ? 'D' : 'F',
'attr' => info[14],
'info' => info
}
break if info[0] == 0
didx += info[0]
end
last_search_id = sid
if search_next == 0
# search id, search count, end of search, error offset, last name offset
sid, scnt, eos, eoff, loff = resp_parm.unpack('v5')
else
# FINX_NEXT doesn't return a SID
scnt, eos, eoff, loff = resp_parm.unpack('v4')
end
didx = 0
while (didx < resp_data.length)
info_buff = resp_data[didx, 70]
break if info_buff.length != 70
info = info_buff.unpack(
'V'+ # Next Entry Offset
'V'+ # File Index
'VV'+ # Time Create
'VV'+ # Time Last Access
'VV'+ # Time Last Write
'VV'+ # Time Change
'VV'+ # End of File
'VV'+ # Allocation Size
'V'+ # File Attributes
'V'+ # File Name Length
'V'+ # Extended Attr List Length
'C'+ # Short File Name Length
'C' # Reserved
)
name = resp_data[didx + 70 + 24, info[15]].sub!(/\x00+$/, '')
files[name] =
{
'type' => (info[14] & 0x10) ? 'D' : 'F',
'attr' => info[14],
'info' => info
}
break if info[0] == 0
didx += info[0]
end
last_search_id = sid
last_offset = loff
last_filename = name
if eos != 1 #If we aren't at the end of the search, run find_next
resp = find_next(last_search_id, last_offset, last_filename)
search_next = 1 # Flip bit so response params will parse correctly
end
end until eos == 1
rescue ::Exception
raise $!
end
@ -1896,21 +1906,19 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
return files
end
# TODO: Finish this method... requires search_id, resume_key, and filename from first
=begin
def find_next(path, sid = last_search_id)
# Supplements find_first if file/dir count exceeds max search count
def find_next(sid, resume_key, last_filename)
parm = [
sid, # Search ID
512, # Maximum search count
20, # Maximum search count (Size of 20 keeps response to 1 packet)
260, # Level of interest
0, # Resume key from previous
1, # Close search if end of search
].pack('vvvVv') + path + "\x00"
return files
resume_key, # Resume key from previous (Last name offset)
6, # Close search if end of search
].pack('vvvVv') + last_filename + "\x00" # Last filename returned from find_first or find_next
resp = trans2(CONST::TRANS2_FIND_NEXT2, parm, '')
return resp # Returns the FIND_NEXT2 response packet for parsing by the find_first function
end
=end
# Creates a new directory on the mounted tree
def create_directory(name)