2012-06-29 05:18:28 +00:00
# -*- coding: binary -*-
2014-10-14 23:43:40 +00:00
require 'msf/core/exploit/tcp_server'
2005-06-05 05:42:43 +00:00
module Msf
2009-03-14 05:06:13 +00:00
module EvasiveTCP
2013-08-30 21:28:33 +00:00
attr_accessor :_send_size , :_send_delay , :evasive
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
def denagle
begin
setsockopt ( Socket :: IPPROTO_TCP , Socket :: TCP_NODELAY , 1 )
rescue :: Exception
end
end
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
def write ( buf , opts = { } )
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
return super ( buf , opts ) if not @evasive
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
ret = 0
idx = 0
len = @_send_size || buf . length
2009-03-14 05:06:13 +00:00
2013-08-30 21:28:33 +00:00
while ( idx < buf . length )
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
if ( @_send_delay and idx > 0 )
:: IO . select ( nil , nil , nil , @_send_delay )
end
2009-11-03 18:09:05 +00:00
2013-08-30 21:28:33 +00:00
pkt = buf [ idx , len ]
2006-02-03 19:55:56 +00:00
2013-08-30 21:28:33 +00:00
res = super ( pkt , opts )
flush ( )
2006-02-03 19:55:56 +00:00
2013-08-30 21:28:33 +00:00
idx += len
ret += res if res
end
ret
end
2006-02-03 19:55:56 +00:00
end
2005-06-05 05:42:43 +00:00
###
#
# This module provides methods for establish a connection to a remote host and
# communicating with it.
#
###
module Exploit::Remote::Tcp
2005-11-15 15:11:43 +00:00
2013-08-30 21:28:33 +00:00
#
# 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 for outgoing connections' , false ] ) ,
2015-10-02 20:26:49 +00:00
OptEnum . new ( 'SSLVersion' , [ false , 'Specify the version of SSL/TLS to be used (TLS and SSL23 are auto-negotiate)' , 'TLS1' , [ 'SSL2' , 'SSL3' , 'SSL23' , 'TLS' , 'TLS1' , 'TLS1.1' , 'TLS1.2' ] ] ) ,
2013-08-30 21:28:33 +00:00
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
2015-12-23 17:44:55 +00:00
# Returns the rhost:rport
def peer
" #{ rhost } : #{ rport } "
end
2013-08-30 21:28:33 +00:00
#
# 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 (
2015-09-28 15:31:17 +00:00
'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' = >
2013-08-30 21:28:33 +00:00
{
'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
##
#
# Wrappers for getters
#
##
#
# Returns the target host
#
def rhost
datastore [ 'RHOST' ]
end
#
# Returns the remote port
#
def rport
datastore [ 'RPORT' ]
end
#
# Returns the local host
#
def lhost
datastore [ 'LHOST' ]
end
#
# Returns the local port
#
def lport
datastore [ 'LPORT' ]
end
#
# Returns the local host for outgoing connections
#
def chost
datastore [ 'CHOST' ]
end
#
# Returns the local port for outgoing connections
#
def cport
datastore [ 'CPORT' ]
end
#
# Returns the boolean indicating SSL
#
def ssl
datastore [ 'SSL' ]
end
#
# Returns the string indicating SSLVersion
#
def ssl_version
datastore [ 'SSLVersion' ]
end
#
# Returns the proxy configuration
#
def proxies
datastore [ 'Proxies' ]
end
#
# Returns the TCP connection timeout
#
def connect_timeout
datastore [ 'ConnectTimeout' ]
end
2009-11-03 18:09:05 +00:00
2015-09-28 15:31:17 +00:00
#
# 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
2005-06-05 06:07:18 +00:00
protected
2013-08-30 21:28:33 +00:00
attr_accessor :sock
2005-06-05 06:07:18 +00:00
2005-06-05 05:42:43 +00:00
end
2008-11-16 20:54:41 +00:00
end