metasploit-framework/lib/msf/core/exploit/smb.rb

125 lines
3.8 KiB
Ruby

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