eea8fa86dc
Also actually handle the 'Auto' option that we had in the crawler and remove hardcoded defaults in modules that do not need them.
308 lines
6.0 KiB
Ruby
308 lines
6.0 KiB
Ruby
# -*- coding: binary -*-
|
|
require 'msf/core/exploit/tcp_server'
|
|
|
|
module Msf
|
|
|
|
module EvasiveTCP
|
|
attr_accessor :_send_size, :_send_delay, :evasive
|
|
|
|
def denagle
|
|
begin
|
|
setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
rescue ::Exception
|
|
end
|
|
end
|
|
|
|
def write(buf, opts={})
|
|
|
|
return super(buf, opts) if not @evasive
|
|
|
|
ret = 0
|
|
idx = 0
|
|
len = @_send_size || buf.length
|
|
|
|
while(idx < buf.length)
|
|
|
|
if(@_send_delay and idx > 0)
|
|
::IO.select(nil, nil, nil, @_send_delay)
|
|
end
|
|
|
|
pkt = buf[idx, len]
|
|
|
|
res = super(pkt, opts)
|
|
flush()
|
|
|
|
idx += len
|
|
ret += res if res
|
|
end
|
|
ret
|
|
end
|
|
end
|
|
|
|
###
|
|
#
|
|
# This module provides methods for establish a connection to a remote host and
|
|
# communicating with it.
|
|
#
|
|
###
|
|
module Exploit::Remote::Tcp
|
|
|
|
#
|
|
# Initializes an instance of an exploit module that exploits a
|
|
# vulnerability in a TCP server.
|
|
#
|
|
def initialize(info = {})
|
|
super
|
|
|
|
register_options(
|
|
[
|
|
Opt::RHOST,
|
|
Opt::RPORT
|
|
], Msf::Exploit::Remote::Tcp
|
|
)
|
|
|
|
register_advanced_options(
|
|
[
|
|
OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]),
|
|
Opt::SSLVersion,
|
|
OptEnum.new('SSLVerifyMode', [ false, 'SSL verification method', 'PEER', %W{CLIENT_ONCE FAIL_IF_NO_PEER_CERT NONE PEER}]),
|
|
OptString.new('SSLCipher', [ false, 'String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"']),
|
|
Opt::Proxies,
|
|
Opt::CPORT,
|
|
Opt::CHOST,
|
|
OptInt.new('ConnectTimeout', [ true, 'Maximum number of seconds to establish a TCP connection', 10])
|
|
], Msf::Exploit::Remote::Tcp
|
|
)
|
|
|
|
register_evasion_options(
|
|
[
|
|
OptInt.new('TCP::max_send_size', [false, 'Maxiumum tcp segment size. (0 = disable)', 0]),
|
|
OptInt.new('TCP::send_delay', [false, 'Delays inserted before every send. (0 = disable)', 0])
|
|
], Msf::Exploit::Remote::Tcp
|
|
)
|
|
end
|
|
|
|
#
|
|
# Establishes a TCP connection to the specified RHOST/RPORT
|
|
#
|
|
# @see Rex::Socket::Tcp
|
|
# @see Rex::Socket::Tcp.create
|
|
def connect(global = true, opts={})
|
|
|
|
dossl = false
|
|
if(opts.has_key?('SSL'))
|
|
dossl = opts['SSL']
|
|
else
|
|
dossl = ssl
|
|
if (datastore.default?('SSL') and rport.to_i == 443)
|
|
dossl = true
|
|
end
|
|
end
|
|
|
|
nsock = Rex::Socket::Tcp.create(
|
|
'PeerHost' => opts['RHOST'] || rhost,
|
|
'PeerPort' => (opts['RPORT'] || rport).to_i,
|
|
'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",
|
|
'LocalPort' => (opts['CPORT'] || cport || 0).to_i,
|
|
'SSL' => dossl,
|
|
'SSLVersion' => opts['SSLVersion'] || ssl_version,
|
|
'SSLVerifyMode' => opts['SSLVerifyMode'] || ssl_verify_mode,
|
|
'SSLCipher' => opts['SSLCipher'] || ssl_cipher,
|
|
'Proxies' => proxies,
|
|
'Timeout' => (opts['ConnectTimeout'] || connect_timeout || 10).to_i,
|
|
'Context' =>
|
|
{
|
|
'Msf' => framework,
|
|
'MsfExploit' => self,
|
|
})
|
|
|
|
# enable evasions on this socket
|
|
set_tcp_evasions(nsock)
|
|
|
|
# Set this socket to the global socket as necessary
|
|
self.sock = nsock if (global)
|
|
|
|
# Add this socket to the list of sockets created by this exploit
|
|
add_socket(nsock)
|
|
|
|
return nsock
|
|
end
|
|
|
|
# Enable evasions on a given client
|
|
def set_tcp_evasions(socket)
|
|
|
|
if( datastore['TCP::max_send_size'].to_i == 0 and datastore['TCP::send_delay'].to_i == 0)
|
|
return
|
|
end
|
|
|
|
return if socket.respond_to?('evasive')
|
|
|
|
socket.extend(EvasiveTCP)
|
|
|
|
if ( datastore['TCP::max_send_size'].to_i > 0)
|
|
socket._send_size = datastore['TCP::max_send_size']
|
|
socket.denagle
|
|
socket.evasive = true
|
|
end
|
|
|
|
if ( datastore['TCP::send_delay'].to_i > 0)
|
|
socket._send_delay = datastore['TCP::send_delay']
|
|
socket.evasive = true
|
|
end
|
|
end
|
|
|
|
def handler(nsock = self.sock)
|
|
# If the handler claims the socket, then we don't want it to get closed
|
|
# during cleanup
|
|
if ((rv = super) == Handler::Claimed)
|
|
if (nsock == self.sock)
|
|
self.sock = nil
|
|
end
|
|
|
|
# Remove this socket from the list of sockets so that it will not be
|
|
# aborted.
|
|
remove_socket(nsock)
|
|
end
|
|
|
|
return rv
|
|
end
|
|
|
|
#
|
|
# Closes the TCP connection
|
|
#
|
|
def disconnect(nsock = self.sock)
|
|
begin
|
|
if (nsock)
|
|
nsock.shutdown
|
|
nsock.close
|
|
end
|
|
rescue IOError
|
|
end
|
|
|
|
if (nsock == sock)
|
|
self.sock = nil
|
|
end
|
|
|
|
# Remove this socket from the list of sockets created by this exploit
|
|
remove_socket(nsock)
|
|
end
|
|
|
|
#
|
|
# Performs cleanup, disconnects the socket if necessary
|
|
#
|
|
def cleanup
|
|
super
|
|
disconnect
|
|
end
|
|
|
|
def print_prefix
|
|
if rhost
|
|
super + peer + " - "
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
##
|
|
#
|
|
# Wrappers for getters
|
|
#
|
|
##
|
|
|
|
#
|
|
# Returns the local host for outgoing connections
|
|
#
|
|
def chost
|
|
datastore['CHOST']
|
|
end
|
|
|
|
#
|
|
# Returns the TCP connection timeout
|
|
#
|
|
def connect_timeout
|
|
datastore['ConnectTimeout']
|
|
end
|
|
|
|
#
|
|
# Returns the local port for outgoing connections
|
|
#
|
|
def cport
|
|
datastore['CPORT']
|
|
end
|
|
|
|
#
|
|
# Returns the local host
|
|
#
|
|
def lhost
|
|
datastore['LHOST']
|
|
end
|
|
|
|
#
|
|
# Returns the local port
|
|
#
|
|
def lport
|
|
datastore['LPORT']
|
|
end
|
|
|
|
# Returns the rhost:rport
|
|
def peer
|
|
"#{rhost}:#{rport}"
|
|
end
|
|
|
|
#
|
|
# Returns the proxy configuration
|
|
#
|
|
def proxies
|
|
datastore['Proxies']
|
|
end
|
|
|
|
#
|
|
# Returns the target host
|
|
#
|
|
def rhost
|
|
datastore['RHOST']
|
|
end
|
|
|
|
#
|
|
# Returns the remote port
|
|
#
|
|
def rport
|
|
datastore['RPORT']
|
|
end
|
|
|
|
#
|
|
# Returns the boolean indicating SSL
|
|
#
|
|
def ssl
|
|
datastore['SSL']
|
|
end
|
|
|
|
#
|
|
# Returns the string indicating SSLVersion
|
|
#
|
|
def ssl_version
|
|
datastore['SSLVersion']
|
|
end
|
|
|
|
#
|
|
# Returns the SSL certification verification mechanism
|
|
#
|
|
def ssl_verify_mode
|
|
datastore['SSLVerifyMode']
|
|
end
|
|
|
|
#
|
|
# Returns the SSL cipher to use for the context
|
|
#
|
|
def ssl_cipher
|
|
datastore['SSLCipher']
|
|
end
|
|
|
|
protected
|
|
|
|
attr_accessor :sock
|
|
|
|
end
|
|
|
|
end
|