Module: Msf::Handler::Reverse

Included in:
ReverseHttp, ReverseSctp, ReverseSsh, ReverseTcp, ReverseTcpDouble, ReverseTcpDoubleSSL
Defined in:
lib/msf/core/handler/reverse.rb,
lib/msf/core/handler/reverse/ssl.rb,
lib/msf/core/handler/reverse/comm.rb

Overview

Options and methods needed for all handlers that listen for a connection from the payload.

Defined Under Namespace

Modules: Comm, SSL

Instance Method Summary collapse

Instance Method Details

#bind_addressesArray<String>

A list of addresses to attempt to bind, in preferred order.

Returns:

  • (Array<String>)

    a two-element array. The first element will be the address that ‘datastore` resolves to, the second will be the INADDR_ANY address for IPv4 or IPv6, depending on the version of the first element.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/msf/core/handler/reverse.rb', line 42

def bind_addresses
  # Switch to IPv6 ANY address if the LHOST is also IPv6
  addr = Rex::Socket.resolv_nbo(datastore['LHOST'])

  # 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"
  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

  addrs = [ addr, any ]

  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

#bind_portInteger

Returns:

  • (Integer)


70
71
72
73
# File 'lib/msf/core/handler/reverse.rb', line 70

def bind_port
  port = datastore['ReverseListenerBindPort'].to_i
  (port > 0) ? port : datastore['LPORT'].to_i
end

#initialize(info = {}) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/msf/core/handler/reverse.rb', line 9

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

#is_loopback_address?(address) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
34
# File 'lib/msf/core/handler/reverse.rb', line 26

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

#setup_handlerObject

Starts the listener but does not actually attempt to accept a connection. Throws socket exceptions if it fails to start the listener.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/msf/core/handler/reverse.rb', line 80

def setup_handler
  if !datastore['Proxies'].blank? && !datastore['ReverseAllowProxy']
    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
      via = via_string(self.listener_sock.client) if self.listener_sock.respond_to?(:client)
      print_status("Started #{human_name} handler on #{ip}:#{local_port} #{via}")
      break
    end
  end
  raise ex if (ex)
end