Path: blob/master/lib/metasploit/framework/tcp/client.rb
19847 views
module Metasploit1module Framework2module Tcp34module EvasiveTCP5attr_accessor :_send_size, :_send_delay, :evasive67def denagle8begin9setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)10rescue ::Exception11end12end1314def write(buf, opts={})1516return super(buf, opts) if not @evasive1718ret = 019idx = 020len = @_send_size || buf.length2122while(idx < buf.length)2324if(@_send_delay and idx > 0)25::IO.select(nil, nil, nil, @_send_delay)26end2728pkt = buf[idx, len]2930res = super(pkt, opts)31flush()3233idx += len34ret += res if res35end36ret37end38end3940module Client4142extend ActiveSupport::Concern4344# @!attribute max_send_size45# @return [Integer] The max size of the data to encapsulate in a single packet46attr_accessor :max_send_size47# @!attribute send_delay48# @return [Integer] The delay between sending packets49attr_accessor :send_delay5051included do52include ActiveModel::Validations53validates :max_send_size,54presence: true,55numericality: {56only_integer: true,57greater_than_or_equal_to: 058}5960validates :send_delay,61presence: true,62numericality: {63only_integer: true,64greater_than_or_equal_to: 065}6667end6869#70# Establishes a TCP connection to the specified RHOST/RPORT71#72# @see Rex::Socket::Tcp73# @see Rex::Socket::Tcp.create74def connect(global = true, opts={})75dossl = false76if(opts.has_key?('SSL'))77dossl = opts['SSL']78else79dossl = ssl80end8182nsock = Rex::Socket::Tcp.create(83'PeerHost' => opts['RHOST'] || rhost,84'PeerHostname' => opts['SSLServerNameIndication'] || opts['RHOSTNAME'],85'PeerPort' => (opts['RPORT'] || rport).to_i,86'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",87'LocalPort' => (opts['CPORT'] || cport || 0).to_i,88'SSL' => dossl,89'SSLVersion' => opts['SSLVersion'] || ssl_version,90'SSLVerifyMode' => opts['SSLVerifyMode'] || ssl_verify_mode,91'SSLKeyLogFile' => opts['SSLKeyLogFile'] || sslkeylogfile,92'SSLCipher' => opts['SSLCipher'] || ssl_cipher,93'Proxies' => proxies,94'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i,95'Context' => { 'Msf' => framework, 'MsfExploit' => framework_module }96)97# enable evasions on this socket98set_tcp_evasions(nsock)99100# Set this socket to the global socket as necessary101self.sock = nsock if (global)102103return nsock104end105106# Enable evasions on a given client107def set_tcp_evasions(socket)108109if( max_send_size.to_i == 0 and send_delay.to_i == 0)110return111end112113return if socket.respond_to?('evasive')114115socket.extend(EvasiveTCP)116117if ( max_send_size.to_i > 0)118socket._send_size = max_send_size119socket.denagle120socket.evasive = true121end122123if ( send_delay.to_i > 0)124socket._send_delay = send_delay125socket.evasive = true126end127end128129#130# Closes the TCP connection131#132def disconnect(nsock = self.sock)133begin134if (nsock)135nsock.shutdown136nsock.close137end138rescue IOError139end140141if (nsock == sock)142self.sock = nil143end144145end146147##148#149# Wrappers for getters150#151##152153#154# Returns the target host155#156def rhost157raise NotImplementedError158end159160#161# Returns the remote port162#163def rport164raise NotImplementedError165end166167#168# Returns the local host for outgoing connections169#170def chost171raise NotImplementedError172end173174#175# Returns the local port for outgoing connections176#177def cport178raise NotImplementedError179end180181#182# Returns the boolean indicating SSL183#184def ssl185raise NotImplementedError186end187188#189# Returns the string indicating SSLVersion190#191def ssl_version192raise NotImplementedError193end194195#196# Returns the proxy configuration197#198def proxies199raise NotImplementedError200end201202attr_accessor :sock203204end205end206end207end208209210