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

Inherits:
Stream
  • Object
show all
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb

Overview

This class represents a logical TCP client connection that is established from the remote machine and tunnelled through the established meterpreter connection, similar to an SSH port forward.

Instance Attribute Summary

Attributes inherited from Channel

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

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Stream

cls

Methods included from SocketAbstraction

#_write, #cleanup, #dio_write_handler

Methods inherited from Channel

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

Methods included from InboundPacketHandler

#request_handler, #response_handler

Constructor Details

#initialize(client, cid, type, flags, packet, sock_params: nil) ⇒ TcpClientChannel

Passes the channel initialization information up to the base class.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb', line 72

def initialize(client, cid, type, flags, packet, sock_params: nil)
  super(client, cid, type, flags, packet)

  lsock.extend(SocketInterface)
  lsock.extend(DirectChannelWrite)
  lsock.channel = self

  rsock.extend(SocketInterface)
  rsock.channel = self

  unless sock_params.nil?
    @params = sock_params.merge(Socket.parameters_from_response(packet))
    lsock.extend(Rex::Socket::SslTcp) if sock_params.ssl
  end

  # synchronize access so the socket isn't closed while initializing, this is particularly important for SSL
  lsock.synchronize_access { lsock.initsock(@params) }
  rsock.synchronize_access { rsock.initsock(@params) }
end

Class Method Details

.open(client, params) ⇒ Object

Opens a TCP client channel using the supplied parameters.



35
36
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
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb', line 35

def TcpClientChannel.open(client, params)
  Channel.create(client, 'stdapi_net_tcp_client', self, CHANNEL_FLAG_SYNCHRONOUS,
    [
      {
        'type'  => TLV_TYPE_PEER_HOST,
        'value' => params.peerhost
      },
      {
        'type'  => TLV_TYPE_PEER_PORT,
        'value' => params.peerport
      },
      {
        'type'  => TLV_TYPE_LOCAL_HOST,
        'value' => params.localhost
      },
      {
        'type'  => TLV_TYPE_LOCAL_PORT,
        'value' => params.localport
      },
      {
        'type'  => TLV_TYPE_CONNECT_RETRIES,
        'value' => params.retries
      }
    ],
    sock_params: params
  )
end

Instance Method Details

#close_writeObject

Closes the write half of the connection.



101
102
103
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb', line 101

def close_write
  return shutdown(1)
end

#monitor_rsock(name = 'MonitorRemote') ⇒ Object



92
93
94
95
96
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb', line 92

def monitor_rsock(name = 'MonitorRemote')
  # call #close on exit instead of #close_write because this is triggered in response to lsock.close
  # lsock.close -> rsock EOF -> #close -> Meterpreter close
  monitor_sock(rsock, sink: self, name: name, on_exit: method(:close))
end

#shutdown(how = 1) ⇒ Object

Shutdown the connection

0 -> future reads 1 -> future sends 2 -> both



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb', line 112

def shutdown(how = 1)
  return false if self.cid.nil?

  request = Packet.create_request(COMMAND_ID_STDAPI_NET_SOCKET_TCP_SHUTDOWN)

  request.add_tlv(TLV_TYPE_SHUTDOWN_HOW, how)
  request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)

  client.send_request(request)

  return true
end