Land @0x41414141's bugfixing

bug/bundler_fix
jvazquez-r7 2015-02-26 11:40:08 -06:00
commit 6d6d5a7dca
No known key found for this signature in database
GPG Key ID: 38D99152B9352D83
6 changed files with 157 additions and 67 deletions

View File

@ -14,10 +14,10 @@ module Msf
pkt = CONST::SMB_CREATE_PKT.make_struct
pkt.from_s(buff)
payload = (pkt['Payload'].v['Payload'])
payload = (pkt['Payload'].v['Payload']).downcase
payload.gsub!(/^[\x00]*/, '') # delete padding
payload = Rex::Text.to_ascii(payload)
payload.gsub!(/[\x00]*$/, '') # delete padding
payload = Rex::Text.ascii_safe_hex(payload)
payload.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
if payload.nil? || payload.empty?
payload = file_name
@ -28,7 +28,7 @@ module Msf
attribs = 0x80 # File Attributes
eof = exe_contents.length
is_dir = 0
elsif payload == path_name
elsif payload.eql?(path_name)
fid = smb[:dir_id].to_i
attribs = 0x10 # Ordinary Dir
eof = 0
@ -52,9 +52,9 @@ module Msf
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 42
pkt['Payload'].v['AndX'] = 0xff # no further commands
pkt['Payload'].v['OpLock'] = 0x3 # Grant Oplock on File
pkt['Payload'].v['OpLock'] = CONST::LEVEL_II_OPLOCK # Grant Oplock on File
pkt['Payload'].v['FileID'] = fid
pkt['Payload'].v['Action'] = 0x1 # The file existed and was opened
pkt['Payload'].v['Action'] = CONST::FILE_OPEN # The file existed and was opened
pkt['Payload'].v['CreateTimeLow'] = lo
pkt['Payload'].v['CreateTimeHigh'] = hi
pkt['Payload'].v['AccessTimeLow'] = lo

View File

@ -7,21 +7,32 @@ module Msf
module Trans2
# This mixin provides methods to handle TRAN2_FIND_FIRST2 subcommands
module FindFirst2
def smb_cmd_trans2_find_first2(c, buff)
params = CONST::SMB_TRANS2_FIND_FIRST2_PARAMETERS.make_struct
params.from_s(buff)
loi = params.v['InformationLevel']
file_name = Rex::Text.to_ascii(params.v['FileName'])
file_name.gsub!(/[\x00]*$/, '') #delete padding
search_path = Rex::Text.to_ascii(params.v['FileName']).downcase
search_path.gsub!(/[\x00]*/, '') #delete padding
search_path.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
# Do some dummy managing for wildcards
# TODO: improve
search_path.gsub!(/<\./, '*.') # manage wildcards
extension = File.extname(file_name)
if search_path == "#{path_name}*#{extension}"
search_path = "#{path_name}#{file_name}"
end
case loi
when CONST::SMB_FIND_FILE_NAMES_INFO
smb_cmd_find_file_names_info(c, file_name)
smb_cmd_find_file_names_info(c, search_path)
when CONST::SMB_FIND_FILE_BOTH_DIRECTORY_INFO
smb_cmd_find_file_both_directory_info(c, file_name)
smb_cmd_find_file_both_directory_info(c, search_path)
when CONST::SMB_FIND_FILE_FULL_DIRECTORY_INFO
smb_cmd_find_file_full_directory_info(c, file_name)
smb_cmd_find_file_full_directory_info(c, search_path)
else
dprint("\t\tUnknown LOI [smb_cmd_trans2_find_first2] - #{loi}")
# SEND success with the hope of going ahead...

View File

