CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/meterpreter/channels/pool.rb
Views: 1904
1
# -*- coding: binary -*-
2
3
require 'rex/post/meterpreter/channel'
4
5
module Rex
6
module Post
7
module Meterpreter
8
module Channels
9
10
###
11
#
12
# This class acts as a base class for all channels that are classified
13
# as 'pools'. This means that only one side of the channel, typically
14
# the client half, acts on the other half of the channel. Examples
15
# of pools come in the form of files where the remote side never sends
16
# any unrequested data.
17
#
18
# Another key distinction of Pools is that they, in general, support
19
# the DIO mode 'seek' which allows for changing the position, or offset,
20
# into the channel.
21
#
22
###
23
class Pool < Rex::Post::Meterpreter::Channel
24
25
class << self
26
def cls
27
return CHANNEL_CLASS_POOL
28
end
29
end
30
31
##
32
#
33
# Constructor
34
#
35
##
36
37
#
38
# Passes the initialization information up to the base class
39
#
40
def initialize(client, cid, type, flags, packet, **_)
41
super(client, cid, type, flags, packet)
42
end
43
44
##
45
#
46
# Channel interaction
47
#
48
##
49
50
#
51
# Checks to see if the EOF flag has been set on the pool.
52
#
53
def eof
54
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_EOF)
55
56
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
57
58
begin
59
response = self.client.send_request(request)
60
rescue
61
return true
62
end
63
64
if (response.has_tlv?(TLV_TYPE_BOOL))
65
return response.get_tlv_value(TLV_TYPE_BOOL)
66
end
67
68
return false
69
end
70
71
#
72
# Reads data from the remote side of the pool and raises EOFError if the
73
# pool has been reached EOF.
74
#
75
def read(length = nil)
76
begin
77
data = super(length)
78
rescue
79
data = nil
80
end
81
82
if (((data == nil) || (data.length == 0)) &&
83
(self.eof))
84
raise EOFError
85
end
86
87
return data
88
end
89
90
#
91
# This method seeks to an offset within the remote side of the pool using
92
# the standard seek whence clauses.
93
#
94
def seek(offset, whence = SEEK_SET)
95
sane = 0
96
97
# Just in case...
98
case whence
99
when ::IO::SEEK_SET
100
sane = 0
101
when ::IO::SEEK_CUR
102
sane = 1
103
when ::IO::SEEK_END
104
sane = 2
105
else
106
raise RuntimeError, "Invalid seek whence #{whence}.", caller
107
end
108
109
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_SEEK)
110
111
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
112
request.add_tlv(TLV_TYPE_SEEK_OFFSET, offset)
113
request.add_tlv(TLV_TYPE_SEEK_WHENCE, sane)
114
115
begin
116
self.client.send_request(request)
117
tell
118
rescue
119
return -1
120
end
121
end
122
123
#
124
# Synonym for tell.
125
#
126
def pos
127
tell
128
end
129
130
#
131
# This method returns the current file pointer position to the caller.
132
#
133
def tell
134
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_TELL)
135
pos = -1
136
137
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
138
139
begin
140
response = self.client.send_request(request)
141
rescue
142
return pos
143
end
144
145
# Set the return value to the position that we're at
146
if (response.has_tlv?(TLV_TYPE_SEEK_POS))
147
pos = response.get_tlv_value(TLV_TYPE_SEEK_POS)
148
end
149
150
return pos
151
end
152
153
protected
154
attr_accessor :_eof # :nodoc:
155
156
end
157
158
end; end; end; end
159
160
161