2015-10-07 09:59:12 -05:00
module Msf
module Handler
2015-10-29 15:02:26 -05:00
# Options and methods needed for all handlers that listen for a connection
# from the payload.
2015-10-07 09:59:12 -05:00
module Reverse
autoload :Comm , 'msf/core/handler/reverse/comm'
autoload :SSL , 'msf/core/handler/reverse/ssl'
2015-10-29 15:02:26 -05:00
def initialize ( info = { } )
super
register_options (
[
Opt :: LHOST ,
Opt :: LPORT ( 4444 )
] , Msf :: Handler :: Reverse )
register_advanced_options (
[
OptPort . new ( 'ReverseListenerBindPort' , [ false , 'The port to bind to on the local system if different from LPORT' ] ) ,
OptBool . new ( 'ReverseAllowProxy' , [ true , 'Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST' , false ] ) ,
] , Msf :: Handler :: Reverse
)
end
2017-03-16 13:06:07 -05:00
def is_loopback_address? ( address )
begin
a = IPAddr . new ( address . to_s )
return true if IPAddr . new ( '127.0.0.1/8' ) === a
return true if IPAddr . new ( '::1' ) === a
rescue
end
false
end
2015-11-03 23:03:13 -06:00
# A list of addresses to attempt to bind, in preferred order.
#
# @return [Array<String>] a two-element array. The first element will be
# the address that `datastore['LHOST']` resolves to, the second will
# be the INADDR_ANY address for IPv4 or IPv6, depending on the version
# of the first element.
def bind_addresses
# Switch to IPv6 ANY address if the LHOST is also IPv6
addr = Rex :: Socket . resolv_nbo ( datastore [ 'LHOST' ] )
2017-03-16 13:06:07 -05:00
2015-11-03 23:03:13 -06:00
# First attempt to bind LHOST. If that fails, the user probably has
# something else listening on that interface. Try again with ANY_ADDR.
any = ( addr . length == 4 ) ? " 0.0.0.0 " : " ::0 "
2017-03-16 13:06:07 -05:00
addr = Rex :: Socket . addr_ntoa ( addr )
# Checking if LHOST is a loopback address
if is_loopback_address? ( addr )
print_warning ( " You are binding to a loopback address by setting LHOST to #{ addr } . Did you want ReverseListenerBindAddress? " )
end
2015-11-03 23:03:13 -06:00
2017-03-16 13:06:07 -05:00
addrs = [ addr , any ]
2015-11-03 23:03:13 -06:00
if not datastore [ 'ReverseListenerBindAddress' ] . to_s . empty?
# Only try to bind to this specific interface
addrs = [ datastore [ 'ReverseListenerBindAddress' ] ]
# Pick the right "any" address if either wildcard is used
addrs [ 0 ] = any if ( addrs [ 0 ] == " 0.0.0.0 " or addrs == " ::0 " )
end
addrs
end
2017-03-08 00:02:50 +05:30
2015-10-29 15:02:26 -05:00
# @return [Integer]
def bind_port
port = datastore [ 'ReverseListenerBindPort' ] . to_i
2016-05-26 18:34:53 -05:00
( port > 0 ) ? port : datastore [ 'LPORT' ] . to_i
2015-10-29 15:02:26 -05:00
end
2015-11-03 23:03:13 -06:00
#
# Starts the listener but does not actually attempt
# to accept a connection. Throws socket exceptions
# if it fails to start the listener.
#
def setup_handler
2016-11-22 09:29:04 -06:00
if ! datastore [ 'Proxies' ] . blank? && ! datastore [ 'ReverseAllowProxy' ]
2015-11-03 23:03:13 -06:00
raise RuntimeError , " TCP connect-back payloads cannot be used with Proxies. Use 'set ReverseAllowProxy true' to override this behaviour. "
end
ex = false
comm = select_comm
local_port = bind_port
bind_addresses . each do | ip |
begin
self . listener_sock = Rex :: Socket :: TcpServer . create (
'LocalHost' = > ip ,
'LocalPort' = > local_port ,
'Comm' = > comm ,
'Context' = >
{
'Msf' = > framework ,
'MsfPayload' = > self ,
'MsfExploit' = > assoc_exploit
} )
rescue
ex = $!
print_error ( " Handler failed to bind to #{ ip } : #{ local_port } :- #{ comm } - " )
else
ex = false
2021-09-24 20:47:06 +10:00
via = via_string ( self . listener_sock . client ) if self . listener_sock . respond_to? ( :client )
2015-11-03 23:03:13 -06:00
print_status ( " Started #{ human_name } handler on #{ ip } : #{ local_port } #{ via } " )
break
end
end
raise ex if ( ex )
end
2015-10-07 09:59:12 -05:00
end
end
end