rex 2.0.9 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rex/exploitation/cmdstager/bourne.rb +14 -8
- data/lib/rex/exploitation/cmdstager/echo.rb +3 -3
- data/lib/rex/exploitation/js/memory.rb +1 -1
- data/lib/rex/java/serialization/model/contents.rb +1 -1
- data/lib/rex/mime/message.rb +1 -1
- data/lib/rex/parser/acunetix_nokogiri.rb +2 -0
- data/lib/rex/parser/appscan_nokogiri.rb +1 -1
- data/lib/rex/parser/burp_issue_nokogiri.rb +139 -0
- data/lib/rex/parser/burp_session_nokogiri.rb +1 -1
- data/lib/rex/parser/fs/bitlocker.rb +233 -0
- data/lib/rex/parser/fusionvm_nokogiri.rb +2 -2
- data/lib/rex/parser/ini.rb +1 -8
- data/lib/rex/parser/nokogiri_doc_mixin.rb +5 -0
- data/lib/rex/payloads/meterpreter/config.rb +23 -4
- data/lib/rex/post/meterpreter/channel.rb +8 -3
- data/lib/rex/post/meterpreter/client.rb +1 -0
- data/lib/rex/post/meterpreter/client_core.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/android/android.rb +86 -1
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +29 -0
- data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +75 -89
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +10 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +7 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +10 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +1 -1
- data/lib/rex/post/meterpreter/packet.rb +38 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +101 -108
- data/lib/rex/post/meterpreter/packet_parser.rb +14 -6
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +42 -21
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +54 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +39 -13
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +8 -0
- data/lib/rex/proto/adb.rb +7 -0
- data/lib/rex/proto/adb/client.rb +39 -0
- data/lib/rex/proto/adb/message.rb +164 -0
- data/lib/rex/proto/dcerpc/svcctl/packet.rb +9 -9
- data/lib/rex/proto/http/client_request.rb +2 -1
- data/lib/rex/proto/http/response.rb +1 -1
- data/lib/rex/proto/kademlia/bootstrap_response.rb +2 -2
- data/lib/rex/proto/ntp/modes.rb +17 -0
- data/lib/rex/text.rb +12 -0
- data/lib/rex/zip/blocks.rb +1 -1
- data/lib/rex/zip/entry.rb +1 -1
- data/rex.gemspec +28 -1
- metadata +106 -3
@@ -59,7 +59,7 @@ module Parser
|
|
59
59
|
unless in_tag("JobOrder")
|
60
60
|
case name
|
61
61
|
when "OS"
|
62
|
-
unless @host.nil? or @text.
|
62
|
+
unless @host.nil? or @text.to_s.empty?
|
63
63
|
tnote = {
|
64
64
|
:type => "host.os.fusionvm_fingerprint",
|
65
65
|
:data => { :os => @text.strip },
|
@@ -86,7 +86,7 @@ module Parser
|
|
86
86
|
when "CVE"
|
87
87
|
@vuln[:refs] << "CVE-#{@text.strip}"
|
88
88
|
when "References"
|
89
|
-
unless @text.
|
89
|
+
unless @text.to_s.empty?
|
90
90
|
@text.split(' ').each do |ref|
|
91
91
|
next unless ref.start_with? "http"
|
92
92
|
if ref =~ /MS\d{2}-\d{3}/
|
data/lib/rex/parser/ini.rb
CHANGED
@@ -49,14 +49,7 @@ class Ini < Hash
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
# Enumerates the groups hash keys.
|
54
|
-
#
|
55
|
-
def each_group(&block)
|
56
|
-
self.keys.each { |k|
|
57
|
-
yield
|
58
|
-
}
|
59
|
-
end
|
52
|
+
alias each_group each_key
|
60
53
|
|
61
54
|
#
|
62
55
|
# Adds a group of the supplied name if it doesn't already exist.
|
@@ -200,6 +200,11 @@ module Parser
|
|
200
200
|
return attr_pairs
|
201
201
|
end
|
202
202
|
|
203
|
+
# Removes HTML from a string
|
204
|
+
def strip_html_tags(text)
|
205
|
+
return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "}
|
206
|
+
end
|
207
|
+
|
203
208
|
# This breaks xml-encoded characters, so need to append.
|
204
209
|
# It's on the end_element tag name to turn the appending
|
205
210
|
# off and clear out the data.
|
@@ -120,6 +120,20 @@ private
|
|
120
120
|
extension_data = [ ext.length, ext ].pack('VA*')
|
121
121
|
end
|
122
122
|
|
123
|
+
def extension_init_block(name, value)
|
124
|
+
# for now, we're going to blindly assume that the value is a path to a file
|
125
|
+
# which contains the data that gets passed to the extension
|
126
|
+
content = ::File.read(value)
|
127
|
+
data = [
|
128
|
+
name,
|
129
|
+
"\x00",
|
130
|
+
content.length,
|
131
|
+
content
|
132
|
+
]
|
133
|
+
|
134
|
+
data.pack('A*A*VA*')
|
135
|
+
end
|
136
|
+
|
123
137
|
def config_block
|
124
138
|
# start with the session information
|
125
139
|
config = session_block(@opts)
|
@@ -142,12 +156,17 @@ private
|
|
142
156
|
end
|
143
157
|
|
144
158
|
# terminate the extensions with a 0 size
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
159
|
+
config << [0].pack('V')
|
160
|
+
|
161
|
+
# wire in the extension init data
|
162
|
+
(@opts[:ext_init] || '').split(':').each do |cfg|
|
163
|
+
name, value = cfg.split(',')
|
164
|
+
config << extension_init_block(name, value)
|
149
165
|
end
|
150
166
|
|
167
|
+
# terminate the ext init config with a final null byte
|
168
|
+
config << "\x00"
|
169
|
+
|
151
170
|
# and we're done
|
152
171
|
config
|
153
172
|
end
|
@@ -141,7 +141,9 @@ class Channel
|
|
141
141
|
if (cid and client)
|
142
142
|
client.add_channel(self)
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
|
+
# Ensure the remote object is closed when all references are removed
|
146
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, cid))
|
145
147
|
end
|
146
148
|
|
147
149
|
def self.finalize(client,cid)
|
@@ -288,8 +290,11 @@ class Channel
|
|
288
290
|
end
|
289
291
|
|
290
292
|
def _close(addends = nil)
|
291
|
-
|
292
|
-
|
293
|
+
unless self.cid.nil?
|
294
|
+
ObjectSpace.undefine_finalizer(self)
|
295
|
+
self.class._close(self.client, self.cid, addends)
|
296
|
+
self.cid = nil
|
297
|
+
end
|
293
298
|
end
|
294
299
|
#
|
295
300
|
# Enables or disables interactive mode.
|
@@ -469,7 +469,7 @@ class ClientCore < Extension
|
|
469
469
|
end
|
470
470
|
|
471
471
|
if client.platform =~ /linux/
|
472
|
-
if writable_dir.
|
472
|
+
if writable_dir.to_s.empty?
|
473
473
|
writable_dir = tmp_folder
|
474
474
|
end
|
475
475
|
|
@@ -752,7 +752,7 @@ class ClientCore < Extension
|
|
752
752
|
def tmp_folder
|
753
753
|
tmp = client.sys.config.getenv('TMPDIR')
|
754
754
|
|
755
|
-
if tmp.
|
755
|
+
if tmp.to_s.empty?
|
756
756
|
tmp = '/tmp'
|
757
757
|
end
|
758
758
|
|
@@ -20,6 +20,8 @@ module Android
|
|
20
20
|
class Android < Extension
|
21
21
|
|
22
22
|
COLLECT_TYPE_WIFI = 1
|
23
|
+
COLLECT_TYPE_GEO = 2
|
24
|
+
COLLECT_TYPE_CELL = 3
|
23
25
|
|
24
26
|
COLLECT_ACTION_START = 1
|
25
27
|
COLLECT_ACTION_PAUSE = 2
|
@@ -28,7 +30,9 @@ class Android < Extension
|
|
28
30
|
COLLECT_ACTION_DUMP = 5
|
29
31
|
|
30
32
|
COLLECT_TYPES = {
|
31
|
-
'wifi' => COLLECT_TYPE_WIFI
|
33
|
+
'wifi' => COLLECT_TYPE_WIFI,
|
34
|
+
'geo' => COLLECT_TYPE_GEO,
|
35
|
+
'cell' => COLLECT_TYPE_CELL,
|
32
36
|
}
|
33
37
|
|
34
38
|
COLLECT_ACTIONS = {
|
@@ -68,6 +72,12 @@ class Android < Extension
|
|
68
72
|
response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
|
69
73
|
end
|
70
74
|
|
75
|
+
def set_audio_mode(n)
|
76
|
+
request = Packet.create_request('set_audio_mode')
|
77
|
+
request.add_tlv(TLV_TYPE_AUDIO_MODE, n)
|
78
|
+
response = client.send_request(request)
|
79
|
+
end
|
80
|
+
|
71
81
|
def interval_collect(opts)
|
72
82
|
request = Packet.create_request('interval_collect')
|
73
83
|
request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]])
|
@@ -107,6 +117,64 @@ class Android < Extension
|
|
107
117
|
records.each do |k, v|
|
108
118
|
result[:entries] << v
|
109
119
|
end
|
120
|
+
|
121
|
+
when COLLECT_TYPE_GEO
|
122
|
+
result[:headers] = ['Timestamp', 'Latitude', 'Longitude']
|
123
|
+
result[:entries] = []
|
124
|
+
records = {}
|
125
|
+
|
126
|
+
response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
|
127
|
+
timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
|
128
|
+
timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
129
|
+
|
130
|
+
g.each(TLV_TYPE_COLLECT_RESULT_GEO) do |w|
|
131
|
+
lat = w.get_tlv_value(TLV_TYPE_GEO_LAT)
|
132
|
+
lng = w.get_tlv_value(TLV_TYPE_GEO_LONG)
|
133
|
+
result[:entries] << [timestamp, lat, lng]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
when COLLECT_TYPE_CELL
|
138
|
+
result[:headers] = ['Timestamp', 'Cell Info']
|
139
|
+
result[:entries] = []
|
140
|
+
records = {}
|
141
|
+
|
142
|
+
response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
|
143
|
+
timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
|
144
|
+
timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
145
|
+
|
146
|
+
g.each(TLV_TYPE_COLLECT_RESULT_CELL) do |cell|
|
147
|
+
|
148
|
+
cell.each(TLV_TYPE_CELL_ACTIVE_GSM) do |info|
|
149
|
+
cid = info.get_tlv_value(TLV_TYPE_CELL_CID)
|
150
|
+
lac = info.get_tlv_value(TLV_TYPE_CELL_LAC)
|
151
|
+
psc = info.get_tlv_value(TLV_TYPE_CELL_PSC)
|
152
|
+
info = sprintf("cid=%d lac=%d psc=%d", cid, lac, psc)
|
153
|
+
result[:entries] << [timestamp, "GSM: #{info}"]
|
154
|
+
end
|
155
|
+
|
156
|
+
cell.each(TLV_TYPE_CELL_ACTIVE_CDMA) do |info|
|
157
|
+
bid = info.get_tlv_value(TLV_TYPE_CELL_BASE_ID)
|
158
|
+
lat = info.get_tlv_value(TLV_TYPE_CELL_BASE_LAT)
|
159
|
+
lng = info.get_tlv_value(TLV_TYPE_CELL_BASE_LONG)
|
160
|
+
net = info.get_tlv_value(TLV_TYPE_CELL_NET_ID)
|
161
|
+
sys = info.get_tlv_value(TLV_TYPE_CELL_SYSTEM_ID)
|
162
|
+
info = sprintf("base_id=%d lat=%d lng=%d net_id=%d sys_id=%d", bid, lat, lng, net, sys)
|
163
|
+
result[:entries] << [timestamp, "CDMA: #{info}"]
|
164
|
+
end
|
165
|
+
|
166
|
+
cell.each(TLV_TYPE_CELL_NEIGHBOR) do |w|
|
167
|
+
net = w.get_tlv_value(TLV_TYPE_CELL_NET_TYPE)
|
168
|
+
cid = w.get_tlv_value(TLV_TYPE_CELL_CID)
|
169
|
+
lac = w.get_tlv_value(TLV_TYPE_CELL_LAC)
|
170
|
+
psc = w.get_tlv_value(TLV_TYPE_CELL_PSC)
|
171
|
+
sig = w.get_tlv_value(TLV_TYPE_CELL_RSSI) * -1
|
172
|
+
inf = sprintf("network_type=%d cid=%d lac=%d psc=%d rssi=%d", net, cid, lac, psc, sig)
|
173
|
+
result[:entries] << [timestamp, inf]
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
110
178
|
end
|
111
179
|
|
112
180
|
result
|
@@ -180,6 +248,23 @@ class Android < Extension
|
|
180
248
|
response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value
|
181
249
|
end
|
182
250
|
|
251
|
+
def activity_start(uri)
|
252
|
+
request = Packet.create_request('activity_start')
|
253
|
+
request.add_tlv(TLV_TYPE_URI_STRING, uri)
|
254
|
+
response = client.send_request(request)
|
255
|
+
if response.get_tlv(TLV_TYPE_ACTIVITY_START_RESULT).value
|
256
|
+
return nil
|
257
|
+
else
|
258
|
+
return response.get_tlv(TLV_TYPE_ACTIVITY_START_ERROR).value
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def set_wallpaper(data)
|
263
|
+
request = Packet.create_request('set_wallpaper')
|
264
|
+
request.add_tlv(TLV_TYPE_WALLPAPER_DATA, data)
|
265
|
+
response = client.send_request(request)
|
266
|
+
end
|
267
|
+
|
183
268
|
def send_sms(dest, body, dr)
|
184
269
|
request = Packet.create_request('send_sms')
|
185
270
|
request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest)
|
@@ -54,6 +54,35 @@ TLV_TYPE_COLLECT_RESULT_WIFI_BSSID = TLV_TYPE_WLAN_BSSID
|
|
54
54
|
TLV_TYPE_COLLECT_RESULT_WIFI_SSID = TLV_TYPE_WLAN_SSID
|
55
55
|
TLV_TYPE_COLLECT_RESULT_WIFI_LEVEL = TLV_TYPE_WLAN_LEVEL
|
56
56
|
|
57
|
+
|
58
|
+
TLV_TYPE_COLLECT_RESULT_GEO = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9030)
|
59
|
+
|
60
|
+
TLV_TYPE_COLLECT_RESULT_CELL = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9060)
|
61
|
+
|
62
|
+
TLV_TYPE_CELL_ACTIVE_GSM = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9061)
|
63
|
+
TLV_TYPE_CELL_ACTIVE_CDMA = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9062)
|
64
|
+
TLV_TYPE_CELL_NEIGHBOR = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9063)
|
65
|
+
|
66
|
+
TLV_TYPE_CELL_NET_TYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9065)
|
67
|
+
TLV_TYPE_CELL_CID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9066)
|
68
|
+
TLV_TYPE_CELL_LAC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9067)
|
69
|
+
TLV_TYPE_CELL_PSC = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9068)
|
70
|
+
TLV_TYPE_CELL_RSSI = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9069)
|
71
|
+
|
72
|
+
|
73
|
+
TLV_TYPE_CELL_BASE_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9070)
|
74
|
+
TLV_TYPE_CELL_BASE_LAT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9071)
|
75
|
+
TLV_TYPE_CELL_BASE_LONG = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9072)
|
76
|
+
TLV_TYPE_CELL_NET_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9073)
|
77
|
+
TLV_TYPE_CELL_SYSTEM_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9074)
|
78
|
+
TLV_TYPE_AUDIO_MODE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9075)
|
79
|
+
|
80
|
+
TLV_TYPE_URI_STRING = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9101)
|
81
|
+
TLV_TYPE_ACTIVITY_START_RESULT = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9102)
|
82
|
+
TLV_TYPE_ACTIVITY_START_ERROR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9103)
|
83
|
+
|
84
|
+
TLV_TYPE_WALLPAPER_DATA = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 9201)
|
85
|
+
|
57
86
|
end
|
58
87
|
end
|
59
88
|
end
|
@@ -31,7 +31,7 @@ class Wmi
|
|
31
31
|
def query(query, root = nil)
|
32
32
|
request = Packet.create_request('extapi_wmi_query')
|
33
33
|
|
34
|
-
request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.
|
34
|
+
request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.to_s.empty?
|
35
35
|
request.add_tlv(TLV_TYPE_EXT_WMI_QUERY, query)
|
36
36
|
|
37
37
|
response = client.send_request(request)
|
@@ -24,73 +24,59 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
24
24
|
#
|
25
25
|
@@server_channels = {}
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
def request_handler( client, packet )
|
38
|
-
|
39
|
-
if( packet.method == "tcp_channel_open" )
|
40
|
-
|
41
|
-
cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
|
42
|
-
pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
|
43
|
-
localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
|
44
|
-
localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
|
45
|
-
peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
|
46
|
-
peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
|
47
|
-
|
48
|
-
if( cid == nil or pid == nil )
|
49
|
-
return false
|
50
|
-
end
|
51
|
-
|
52
|
-
server_channel = client.find_channel( pid )
|
53
|
-
if( server_channel == nil )
|
54
|
-
return false
|
55
|
-
end
|
56
|
-
|
57
|
-
params = Rex::Socket::Parameters.from_hash(
|
58
|
-
{
|
59
|
-
'Proto' => 'tcp',
|
60
|
-
'LocalHost' => localhost,
|
61
|
-
'LocalPort' => localport,
|
62
|
-
'PeerHost' => peerhost,
|
63
|
-
'PeerPort' => peerport,
|
64
|
-
'Comm' => server_channel.client
|
65
|
-
}
|
66
|
-
)
|
67
|
-
|
68
|
-
client_channel = TcpClientChannel.new( client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS )
|
69
|
-
|
70
|
-
client_channel.params = params
|
71
|
-
|
72
|
-
if( @@server_channels[server_channel] == nil )
|
73
|
-
@@server_channels[server_channel] = []
|
74
|
-
end
|
75
|
-
|
76
|
-
@@server_channels[server_channel] << client_channel
|
77
|
-
|
78
|
-
return true
|
79
|
-
end
|
80
|
-
|
81
|
-
return false
|
82
|
-
end
|
27
|
+
#
|
28
|
+
# This is the request handler which is registered to the respective meterpreter instance via
|
29
|
+
# Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket. All incoming requests from the meterpreter
|
30
|
+
# for a 'tcp_channel_open' will be processed here. We create a new TcpClientChannel for each request
|
31
|
+
# received and store it in the respective tcp server channels list of new pending client channels.
|
32
|
+
# These new tcp client channels are passed off via a call the the tcp server channels accept() method.
|
33
|
+
#
|
34
|
+
def self.request_handler(client, packet)
|
35
|
+
return false unless packet.method == "tcp_channel_open"
|
83
36
|
|
84
|
-
|
85
|
-
|
86
|
-
|
37
|
+
cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
|
38
|
+
pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
|
39
|
+
localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
|
40
|
+
localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
|
41
|
+
peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
|
42
|
+
peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
|
43
|
+
|
44
|
+
return false if cid.nil? || pid.nil?
|
45
|
+
|
46
|
+
server_channel = client.find_channel(pid)
|
47
|
+
|
48
|
+
return false if server_channel.nil?
|
87
49
|
|
50
|
+
params = Rex::Socket::Parameters.from_hash(
|
51
|
+
{
|
52
|
+
'Proto' => 'tcp',
|
53
|
+
'LocalHost' => localhost,
|
54
|
+
'LocalPort' => localport,
|
55
|
+
'PeerHost' => peerhost,
|
56
|
+
'PeerPort' => peerport,
|
57
|
+
'Comm' => server_channel.client
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS)
|
62
|
+
|
63
|
+
client_channel.params = params
|
64
|
+
|
65
|
+
@@server_channels[server_channel] ||= ::Queue.new
|
66
|
+
@@server_channels[server_channel].enq(client_channel)
|
67
|
+
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.cls
|
72
|
+
CHANNEL_CLASS_STREAM
|
88
73
|
end
|
89
74
|
|
90
75
|
#
|
91
76
|
# Open a new tcp server channel on the remote end.
|
92
77
|
#
|
93
|
-
|
78
|
+
# @return [Channel]
|
79
|
+
def self.open(client, params)
|
94
80
|
c = Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
|
95
81
|
[
|
96
82
|
{
|
@@ -112,7 +98,7 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
112
98
|
def initialize(client, cid, type, flags)
|
113
99
|
super(client, cid, type, flags)
|
114
100
|
# add this instance to the class variables dictionary of tcp server channels
|
115
|
-
@@server_channels[self]
|
101
|
+
@@server_channels[self] ||= ::Queue.new
|
116
102
|
end
|
117
103
|
|
118
104
|
#
|
@@ -120,46 +106,46 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
|
120
106
|
# and returns nil if no new client connection is available.
|
121
107
|
#
|
122
108
|
def accept_nonblock
|
123
|
-
|
124
|
-
if( @@server_channels[self].length > 0 )
|
125
|
-
channel = @@server_channels[self].shift
|
126
|
-
result = channel.lsock
|
127
|
-
end
|
128
|
-
return result
|
109
|
+
_accept(true)
|
129
110
|
end
|
130
111
|
|
131
112
|
#
|
132
113
|
# Accept a new tcp client connection form this tcp server channel. This method will block indefinatly
|
133
114
|
# if no timeout is specified.
|
134
115
|
#
|
135
|
-
def accept(
|
136
|
-
timeout = opts['Timeout']
|
137
|
-
if( timeout
|
138
|
-
|
139
|
-
else
|
140
|
-
begin
|
141
|
-
::Timeout.timeout( timeout ) {
|
142
|
-
result = _accept
|
143
|
-
}
|
144
|
-
rescue Timeout::Error
|
145
|
-
result = nil
|
146
|
-
end
|
116
|
+
def accept(opts = {})
|
117
|
+
timeout = opts['Timeout']
|
118
|
+
if (timeout.nil? || timeout <= 0)
|
119
|
+
timeout = 0
|
147
120
|
end
|
148
|
-
|
121
|
+
|
122
|
+
result = nil
|
123
|
+
begin
|
124
|
+
::Timeout.timeout(timeout) {
|
125
|
+
result = _accept
|
126
|
+
}
|
127
|
+
rescue Timeout::Error
|
128
|
+
end
|
129
|
+
|
130
|
+
result
|
149
131
|
end
|
150
132
|
|
151
133
|
protected
|
152
134
|
|
153
|
-
def _accept
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
result =
|
160
|
-
break if result != nil
|
135
|
+
def _accept(nonblock = false)
|
136
|
+
result = nil
|
137
|
+
|
138
|
+
channel = @@server_channels[self].deq(nonblock)
|
139
|
+
|
140
|
+
if channel
|
141
|
+
result = channel.lsock
|
161
142
|
end
|
162
|
-
|
143
|
+
|
144
|
+
if result != nil && !result.kind_of?(Rex::Socket::Tcp)
|
145
|
+
result.extend(Rex::Socket::Tcp)
|
146
|
+
end
|
147
|
+
|
148
|
+
result
|
163
149
|
end
|
164
150
|
|
165
151
|
end
|