Module: Msf::Exploit::Remote::SocketServer

Included in:
DHCPServer, DNS::Server, LDAP::Server, Msf::Exploit::Remote::SMB::RelayServer, Msf::Exploit::Remote::SMB::Server, TcpServer
Defined in:
lib/msf/core/exploit/remote/socket_server.rb

Overview

This mixin provides a generic interface for running a socket server of some sort that is designed to exploit clients. Exploits that include this mixin automatically take a passive stance.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#serviceObject (protected)

:nodoc:



206
207
208
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 206

def service
  @service
end

Instance Method Details

#_determine_server_comm(ip, srv_comm = datastore['ListenerComm'].to_s) ⇒ Object (protected)

Determines appropriate listener comm



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 175

def _determine_server_comm(ip, srv_comm = datastore['ListenerComm'].to_s)
  comm = nil

  case srv_comm
  when 'local'
    comm = ::Rex::Socket::Comm::Local
  when /\A-?[0-9]+\Z/
    comm = framework.sessions.get(srv_comm.to_i)
    raise(RuntimeError, "Socket Server Comm (Session #{srv_comm}) does not exist") unless comm
    raise(RuntimeError, "Socket Server Comm (Session #{srv_comm}) does not implement Rex::Socket::Comm") unless comm.is_a? ::Rex::Socket::Comm
  when nil, ''
    unless ip.nil?
      comm = Rex::Socket::SwitchBoard.best_comm(ip)
    end
  else
    raise(RuntimeError, "SocketServer Comm '#{srv_comm}' is invalid")
  end

  comm || ::Rex::Socket::Comm::Local
end

#bindhostObject

Returns the address that the service is bound to. Can be different from SRVHOST when the ListenerBindAddress is specified and can be used for binding to a specific address when NATing is in place.



128
129
130
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 128

def bindhost
  datastore['ListenerBindAddress'].blank? ? datastore['SRVHOST'] : datastore['ListenerBindAddress']
end

#bindportObject



132
133
134
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 132

def bindport
  datastore['ListenerBindPort'].blank? ? datastore['SRVPORT'] : datastore['ListenerBindPort']
end

#cleanupObject

Stops the service, if one was created.



62
63
64
65
66
67
68
69
70
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 62

def cleanup
  super
  if service
    stopped = cleanup_service
    if stopped
      print_status("Server stopped.")
    end
  end
end

#cleanup_serviceObject

Cleans up the service; either closing the socket, or dereferencing the service



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 87

def cleanup_service
  if service
    begin
      if self.service.kind_of?(Rex::Service)
        temp_service = self.service
        self.service = nil
        return temp_service.deref
      else
        if self.service.kind_of?(Rex::Socket) || self.service.kind_of?(Rex::Post::Meterpreter::Channel)
          self.service.close
          self.service.stop
        end
      end

      self.service = nil
      true
    rescue ::Exception => e
      print_error(e.message)
      false
    end
  end
end

#exploitObject

This mixin overrides the exploit method so that it can initiate the service that corresponds with what the client has requested.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 41

def exploit

  start_service()
  print_status("Server started.")

  # Call the exploit primer
  primer

  # Wait on the service to stop
  self.service.wait if service
end

#initialize(info = {}) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 15

def initialize(info = {})
  super(update_info(info,
    'Stance' => Msf::Exploit::Stance::Passive))

  register_options(
    [
      OptAddressLocal.new('SRVHOST', [ true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ]),
      OptPort.new('SRVPORT',    [ true, "The local port to listen on.", 8080 ]),
      OptBool.new('SRVSSL', [ false, 'Negotiate SSL/TLS for local server connections', false], fallbacks: ['SSL'])

    ], Msf::Exploit::Remote::SocketServer
  )

  register_advanced_options(
    [
      OptAddress.new('ListenerBindAddress', [ false, 'The specific IP address to bind to if different from SRVHOST']),
      OptPort.new('ListenerBindPort', [false, 'The port to bind to if different from SRVPORT']),
      OptString.new('ListenerComm', [ false, 'The specific communication channel to use for this service'])
    ], Msf::Exploit::Remote::SocketServer
  )
end

#on_client_data(client) ⇒ Object

Called when a client has data available for reading.



75
76
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 75

def on_client_data(client)
end

#primerObject

Primer method to call after starting service but before handling connections



56
57
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 56

def primer
end

#regenerate_payload(cli, arch = nil, platform = nil, target = nil) ⇒ Object

Re-generates the payload, substituting the current RHOST and RPORT with the supplied client host and port from the socket.



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 140

def regenerate_payload(cli, arch = nil, platform = nil, target = nil)

  ohost = datastore['RHOST']
  oport = datastore['RPORT']
  p = nil

  begin
    # Update the datastore with the supplied client peerhost/peerport
    datastore['RHOST'] = cli.peerhost
    datastore['RPORT'] = cli.peerport

    if ((p = super(arch, platform, target)) == nil)
      print_error("Failed to generate payload")
      return nil
    end

    # Allow the payload to start a new handler
    add_handler({
      'RHOST' => datastore['RHOST'],
      'RPORT' => datastore['RPORT']
    })

  ensure
    datastore['RHOST'] = ohost
    datastore['RPORT'] = oport
  end

  p
end

#srvhostObject

Returns the local host that is being listened on.



113
114
115
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 113

def srvhost
  datastore['SRVHOST']
end

#srvportObject

Returns the local port that is being listened on.



120
121
122
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 120

def srvport
  datastore['SRVPORT']
end

#start_service(opts = {}) ⇒ Object

Starts the service. Override this method in consumers



81
82
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 81

def start_service(opts = {})
end

#via_string(comm) ⇒ Object (protected)



196
197
198
199
200
201
202
203
204
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 196

def via_string(comm)
  if comm.respond_to?(:type) && comm.respond_to?(:sid)
    via = "via the #{comm.type} on session #{comm.sid}"
  else
    via = ""
  end

  via
end