class Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel

Public Class Methods

cls() click to toggle source
# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 70
def self.cls
  CHANNEL_CLASS_STREAM
end
new(client, cid, type, flags) click to toggle source

Simply initilize this instance.

Calls superclass method Rex::Post::Meterpreter::Channel::new
# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 97
def initialize(client, cid, type, flags)
  super(client, cid, type, flags)
  # add this instance to the class variables dictionary of tcp server channels
  @@server_channels[self] ||= ::Queue.new
end
open(client, params) click to toggle source

Open a new tcp server channel on the remote end.

@return [Channel]

# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 78
def self.open(client, params)
  c = Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
    [
      {
      'type'  => TLV_TYPE_LOCAL_HOST,
      'value' => params.localhost
      },
      {
      'type'  => TLV_TYPE_LOCAL_PORT,
      'value' => params.localport
      }
    ] )
  c.params = params
  c
end
request_handler(client, packet) click to toggle source

This is the request handler which is registered to the respective meterpreter instance via Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket. All incoming requests from the meterpreter for a 'tcp_channel_open' will be processed here. We create a new TcpClientChannel for each request received and store it in the respective tcp server channels list of new pending client channels. These new tcp client channels are passed off via a call the the tcp server channels accept() method.

# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 33
def self.request_handler(client, packet)
  return false unless packet.method == "tcp_channel_open"

  cid       = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
  pid       = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
  localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
  localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
  peerhost  = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
  peerport  = packet.get_tlv_value( TLV_TYPE_PEER_PORT )

  return false if cid.nil? || pid.nil?

  server_channel = client.find_channel(pid)

  return false if server_channel.nil?

  params = Rex::Socket::Parameters.from_hash(
    {
      'Proto'     => 'tcp',
      'LocalHost' => localhost,
      'LocalPort' => localport,
      'PeerHost'  => peerhost,
      'PeerPort'  => peerport,
      'Comm'      => server_channel.client
    }
  )

  client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS)

  client_channel.params = params

  @@server_channels[server_channel] ||= ::Queue.new
  @@server_channels[server_channel].enq(client_channel)

  true
end

Public Instance Methods

accept(opts = {}) click to toggle source

Accept a new tcp client connection form this tcp server channel. This method will block indefinatly if no timeout is specified.

# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 115
def accept(opts = {})
  timeout = opts['Timeout']
  if (timeout.nil? || timeout <= 0)
    timeout = 0
  end

  result = nil
  begin
    ::Timeout.timeout(timeout) {
      result = _accept
    }
  rescue Timeout::Error
  end

  result
end
accept_nonblock() click to toggle source

Accept a new tcp client connection form this tcp server channel. This method does not block and returns nil if no new client connection is available.

# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 107
def accept_nonblock
  _accept(true)
end

Protected Instance Methods

_accept(nonblock = false) click to toggle source
# File lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb, line 134
def _accept(nonblock = false)
  result = nil

  channel = @@server_channels[self].deq(nonblock)

  if channel
    result = channel.lsock
  end

  if result != nil && !result.kind_of?(Rex::Socket::Tcp)
    result.extend(Rex::Socket::Tcp)
  end

  result
end