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

Inherits:
Channel
  • Object
show all
Extended by:
InboundPacketHandler
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb

Constant Summary collapse

@@server_channels =

This is a class variable to store all pending client tcp connections which have not been passed off via a call to the respective server tcp channels accept method. The dictionary key is the tcp server channel instance and the values held are an array of pending tcp client channels connected to the tcp server channel.

{}

Instance Attribute Summary

Attributes inherited from Channel

#cid, #client, #cls, #flags, #params, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods included from InboundPacketHandler

request_handler, response_handler

Methods inherited from Channel

_close, #_close, #_read, #_write, #close, #close_read, #close_write, create, #dio_close_handler, #dio_handler, #dio_map, #dio_read_handler, #dio_write_handler, finalize, #flag?, #interactive, #read, #synchronous?, #write

Constructor Details

#initialize(client, cid, type, flags) ⇒ TcpServerChannel

Simply initilize this instance.


112
113
114
115
116
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 112

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] = []
end

Class Method Details

.clsObject


84
85
86
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 84

def cls
  return CHANNEL_CLASS_STREAM
end

.open(client, params) ⇒ Object

Open a new tcp server channel on the remote end.


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 93

def TcpServerChannel.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) ⇒ Object

This is the request handler which is registerd 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.


37
38
39
40
41
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 37

def request_handler( client, packet )

  if( 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 )

    if( cid == nil or pid == nil )
      return false
    end

    server_channel = client.find_channel( pid )
    if( server_channel == nil )
      return false
    end

    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

    if( @@server_channels[server_channel] == nil )
      @@server_channels[server_channel] = []
    end

    @@server_channels[server_channel] << client_channel

    return true
  end

  return false
end

Instance Method Details

#accept(opts = {}) ⇒ Object

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


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 135

def accept( opts={} )
  timeout = opts['Timeout'] || -1
  if( timeout == -1 )
    result = _accept
  else
    begin
      ::Timeout.timeout( timeout ) {
        result = _accept
      }
    rescue Timeout::Error
      result = nil
    end
  end
  return result
end

#accept_nonblockObject

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.


122
123
124
125
126
127
128
129
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb', line 122

def accept_nonblock
  result = nil
  if( @@server_channels[self].length > 0 )
    channel = @@server_channels[self].shift
    result = channel.lsock
  end
  return result
end