Land @0x41414141's bugfixing
commit
6d6d5a7dca
|
@ -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
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -7,16 +7,59 @@ 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 # 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['ErrorClass'] = CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND
|
||||
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)
|
||||
return
|
||||
end
|
||||
|
||||
# shortcut, we only have one file....
|
||||
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue