require 'rex/proto/smb' require 'rex/proto/dcerpc' require 'rex/encoder/ndr' module Msf ### # # This mixin provides utility methods for interacting with a SMB/CIFS service on # a remote machine. These methods may generally be useful in the context of # exploitation. This mixin extends the Tcp exploit mixin. Only one SMB # service can be accessed at a time using this class. # ### module Exploit::Remote::SMB include Exploit::Remote::Tcp SIMPLE = Rex::Proto::SMB::SimpleClient XCEPT = Rex::Proto::SMB::Exceptions CONST = Rex::Proto::SMB::Constants # Alias over the Rex DCERPC protocol modules DCERPCPacket = Rex::Proto::DCERPC::Packet DCERPCClient = Rex::Proto::DCERPC::Client DCERPCResponse = Rex::Proto::DCERPC::Response DCERPCUUID = Rex::Proto::DCERPC::UUID NDR = Rex::Encoder::NDR def initialize(info = {}) super register_evasion_options( [ OptBool.new('SMB::pipe_evasion', [ true, 'Enable segmented read/writes for SMB Pipes', 'False']), OptInt.new('SMB::pipe_write_min_size', [ true, 'Minimum buffer size for pipe writes', 1]), OptInt.new('SMB::pipe_write_max_size', [ true, 'Maximum buffer size for pipe writes', 1024]), OptInt.new('SMB::pipe_read_min_size', [ true, 'Minimum buffer size for pipe reads', 1]), OptInt.new('SMB::pipe_read_max_size', [ true, 'Maximum buffer size for pipe reads', 1024]), OptInt.new('SMB::pad_data_level', [ true, 'Place extra padding between headers and data (level 0-3)', 0]), OptInt.new('SMB::pad_file_level', [ true, 'Obscure path names used in open/create (level 0-3)', 0]), OptInt.new('SMB::obscure_trans_pipe_level', [ true, 'Obscure PIPE string in TransNamedPipe (level 0-3)', 0]), ], Msf::Exploit::Remote::SMB) register_options( [ Opt::RHOST, OptInt.new('RPORT', [ true, 'Set the SMB service port', 445]), OptBool.new('SMBDirect', [ true, 'The target port is a raw SMB service (not NetBIOS)', 'True' ]), OptString.new('SMBUSER', [ false, 'The username to authenticate as', '']), OptString.new('SMBPASS', [ false, 'The password for the specified username', '']), OptString.new('SMBDOM', [ false, 'The Windows domain to use for authentication', 'WORKGROUP']), OptString.new('SMBNAME', [ true, 'The NetBIOS hostname (required for port 139 connections)', '*SMBSERVER']) ], Msf::Exploit::Remote::SMB) end def connect() disconnect() super self.simple = SIMPLE.new(self.sock, datastore['SMBDirect']) # setup pipe evasion foo if datastore['SMB::pipe_evasion'] # XXX - insert code to change the instance of the read/write functions to do segmentation end if (datastore['SMB::pad_data_level']) self.simple.client.evasion_opts['pad_data'] = datastore['SMB::pad_data_level'] end if (datastore['SMB::pad_file_level']) self.simple.client.evasion_opts['pad_file'] = datastore['SMB::pad_file_level'] end if (datastore['SMB::obscure_trans_pipe_level']) self.simple.client.evasion_opts['obscure_trans_pipe'] = datastore['SMB::obscure_trans_pipe_level'] end end # Convert a standard ASCII string to 16-bit Unicode def unicode(str) Rex::Text.to_unicode(str) end # This method establishes a SMB session over the default socket def smb_login simple.login( datastore['SMBNAME'], datastore['SMBUSER'], datastore['SMBPASS'], datastore['SMBDOM'] ) simple.connect('IPC$') end # This method returns the native operating system of the peer def smb_peer_os self.simple.client.peer_native_os end # This method returns the native lanman version of the peer def smb_peer_lm self.simple.client.peer_native_lm end # This method opens a handle to an IPC pipe def smb_create(pipe) self.simple.create_pipe(pipe) end def smb_hostname datastore['SMBNAME'] || '*SMBSERVER' end attr_accessor :simple end end