@ -17,12 +17,10 @@ module Msf
fid = params.v['FID']
case loi
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS, CONST::SMB_QUERY_FILE_INTERNAL_INFO_ALIAS
smb_cmd_trans_query_file_info_standard(c, fid)
when CONST::SMB_QUERY_FILE_BASIC_INFO, CONST::SMB_QUERY_FILE_BASIC_INFO_ALIAS, CONST::SMB_SET_FILE_BASIC_INFO_ALIAS
smb_cmd_trans_query_file_info_basic(c, fid)
#when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
#smb_cmd_trans_query_file_info_network(c, fid)
else
dprint("\t\tUnknown LOI [smb_cmd_trans2_query_file_information] - #{loi.to_s}")
# SEND success with the hope of going ahead...

View File

@ -9,20 +9,22 @@ module Msf
module QueryPathInformation
def smb_cmd_trans2_query_path_information(c, buff)
params = CONST::SMB_TRANS2_QUERY_PATH_PARAMETERS.make_struct
params.from_s(buff)
loi = params.v['InformationLevel']
file_name = params.v['FileName']
file_name.gsub!(/[\x00]*$/, '') #delete padding
file_name = Rex::Text.to_ascii(params.v['FileName']).downcase
file_name.gsub!(/[\x00]*/, '') #delete padding
file_name.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
case loi
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS, CONST::SMB_QUERY_FILE_INTERNAL_INFO_ALIAS
smb_cmd_trans_query_path_info_standard(c, file_name)
when CONST::SMB_QUERY_FILE_BASIC_INFO, CONST::SMB_QUERY_FILE_BASIC_INFO_ALIAS, CONST::SMB_SET_FILE_BASIC_INFO_ALIAS
smb_cmd_trans_query_path_info_basic(c, file_name)
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS
smb_cmd_trans_query_path_info_standard(c, file_name)
#when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
#smb_cmd_trans_query_file_info_network(c, buff)
when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
smb_cmd_trans_query_path_info_network(c, file_name)
else
dprint("\t\tUnknown LOI [smb_cmd_trans2_query_path_information] - #{loi.to_s}")
# SEND success with the hope of going ahead...

View File

