Do first commands refactoring

bug/bundler_fix
jvazquez-r7 2015-02-21 01:48:47 -06:00
parent 52b41ab4f8
commit 80aef690a0
8 changed files with 361 additions and 277 deletions

View File

@ -12,11 +12,24 @@ module Msf
module Exploit::Remote::SMB::Server module Exploit::Remote::SMB::Server
# This mixin provides a minimal SMB server # This mixin provides a minimal SMB server
module Share module Share
require 'msf/core/exploit/smb/server/share/command'
require 'msf/core/exploit/smb/server/share/information_level' require 'msf/core/exploit/smb/server/share/information_level'
require 'msf/core/exploit/smb/server/share/sub_command' require 'msf/core/exploit/smb/server/share/sub_command'
include Msf::Exploit::Remote::SMB::Server::Share::Command::Close
include Msf::Exploit::Remote::SMB::Server::Share::Command::Negotiate
include Msf::Exploit::Remote::SMB::Server::Share::Command::NtCreateAndx
include Msf::Exploit::Remote::SMB::Server::Share::Command::ReadAndx
include Msf::Exploit::Remote::SMB::Server::Share::Command::SessionSetupAndx
include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Find include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Find
include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Query include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Query
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::FindFirst2
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryFileInformation
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryPathInformation
include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Find
include Msf::Exploit::Remote::SMB::Server::Share::InformationLevel::Query
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::FindFirst2 include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::FindFirst2
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryFileInformation include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryFileInformation
include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryPathInformation include Msf::Exploit::Remote::SMB::Server::Share::SubCommand::Trans2::QueryPathInformation
@ -133,283 +146,6 @@ module Msf
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS) smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
end end
end end
#
# Responds to a client CLOSE request
#
def smb_cmd_close(c, buff)
dprint("[SMB_CMD_CLOSE]")
pkt = CONST::SMB_CLOSE_PKT.make_struct
pkt.from_s(buff)
pkt = CONST::SMB_CLOSE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 0
c.put(pkt.to_s)
end
#
# Negotiates a SHARE session with the client
#
def smb_cmd_negotiate(c, buff)
dprint("[SMB_CMD_NEGOTIATE]")
pkt = CONST::SMB_NEG_PKT.make_struct
pkt.from_s(buff)
dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/)
dialect = dialects.index("NT LM 0.12") || dialects.length-1
pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 17
pkt['Payload'].v['Dialect'] = dialect
pkt['Payload'].v['SecurityMode'] = 2 # SHARE Security Mode
pkt['Payload'].v['MaxMPX'] = 50
pkt['Payload'].v['MaxVCS'] = 1
pkt['Payload'].v['MaxBuff'] = 4356
pkt['Payload'].v['MaxRaw'] = 65536
pkt['Payload'].v['SystemTimeLow'] = lo
pkt['Payload'].v['SystemTimeHigh'] = hi
pkt['Payload'].v['ServerTimeZone'] = 0x0
pkt['Payload'].v['SessionKey'] = 0
pkt['Payload'].v['Capabilities'] = 0x0080f3fd
pkt['Payload'].v['KeyLength'] = 8
pkt['Payload'].v['Payload'] = Rex::Text.rand_text_hex(8)
c.put(pkt.to_s)
end
#
# Sets up an SMB session in response to a SESSION_SETUP_ANDX request
#
def smb_cmd_session_setup(c, buff)
dprint("[SMB_CMD_SESSION_SETUP]")
pkt = CONST::SMB_SETUP_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 3
pkt['Payload'].v['AndX'] = 0x75
pkt['Payload'].v['Reserved1'] = 00
pkt['Payload'].v['AndXOffset'] = 96
pkt['Payload'].v['Action'] = 0x1 # Logged in as Guest
pkt['Payload'].v['Payload'] =
Rex::Text.to_unicode("Unix", 'utf-16be') + "\x00\x00" + # Native OS # Samba signature
Rex::Text.to_unicode("Samba 3.4.7", 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature
Rex::Text.to_unicode("WORKGROUP", 'utf-16be') + "\x00\x00\x00" + # Primary DOMAIN # Samba signature
tree_connect_response = ""
tree_connect_response << [7].pack("C") # Tree Connect Response : WordCount
tree_connect_response << [0xff].pack("C") # Tree Connect Response : AndXCommand
tree_connect_response << [0].pack("C") # Tree Connect Response : Reserved
tree_connect_response << [0].pack("v") # Tree Connect Response : AndXOffset
tree_connect_response << [0x1].pack("v") # Tree Connect Response : Optional Support
tree_connect_response << [0xa9].pack("C") # Access Mask for just Read and Exec
tree_connect_response << [0x00].pack("C")
tree_connect_response << [0x12].pack("C")
tree_connect_response << [0x00].pack("C")
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
tree_connect_response << [13].pack("v") # Tree Connect Response : ByteCount
tree_connect_response << "A:\x00" # Service
tree_connect_response << "#{Rex::Text.to_unicode("NTFS")}\x00\x00" # Extra byte parameters
# Fix the Netbios Session Service Message Length
# to have into account the tree_connect_response,
# need to do this because there isn't support for
# AndX still
my_pkt = pkt.to_s + tree_connect_response
original_length = my_pkt[2, 2].unpack("n").first
original_length = original_length + tree_connect_response.length
my_pkt[2, 2] = [original_length].pack("n")
c.put(my_pkt)
end
#
# Responds to a client NT_CREATE_ANDX request
#
def smb_cmd_create(c, buff)
dprint("[SMB_CMD_CREATE]")
smb = @state[c]
pkt = CONST::SMB_CREATE_PKT.make_struct
pkt.from_s(buff)
# Tries to do CREATE and X
payload = pkt['Payload'].v['Payload'].gsub(/\x00/, '').gsub(/.*\\/, '\\').chomp.strip.split('\\').last
file = file_name
path = path_name
if payload.nil?
payload = file
end
if payload.length.to_s.eql?('1') or payload.eql?(path)
fid = smb[:dir_id].to_i
attribs = 0x10 # Ordinary Dir
eof = 0
isdir = 1
else
fid = smb[:file_id].to_i
attribs = 0x80 # File Attributes
eof = exe_contents.length
isdir = 0
end
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
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['FileID'] = fid
pkt['Payload'].v['Action'] = 0x1 # The file existed and was opened
pkt['Payload'].v['CreateTimeLow'] = lo
pkt['Payload'].v['CreateTimeHigh'] = hi
pkt['Payload'].v['AccessTimeLow'] = lo
pkt['Payload'].v['AccessTimeHigh'] = hi
pkt['Payload'].v['WriteTimeLow'] = lo
pkt['Payload'].v['WriteTimeHigh'] = hi
pkt['Payload'].v['ChangeTimeLow'] = lo
pkt['Payload'].v['ChangeTimeHigh'] = hi
pkt['Payload'].v['Attributes'] = attribs
pkt['Payload'].v['AllocLow'] = 0x100000
pkt['Payload'].v['AllocHigh'] = 0
pkt['Payload'].v['EOFLow'] = eof
pkt['Payload'].v['EOFHigh'] = 0
pkt['Payload'].v['FileType'] = 0
pkt['Payload'].v['IPCState'] = 0x7
pkt['Payload'].v['IsDirectory'] = isdir
# As above, if payload is a file or "\" send found response
if (payload.downcase.eql?(file.downcase)) or payload.length.to_s.eql?('1') or payload.eql?(path)
connect_response = ""
# GUID
connect_response << ([0].pack("C") * 16)
# File ID
connect_response << ([0].pack("C") * 6)
# Access Rights
connect_response << [0xff].pack("C")
connect_response << [0x01].pack("C")
connect_response << [0x1f].pack("C")
connect_response << [0].pack("C")
connect_response << ([0].pack("C") * 4) # Guest access
connect_response << ([0].pack("C") * 2) # Byte Count
my_pkt = pkt.to_s + connect_response
original_length = my_pkt[2, 2].unpack("n").first
original_length = original_length + connect_response.length
my_pkt[2, 2] = [original_length].pack("n")
c.put(my_pkt)
else
# Otherwise send not found
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
c.put(pkt.to_s)
end
end
#
# Responds to a client READ_ANDX request
# This function sends chunks of the payload to the client
# by reading the offset and length requested by the client
# and sending the appropriate chunk of the payload
#
def smb_cmd_read(c, buff)
dprint("[SMB_CMD_READ]")
pkt = CONST::SMB_READ_PKT.make_struct
pkt.from_s(buff)
offset = pkt['Payload'].v['Offset']
length = pkt['Payload'].v['MaxCountLow']
pkt = CONST::SMB_READ_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 12
pkt['Payload'].v['AndX'] = 0xff # no more commands
pkt['Payload'].v['Remaining'] = 0xffff
pkt['Payload'].v['DataLenLow'] = length
pkt['Payload'].v['DataOffset'] = 59
pkt['Payload'].v['DataLenHigh'] = 0
pkt['Payload'].v['Reserved3'] = 0
pkt['Payload'].v['Reserved4'] = 0x0a
pkt['Payload'].v['ByteCount'] = length
pkt['Payload'].v['Payload'] = exe_contents[offset, length]
c.put(pkt.to_s)
end
#
# Responds to client TRANSACTION2 requests and dispatches the request off to
# other functions dependent on what the sub_command is. Commands supported
# include:
# QUERY_FILE_INFO (Basic, Standard and Internal)
# QUERY_PATH_INFO (Basic and Standard)
#
def smb_cmd_trans(c, buff)
dprint("[SMB_CMD_TRANS]")
# Client socket is c
pkt = CONST::SMB_TRANS2_PKT.make_struct
pkt.from_s(buff)
sub_command = pkt['Payload'].v['SetupData'].unpack("v").first
ar = Rex::Text.to_hex(buff, '').to_s
mdc = ar[86..89].unpack('n*').reverse.pack('n*').to_i(16)
case sub_command
when CONST::TRANS2_QUERY_FILE_INFO_BASIC
dprint("\t[query_file_info_basic]")
smb_cmd_trans_query_path_info_standard(c, buff)
when CONST::TRANS2_QUERY_FILE_INFO_STANDARD
dprint("\t[query_file_info_standard]")
loi = ar[148..151].unpack('n*').reverse.pack('n*').to_i(16)
case loi
when CONST::SMB_QUERY_PATH_STANDARD_INFO
dprint("\t\t[smb_cmd_trans_query_path_info_standard]")
smb_cmd_trans_query_path_info_standard(c, buff)
when CONST::SMB_QUERY_FILE_STANDARD_INFO_BASIC
dprint("\t\t[smb_cmd_trans_query_file_info_basic]")
smb_cmd_trans_query_file_info_basic(c, buff)
when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
dprint("\t\t[smb_cmd_trans_query_file_info_network]")
smb_cmd_trans_query_file_info_network(c, buff)
else
dprint("\t\tUnknown LOI [smb_cmd_trans_query_path_info_standard] - #{loi.to_s}")
smb_cmd_trans_query_file_info_standard(c, buff)
end
when CONST::TRANS2_QUERY_PATH_INFO
smb_cmd_trans2_query_path_information(c, buff)
when CONST::TRANS2_FIND_FIRST2
smb_cmd_trans2_find_first2(c, buff)
else
dprint("\t[UNKNOWN SUBCOMMAND]")
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['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['ErrorClass'] = 0xc0000225 # NT_STATUS_NOT_FOUND
c.put(pkt.to_s)
end
end
end end
end end
end end

View File

@ -0,0 +1,15 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
require 'msf/core/exploit/smb/server/share/command/close'
require 'msf/core/exploit/smb/server/share/command/negotiate'
require 'msf/core/exploit/smb/server/share/command/nt_create_andx'
require 'msf/core/exploit/smb/server/share/command/read_andx'
require 'msf/core/exploit/smb/server/share/command/session_setup_andx'
end
end
end
end

View File

@ -0,0 +1,30 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Close
#
# Responds to a client CLOSE request
#
def smb_cmd_close(c, buff)
dprint("[SMB_CMD_CLOSE]")
pkt = CONST::SMB_CLOSE_PKT.make_struct
pkt.from_s(buff)
pkt = CONST::SMB_CLOSE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 0
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,47 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Negotiate
#
# Negotiates a SHARE session with the client
#
def smb_cmd_negotiate(c, buff)
dprint("[SMB_CMD_NEGOTIATE]")
pkt = CONST::SMB_NEG_PKT.make_struct
pkt.from_s(buff)
dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/)
dialect = dialects.index("NT LM 0.12") || dialects.length-1
pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 17
pkt['Payload'].v['Dialect'] = dialect
pkt['Payload'].v['SecurityMode'] = 2 # SHARE Security Mode
pkt['Payload'].v['MaxMPX'] = 50
pkt['Payload'].v['MaxVCS'] = 1
pkt['Payload'].v['MaxBuff'] = 4356
pkt['Payload'].v['MaxRaw'] = 65536
pkt['Payload'].v['SystemTimeLow'] = lo
pkt['Payload'].v['SystemTimeHigh'] = hi
pkt['Payload'].v['ServerTimeZone'] = 0x0
pkt['Payload'].v['SessionKey'] = 0
pkt['Payload'].v['Capabilities'] = 0x0080f3fd
pkt['Payload'].v['KeyLength'] = 8
pkt['Payload'].v['Payload'] = Rex::Text.rand_text_hex(8)
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,100 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module NtCreateAndx
#
# Responds to a client NT_CREATE_ANDX request
#
def smb_cmd_create(c, buff)
dprint("[SMB_CMD_CREATE]")
smb = @state[c]
pkt = CONST::SMB_CREATE_PKT.make_struct
pkt.from_s(buff)
# Tries to do CREATE and X
payload = pkt['Payload'].v['Payload'].gsub(/\x00/, '').gsub(/.*\\/, '\\').chomp.strip.split('\\').last
file = file_name
path = path_name
if payload.nil?
payload = file
end
if payload.length.to_s.eql?('1') or payload.eql?(path)
fid = smb[:dir_id].to_i
attribs = 0x10 # Ordinary Dir
eof = 0
isdir = 1
else
fid = smb[:file_id].to_i
attribs = 0x80 # File Attributes
eof = exe_contents.length
isdir = 0
end
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
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['FileID'] = fid
pkt['Payload'].v['Action'] = 0x1 # The file existed and was opened
pkt['Payload'].v['CreateTimeLow'] = lo
pkt['Payload'].v['CreateTimeHigh'] = hi
pkt['Payload'].v['AccessTimeLow'] = lo
pkt['Payload'].v['AccessTimeHigh'] = hi
pkt['Payload'].v['WriteTimeLow'] = lo
pkt['Payload'].v['WriteTimeHigh'] = hi
pkt['Payload'].v['ChangeTimeLow'] = lo
pkt['Payload'].v['ChangeTimeHigh'] = hi
pkt['Payload'].v['Attributes'] = attribs
pkt['Payload'].v['AllocLow'] = 0x100000
pkt['Payload'].v['AllocHigh'] = 0
pkt['Payload'].v['EOFLow'] = eof
pkt['Payload'].v['EOFHigh'] = 0
pkt['Payload'].v['FileType'] = 0
pkt['Payload'].v['IPCState'] = 0x7
pkt['Payload'].v['IsDirectory'] = isdir
# As above, if payload is a file or "\" send found response
if (payload.downcase.eql?(file.downcase)) or payload.length.to_s.eql?('1') or payload.eql?(path)
connect_response = ""
# GUID
connect_response << ([0].pack("C") * 16)
# File ID
connect_response << ([0].pack("C") * 6)
# Access Rights
connect_response << [0xff].pack("C")
connect_response << [0x01].pack("C")
connect_response << [0x1f].pack("C")
connect_response << [0].pack("C")
connect_response << ([0].pack("C") * 4) # Guest access
connect_response << ([0].pack("C") * 2) # Byte Count
my_pkt = pkt.to_s + connect_response
original_length = my_pkt[2, 2].unpack("n").first
original_length = original_length + connect_response.length
my_pkt[2, 2] = [original_length].pack("n")
c.put(my_pkt)
else
# Otherwise send not found
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
c.put(pkt.to_s)
end
end
end
end
end
end
end

View File

@ -0,0 +1,44 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module ReadAndx
#
# Responds to a client READ_ANDX request
# This function sends chunks of the payload to the client
# by reading the offset and length requested by the client
# and sending the appropriate chunk of the payload
#
def smb_cmd_read(c, buff)
dprint("[SMB_CMD_READ]")
pkt = CONST::SMB_READ_PKT.make_struct
pkt.from_s(buff)
offset = pkt['Payload'].v['Offset']
length = pkt['Payload'].v['MaxCountLow']
pkt = CONST::SMB_READ_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 12
pkt['Payload'].v['AndX'] = 0xff # no more commands
pkt['Payload'].v['Remaining'] = 0xffff
pkt['Payload'].v['DataLenLow'] = length
pkt['Payload'].v['DataOffset'] = 59
pkt['Payload'].v['DataLenHigh'] = 0
pkt['Payload'].v['Reserved3'] = 0
pkt['Payload'].v['Reserved4'] = 0x0a
pkt['Payload'].v['ByteCount'] = length
pkt['Payload'].v['Payload'] = exe_contents[offset, length]
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,57 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module SessionSetupAndx
#
# Sets up an SMB session in response to a SESSION_SETUP_ANDX request
#
def smb_cmd_session_setup(c, buff)
dprint("[SMB_CMD_SESSION_SETUP]")
pkt = CONST::SMB_SETUP_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 3
pkt['Payload'].v['AndX'] = 0x75
pkt['Payload'].v['Reserved1'] = 00
pkt['Payload'].v['AndXOffset'] = 96
pkt['Payload'].v['Action'] = 0x1 # Logged in as Guest
pkt['Payload'].v['Payload'] =
Rex::Text.to_unicode("Unix", 'utf-16be') + "\x00\x00" + # Native OS # Samba signature
Rex::Text.to_unicode("Samba 3.4.7", 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature
Rex::Text.to_unicode("WORKGROUP", 'utf-16be') + "\x00\x00\x00" + # Primary DOMAIN # Samba signature
tree_connect_response = ""
tree_connect_response << [7].pack("C") # Tree Connect Response : WordCount
tree_connect_response << [0xff].pack("C") # Tree Connect Response : AndXCommand
tree_connect_response << [0].pack("C") # Tree Connect Response : Reserved
tree_connect_response << [0].pack("v") # Tree Connect Response : AndXOffset
tree_connect_response << [0x1].pack("v") # Tree Connect Response : Optional Support
tree_connect_response << [0xa9].pack("C") # Access Mask for just Read and Exec
tree_connect_response << [0x00].pack("C")
tree_connect_response << [0x12].pack("C")
tree_connect_response << [0x00].pack("C")
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
tree_connect_response << [13].pack("v") # Tree Connect Response : ByteCount
tree_connect_response << "A:\x00" # Service
tree_connect_response << "#{Rex::Text.to_unicode("NTFS")}\x00\x00" # Extra byte parameters
# Fix the Netbios Session Service Message Length
# to have into account the tree_connect_response,
# need to do this because there isn't support for
# AndX still
my_pkt = pkt.to_s + tree_connect_response
original_length = my_pkt[2, 2].unpack("n").first
original_length = original_length + tree_connect_response.length
my_pkt[2, 2] = [original_length].pack("n")
c.put(my_pkt)
end
end
end
end
end
end

View File

@ -8,6 +8,61 @@ module Msf
require 'msf/core/exploit/smb/server/share/sub_command/trans2/find_first2' require 'msf/core/exploit/smb/server/share/sub_command/trans2/find_first2'
require 'msf/core/exploit/smb/server/share/sub_command/trans2/query_file_information' require 'msf/core/exploit/smb/server/share/sub_command/trans2/query_file_information'
require 'msf/core/exploit/smb/server/share/sub_command/trans2/query_path_information' require 'msf/core/exploit/smb/server/share/sub_command/trans2/query_path_information'
#
# Responds to client TRANSACTION2 requests and dispatches the request off to
# other functions dependent on what the sub_command is. Commands supported
# include:
# QUERY_FILE_INFO (Basic, Standard and Internal)
# QUERY_PATH_INFO (Basic and Standard)
#
def smb_cmd_trans(c, buff)
dprint("[SMB_CMD_TRANS]")
# Client socket is c
pkt = CONST::SMB_TRANS2_PKT.make_struct
pkt.from_s(buff)
sub_command = pkt['Payload'].v['SetupData'].unpack("v").first
ar = Rex::Text.to_hex(buff, '').to_s
mdc = ar[86..89].unpack('n*').reverse.pack('n*').to_i(16)
case sub_command
when CONST::TRANS2_QUERY_FILE_INFO_BASIC
dprint("\t[query_file_info_basic]")
smb_cmd_trans_query_path_info_standard(c, buff)
when CONST::TRANS2_QUERY_FILE_INFO_STANDARD
dprint("\t[query_file_info_standard]")
loi = ar[148..151].unpack('n*').reverse.pack('n*').to_i(16)
case loi
when CONST::SMB_QUERY_PATH_STANDARD_INFO
dprint("\t\t[smb_cmd_trans_query_path_info_standard]")
smb_cmd_trans_query_path_info_standard(c, buff)
when CONST::SMB_QUERY_FILE_STANDARD_INFO_BASIC
dprint("\t\t[smb_cmd_trans_query_file_info_basic]")
smb_cmd_trans_query_file_info_basic(c, buff)
when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
dprint("\t\t[smb_cmd_trans_query_file_info_network]")
smb_cmd_trans_query_file_info_network(c, buff)
else
dprint("\t\tUnknown LOI [smb_cmd_trans_query_path_info_standard] - #{loi.to_s}")
smb_cmd_trans_query_file_info_standard(c, buff)
end
when CONST::TRANS2_QUERY_PATH_INFO
smb_cmd_trans2_query_path_information(c, buff)
when CONST::TRANS2_FIND_FIRST2
smb_cmd_trans2_find_first2(c, buff)
else
dprint("\t[UNKNOWN SUBCOMMAND]")
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['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['ErrorClass'] = 0xc0000225 # NT_STATUS_NOT_FOUND
c.put(pkt.to_s)
end
end
end end
end end
end end