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

Included in:
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:



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

def service
  @service
end

Instance Method Details

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

Determines appropriate listener comm



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

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.



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

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

#bindportObject



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

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

#cleanupObject

Stops the service, if one was created.



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

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



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

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.



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

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
# 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 ]),

    ], 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.



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

def on_client_data(client)
end

#primerObject

Primer method to call after starting service but before handling connections



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

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.



139
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
# File 'lib/msf/core/exploit/remote/socket_server.rb', line 139

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.



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

def srvhost
  datastore['SRVHOST']
end

#srvportObject

Returns the local port that is being listened on.



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

def srvport
  datastore['SRVPORT']
end

#start_service(opts = {}) ⇒ Object

Starts the service. Override this method in consumers



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

def start_service(opts = {})
end

#via_string(comm) ⇒ Object (protected)



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

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