@ -7,18 +7,61 @@ module Msf
# This mixin provides methods to handle TRAN2_QUERY_PATH_INFORMATION subcommands
module Query
# shortcut.. always send OBJECT_NAME_NOT_FOUND
def smb_cmd_trans_query_file_info_basic(c, buff)
#
# Responds to QUERY_PATH_INFO (Basic) requests
#
def smb_cmd_trans_query_file_info_basic(c, fid)
smb = @state[c]
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
if fid.eql?smb[:file_id].to_i
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL # File attributes => file
elsif fid.nil? || fid.empty? || fid == "\x00" # empty path
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
else
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND
pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND # OBJECT_NAME_NOT_FOUND
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
c.put(pkt.to_s)
return
end
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
trans2_params.v['EaErrorOffset'] = 0
query_path_info = CONST::SMB_QUERY_FILE_BASIC_INFO_HDR.make_struct
query_path_info.v['loCreationTime'] = lo
query_path_info.v['hiCreationTime'] = hi
query_path_info.v['loLastAccessTime'] = lo
query_path_info.v['hiLastAccessTime'] = hi
query_path_info.v['loLastWriteTime'] = lo
query_path_info.v['hiLastWriteTime'] = hi
query_path_info.v['loLastChangeTime'] = lo
query_path_info.v['hiLastChangeTime'] = hi
query_path_info.v['ExtFileAttributes'] = attrib
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 10
pkt['Payload'].v['ParamCountTotal'] = trans2_params.to_s.length
pkt['Payload'].v['DataCountTotal'] = query_path_info.to_s.length
pkt['Payload'].v['ParamCount'] = trans2_params.to_s.length
pkt['Payload'].v['ParamOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH
pkt['Payload'].v['DataCount'] = query_path_info.to_s.length
pkt['Payload'].v['DataOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH + trans2_params.to_s.length + UNICODE_NULL_LENGTH
pkt['Payload'].v['Payload'] =
"\x00" + # Padding
trans2_params.to_s +
"\x00\x00" + # Padding
query_path_info.to_s
c.put(pkt.to_s)
end
# shortcut, we only have one file....
def smb_cmd_trans_query_file_info_standard(c, buff)
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
@ -113,7 +156,6 @@ module Msf
c.put(pkt.to_s)
end
#
# Responds to QUERY_PATH_INFO (Standard) requests
#
@ -123,10 +165,8 @@ module Msf
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
if path && path.ends_with?(file_name) #TODO: do it better
if path && path.include?(file_name) #TODO: do it better
attrib = 0 # File attributes => file
elsif path && path.ends_with?(file_name + '.Local')
attrib = 1 # File attributes => file
elsif path && path == path_name
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = 1 # File attributes => directory
@ -174,61 +214,68 @@ module Msf
c.put(pkt.to_s)
end
=begin
#
# Responds to QUERY_FILE_INFO (Network) requests
# Is it needed?
def smb_cmd_trans_query_file_info_network(c, buff)
pkt = CONST::SMB_TRANS2_PKT.make_struct
pkt.from_s(buff)
# Responds to QUERY_PATH_INFO (Network Open) requests
#
# At the moment we just support '\\' path always send a SUCCESS...
def smb_cmd_trans_query_path_info_network(c, path)
payload = pkt['Payload'].v['SetupData'].gsub(/\x00/, '').gsub(/.*\\/, '').chomp.strip
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
dprint("[smb_cmd_trans_query_file_info_network] Payload length: #{payload.length.to_s}")
dprint("[smb_cmd_trans_query_file_info_network] Payload is : #{payload.to_s}")
if payload.length.to_s.eql?('4')
attrib = "\x10\x00\x00\x00" # File attributes => directory
if path && path.include?(file_name) #TODO: do it better
attrib = 0 # File attributes => file
elsif path && path == path_name
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
elsif path.nil? || path.empty? || path == "\x00" # empty path
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
else
attrib = "\x80\x00\x00\x00" # File attributes => normal file
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
pkt['Payload']['SMB'].v['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND # OBJECT_NAME_NOT_FOUND
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
c.put(pkt.to_s)
return
end
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
trans2_params.v['EaErrorOffset'] = 0
query_path_info = CONST::SMB_QUERY_FILE_NETWORK_INFO_HDR.make_struct
query_path_info.v['loCreationTime'] = lo
query_path_info.v['hiCreationTime'] = hi
query_path_info.v['loLastAccessTime'] = lo
query_path_info.v['hiLastAccessTime'] = hi
query_path_info.v['loLastWriteTime'] = lo
query_path_info.v['hiLastWriteTime'] = hi
query_path_info.v['loLastChangeTime'] = lo
query_path_info.v['hiLastChangeTime'] = hi
query_path_info.v['AllocationSize'] = 1048576
query_path_info.v['EndOfFile'] = exe_contents.length
query_path_info.v['ExtFileAttributes'] = attrib
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 10
pkt['Payload'].v['ParamCountTotal'] = 2
pkt['Payload'].v['DataCountTotal'] = 56
pkt['Payload'].v['ParamCount'] = 2
pkt['Payload'].v['ParamOffset'] = 56
pkt['Payload'].v['DataCount'] = 56
pkt['Payload'].v['DataOffset'] = 60
pkt['Payload'].v['ParamCountTotal'] = trans2_params.to_s.length
pkt['Payload'].v['DataCountTotal'] = query_path_info.to_s.length + UNICODE_NULL_LENGTH
pkt['Payload'].v['ParamCount'] = trans2_params.to_s.length
pkt['Payload'].v['ParamOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH
pkt['Payload'].v['DataCount'] = query_path_info.to_s.length + UNICODE_NULL_LENGTH
pkt['Payload'].v['DataOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH + trans2_params.to_s.length + UNICODE_NULL_LENGTH
pkt['Payload'].v['Payload'] =
"\x00" + # Padding
# QUERY_PATH_INFO Parameters
"\x00\x00" + # EA Error Offset
trans2_params.to_s +
"\x00\x00" + # Padding
# QUERY_PATH_INFO Data
[lo, hi].pack("VV") + # Created
[lo, hi].pack("VV") + # Last Access
[lo, hi].pack("VV") + # Last Write
[lo, hi].pack("VV") + # Change
"\x00\x00\x10\x00\x00\x00\x00\x00" + # Allocation Size = 1048576 || 1Mb
[exe_contents.length].pack("V") + "\x00\x00\x00\x00" + # End Of File
attrib +
"\x00\x00\x00\x00" # Unknown
my_pkt = pkt.to_s
original_length = my_pkt[2, 2].unpack("n").first
original_length = original_length + 24
my_pkt[2, 2] = [original_length].pack("n")
new_length = my_pkt[2, 2].unpack("n").first
query_path_info.to_s
c.put(pkt.to_s)
end
=end
end
end
end

View File

@ -184,6 +184,19 @@ class Constants
OPEN_SHARE_DENY_READEXEC = 0x30
OPEN_SHARE_DENY_NONE = 0x40
# OpLock Levels
NO_OPLOCK = 0x00
EXCLUSIVE_OPLOCK = 0x01
BATCH_OPLOCK = 0x02
LEVEL_II_OPLOCK = 0x03
# Dispositions, action to take if the file already exists or if the file is a new file and does not already exist
FILE_SUPERSEDE = 0x00000000
FILE_OPEN = 0x00000001
FILE_CREATE = 0x00000002
FILE_OPEN_IF = 0x00000003
FILE_OVERWRITE = 0x00000004
FILE_OVERWRITE_IF = 0x00000005
# File Access
OPEN_ACCESS_READ = 0x00
@ -282,9 +295,10 @@ class Constants
SMB_QUERY_FILE_BASIC_INFO_ALIAS = 0x3EC # alias for 0x101
SMB_SET_FILE_BASIC_INFO_ALIAS = 0x3EC # alias for 0x101
SMB_QUERY_FILE_STANDARD_INFO_ALIAS = 0x3ED # alias for 0x102
SMB_QUERY_FILE_INTERNAL_INFO_ALIAS = 0x3EE # alias for 0x103
SMB_QUERY_FILE_EA_INFO_ALIAS = 0x3EF # alias for 0x103
SMB_QUERY_FILE_NAME_INFO_ALIAS = 0x3F1 # alias for 0x104
SMB_QUERY_FILE_NETWORK_OPEN_INFO = 0x040a
SMB_QUERY_FILE_NETWORK_OPEN_INFO = 0x40A
SMB_INFO_PASSTHROUGH = 0x1000
# SMB_COM_TRANSACTION2 MAX DATA COUNT information levels
@ -1282,6 +1296,24 @@ class Constants
['uint16v', 'EaErrorOffset', 0]
)
# A template for SMB_QUERY_FILE_NETWORK_INFO query path information level
SMB_QUERY_FILE_NETWORK_INFO_HDR = Rex::Struct2::CStructTemplate.new(
['uint32v', 'loCreationTime', 0],
['uint32v', 'hiCreationTime', 0],
['uint32v', 'loLastAccessTime', 0],
['uint32v', 'hiLastAccessTime', 0],
['uint32v', 'loLastWriteTime', 0],
['uint32v', 'hiLastWriteTime', 0],
['uint32v', 'loLastChangeTime', 0],
['uint32v', 'hiLastChangeTime', 0],
['uint64v', 'AllocationSize', 0],
['uint64v', 'EndOfFile', 0],
['uint32v', 'ExtFileAttributes', 0],
['uint32v', 'Reserved', 0]
)
SMB_QUERY_FILE_NETWORK_INFO_HDR_LENGTH = 56
# A template for SMB_QUERY_FILE_BASIC_INFO query path information level
SMB_QUERY_FILE_BASIC_INFO_HDR = Rex::Struct2::CStructTemplate.new(
['uint32v', 'loCreationTime', 0],