Module: Msf::Exploit::Remote::TcpServer

Included in:
FtpServer, HttpServer, SMBServer
Defined in:
lib/msf/core/exploit/tcp.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#cleanupObject

Stops the service, if one was created.


339
340
341
342
343
344
345
# File 'lib/msf/core/exploit/tcp.rb', line 339

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

#exploitObject

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


318
319
320
321
322
323
324
325
326
327
328
# File 'lib/msf/core/exploit/tcp.rb', line 318

def exploit

  start_service()
  print_status("Server started.")

  # Call the exploit primer
  primer

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

#initialize(info = {}) ⇒ Object


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/msf/core/exploit/tcp.rb', line 286

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

  register_options(
    [
      OptBool.new('SSL',        [ false, 'Negotiate SSL for incoming connections', false]),
      OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'SSL3', ['SSL2', 'SSL3', 'TLS1']]),
      OptPath.new('SSLCert',    [ false, 'Path to a custom SSL certificate (default is randomly generated)']),
      OptAddress.new('SRVHOST', [ true, "The local host to listen on. This must be an address on the local machine or 0.0.0.0", '0.0.0.0' ]),
      OptPort.new('SRVPORT',    [ true, "The local port to listen on.", 8080 ]),

    ], Msf::Exploit::Remote::TcpServer)

  register_advanced_options(
    [
      OptString.new('ListenerComm', [ false, 'The specific communication channel to use for this service']),
      OptBool.new('SSLCompression', [ false, 'Enable SSL/TLS-level compression', false ])
    ], Msf::Exploit::Remote::TcpServer)

  register_evasion_options(
    [
      OptInt.new('TCP::max_send_size', [false, 'Maximum 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

#on_client_close(client) ⇒ Object

Called when a client has disconnected.


362
363
# File 'lib/msf/core/exploit/tcp.rb', line 362

def on_client_close(client)
end

#on_client_connect(client) ⇒ Object

Called when a client connects.


350
351
# File 'lib/msf/core/exploit/tcp.rb', line 350

def on_client_connect(client)
end

#on_client_data(client) ⇒ Object

Called when a client has data available for reading.


356
357
# File 'lib/msf/core/exploit/tcp.rb', line 356

def on_client_data(client)
end

#primerObject

Primer method to call after starting service but before handling connections


333
334
# File 'lib/msf/core/exploit/tcp.rb', line 333

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.


478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'lib/msf/core/exploit/tcp.rb', line 478

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.


444
445
446
# File 'lib/msf/core/exploit/tcp.rb', line 444

def srvhost
  datastore['SRVHOST']
end

#srvportObject

Returns the local port that is being listened on.


451
452
453
# File 'lib/msf/core/exploit/tcp.rb', line 451

def srvport
  datastore['SRVPORT']
end

#sslObject

Returns the SSL option


458
459
460
# File 'lib/msf/core/exploit/tcp.rb', line 458

def ssl
  datastore['SSL']
end

#ssl_certObject

Returns the SSLCert option


465
466
467
# File 'lib/msf/core/exploit/tcp.rb', line 465

def ssl_cert
  datastore['SSLCert']
end

#ssl_compressionBool


470
471
472
# File 'lib/msf/core/exploit/tcp.rb', line 470

def ssl_compression
  datastore['SSLCompression']
end

#start_service(*args) ⇒ Object

Starts the service.


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'lib/msf/core/exploit/tcp.rb', line 368

def start_service(*args)
  begin

    comm = datastore['ListenerComm']
    if comm == "local"
      comm = ::Rex::Socket::Comm::Local
    else
      comm = nil
    end

    self.service = Rex::Socket::TcpServer.create(
      'LocalHost' => srvhost,
      'LocalPort' => srvport,
      'SSL'       => ssl,
      'SSLCert'   => ssl_cert,
      'SSLCompression' => ssl_compression,
      'Comm'      => comm,
      'Context'   =>
        {
          'Msf'        => framework,
          'MsfExploit' => self,
        })

    self.service.on_client_connect_proc = Proc.new { |client|
      on_client_connect(client)
    }
    self.service.on_client_data_proc = Proc.new { |client|
      on_client_data(client)
    }
    self.service.on_client_close_proc = Proc.new { |client|
      on_client_close(client)
    }

    # Start the listening service
    self.service.start

  rescue ::Errno::EACCES => e
    if (srvport.to_i < 1024)
      print_line(" ")
      print_error("Could not start the TCP server: #{e}.")
      print_error(
        "This module is configured to use a privileged TCP port (#{srvport}). " +
        "On Unix systems, only the root user account is allowed to bind to privileged ports." +
        "Please run the framework as root to use this module."
      )
      print_error(
        "On Microsoft Windows systems, this error is returned when a process attempts to "+
        "listen on a host/port combination that is already in use. For example, Windows XP "+
        "will return this error if a process attempts to bind() over the system SMB/NetBIOS services."
      )
      print_line(" ")
    end
    raise e
  end
end

#stop_serviceObject

Stops the service.


427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/msf/core/exploit/tcp.rb', line 427

def stop_service
  if (service)
    begin
      self.service.deref if self.service.kind_of?(Rex::Service)
      if self.service.kind_of?(Rex::Socket)
        self.service.close
        self.service.stop
      end
      self.service = nil
    rescue ::Exception
    end
  end
end