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
@@ -60,7 +60,9 @@ class EventLog
|
|
60
60
|
def initialize(hand)
|
61
61
|
self.client = self.class.client
|
62
62
|
self.handle = hand
|
63
|
-
|
63
|
+
|
64
|
+
# Ensure the remote object is closed when all references are removed
|
65
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, hand))
|
64
66
|
end
|
65
67
|
|
66
68
|
def self.finalize(client,handle)
|
@@ -185,7 +187,11 @@ class EventLog
|
|
185
187
|
|
186
188
|
# Instance method
|
187
189
|
def close
|
188
|
-
|
190
|
+
unless self.handle.nil?
|
191
|
+
ObjectSpace.undefine_finalizer(self)
|
192
|
+
self.class.close(self.client, self.handle)
|
193
|
+
self.handle = nil
|
194
|
+
end
|
189
195
|
end
|
190
196
|
end
|
191
197
|
|
@@ -285,11 +285,12 @@ class Process < Rex::Post::Process
|
|
285
285
|
'thread' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Thread.new(self),
|
286
286
|
})
|
287
287
|
|
288
|
-
|
288
|
+
# Ensure the remote object is closed when all references are removed
|
289
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, handle))
|
289
290
|
end
|
290
291
|
|
291
|
-
def self.finalize(client,handle)
|
292
|
-
proc { self.close(client,handle) }
|
292
|
+
def self.finalize(client, handle)
|
293
|
+
proc { self.close(client, handle) }
|
293
294
|
end
|
294
295
|
|
295
296
|
#
|
@@ -320,8 +321,12 @@ class Process < Rex::Post::Process
|
|
320
321
|
#
|
321
322
|
# Instance method
|
322
323
|
#
|
323
|
-
def close(handle=self.handle)
|
324
|
-
self.
|
324
|
+
def close(handle = self.handle)
|
325
|
+
unless self.pid.nil?
|
326
|
+
ObjectSpace.undefine_finalizer(self)
|
327
|
+
self.class.close(self.client, handle)
|
328
|
+
self.pid = nil
|
329
|
+
end
|
325
330
|
end
|
326
331
|
|
327
332
|
#
|
@@ -30,7 +30,8 @@ class RegistryKey
|
|
30
30
|
self.perm = perm
|
31
31
|
self.hkey = hkey
|
32
32
|
|
33
|
-
|
33
|
+
# Ensure the remote object is closed when all references are removed
|
34
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, hkey))
|
34
35
|
end
|
35
36
|
|
36
37
|
def self.finalize(client,hkey)
|
@@ -115,7 +116,11 @@ class RegistryKey
|
|
115
116
|
|
116
117
|
# Instance method for the same
|
117
118
|
def close()
|
118
|
-
|
119
|
+
unless self.hkey.nil?
|
120
|
+
ObjectSpace.undefine_finalizer(self)
|
121
|
+
self.class.close(self.client, self.hkey)
|
122
|
+
self.hkey = nil
|
123
|
+
end
|
119
124
|
end
|
120
125
|
|
121
126
|
##
|
data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb
CHANGED
@@ -29,11 +29,12 @@ class RemoteRegistryKey
|
|
29
29
|
self.target_host = target_host
|
30
30
|
self.hkey = hkey
|
31
31
|
|
32
|
-
|
32
|
+
# Ensure the remote object is closed when all references are removed
|
33
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(client, hkey))
|
33
34
|
end
|
34
35
|
|
35
|
-
def self.finalize(client,hkey)
|
36
|
-
proc { self.close(client,hkey) }
|
36
|
+
def self.finalize(client, hkey)
|
37
|
+
proc { self.close(client, hkey) }
|
37
38
|
end
|
38
39
|
|
39
40
|
##
|
@@ -113,8 +114,12 @@ class RemoteRegistryKey
|
|
113
114
|
end
|
114
115
|
|
115
116
|
# Instance method for the same
|
116
|
-
def close
|
117
|
-
|
117
|
+
def close
|
118
|
+
unless self.hkey.nil?
|
119
|
+
ObjectSpace.undefine_finalizer(self)
|
120
|
+
self.class.close(self.client, self.hkey)
|
121
|
+
self.hkey = nil
|
122
|
+
end
|
118
123
|
end
|
119
124
|
|
120
125
|
##
|
@@ -34,7 +34,9 @@ class Thread < Rex::Post::Thread
|
|
34
34
|
self.process = process
|
35
35
|
self.handle = handle
|
36
36
|
self.tid = tid
|
37
|
-
|
37
|
+
|
38
|
+
# Ensure the remote object is closed when all references are removed
|
39
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(process.client, handle))
|
38
40
|
end
|
39
41
|
|
40
42
|
def self.finalize(client,handle)
|
@@ -168,7 +170,11 @@ class Thread < Rex::Post::Thread
|
|
168
170
|
|
169
171
|
# Instance method
|
170
172
|
def close
|
171
|
-
|
173
|
+
unless self.handle.nil?
|
174
|
+
ObjectSpace.undefine_finalizer(self)
|
175
|
+
self.class.close(self.process.client, self.handle)
|
176
|
+
self.handle = nil
|
177
|
+
end
|
172
178
|
end
|
173
179
|
|
174
180
|
attr_reader :process, :handle, :tid # :nodoc:
|
@@ -665,6 +665,44 @@ class Packet < GroupTlv
|
|
665
665
|
end
|
666
666
|
end
|
667
667
|
|
668
|
+
#
|
669
|
+
# Override the function that creates the raw byte stream for
|
670
|
+
# sending so that it generates an XOR key, uses it to scramble
|
671
|
+
# the serialized TLV content, and then returns the key plus the
|
672
|
+
# scrambled data as the payload.
|
673
|
+
#
|
674
|
+
def to_r
|
675
|
+
raw = super
|
676
|
+
xor_key = rand(254) + 1
|
677
|
+
xor_key |= (rand(254) + 1) << 8
|
678
|
+
xor_key |= (rand(254) + 1) << 16
|
679
|
+
xor_key |= (rand(254) + 1) << 24
|
680
|
+
result = [xor_key].pack('N') + xor_bytes(xor_key, raw)
|
681
|
+
result
|
682
|
+
end
|
683
|
+
|
684
|
+
#
|
685
|
+
# Override the function that reads from a raw byte stream so
|
686
|
+
# that the XORing of data is included in the process prior to
|
687
|
+
# passing it on to the default functionality that can parse
|
688
|
+
# the TLV values.
|
689
|
+
#
|
690
|
+
def from_r(bytes)
|
691
|
+
xor_key = bytes[0,4].unpack('N')[0]
|
692
|
+
super(xor_bytes(xor_key, bytes[4, bytes.length]))
|
693
|
+
end
|
694
|
+
|
695
|
+
#
|
696
|
+
# Xor a set of bytes with a given DWORD xor key.
|
697
|
+
#
|
698
|
+
def xor_bytes(xor_key, bytes)
|
699
|
+
result = ''
|
700
|
+
bytes.bytes.zip([xor_key].pack('V').bytes.cycle).each do |b|
|
701
|
+
result << (b[0].ord ^ b[1].ord).chr
|
702
|
+
end
|
703
|
+
result
|
704
|
+
end
|
705
|
+
|
668
706
|
##
|
669
707
|
#
|
670
708
|
# Conditionals
|
@@ -42,23 +42,32 @@ end
|
|
42
42
|
###
|
43
43
|
module PacketDispatcher
|
44
44
|
|
45
|
-
|
45
|
+
# Defualt time, in seconds, to wait for a response after sending a packet
|
46
|
+
PACKET_TIMEOUT = 600
|
46
47
|
|
47
|
-
|
48
|
-
#
|
49
|
-
#
|
48
|
+
# Number of seconds to wait without getting any packets before we try to
|
49
|
+
# send a liveness check. A minute should be generous even on the highest
|
50
|
+
# latency networks
|
50
51
|
#
|
51
|
-
|
52
|
+
# @see #keepalive
|
53
|
+
PING_TIME = 60
|
54
|
+
|
55
|
+
# This mutex is used to lock out new commands during an
|
56
|
+
# active migration. Unused if this is a passive dispatcher
|
52
57
|
attr_accessor :comm_mutex
|
53
58
|
|
54
59
|
|
55
|
-
##
|
56
|
-
#
|
57
|
-
#
|
58
60
|
# Passive Dispatching
|
59
61
|
#
|
60
|
-
|
61
|
-
|
62
|
+
# @return [Rex::ServiceManager]
|
63
|
+
# @return [nil] if this is not a passive dispatcher
|
64
|
+
attr_accessor :passive_service
|
65
|
+
|
66
|
+
# @return [Array]
|
67
|
+
attr_accessor :send_queue
|
68
|
+
|
69
|
+
# @return [Array]
|
70
|
+
attr_accessor :recv_queue
|
62
71
|
|
63
72
|
def initialize_passive_dispatcher
|
64
73
|
self.send_queue = []
|
@@ -108,8 +117,7 @@ module PacketDispatcher
|
|
108
117
|
|
109
118
|
self.last_checkin = Time.now
|
110
119
|
|
111
|
-
|
112
|
-
if req.body[0,4] == "RECV"
|
120
|
+
if req.method == 'GET'
|
113
121
|
rpkt = send_queue.shift
|
114
122
|
resp.body = rpkt || ''
|
115
123
|
begin
|
@@ -159,9 +167,6 @@ module PacketDispatcher
|
|
159
167
|
|
160
168
|
if (raw)
|
161
169
|
|
162
|
-
# This mutex is used to lock out new commands during an
|
163
|
-
# active migration.
|
164
|
-
|
165
170
|
self.comm_mutex.synchronize do
|
166
171
|
begin
|
167
172
|
bytes = self.sock.write(raw)
|
@@ -170,13 +175,11 @@ module PacketDispatcher
|
|
170
175
|
end
|
171
176
|
end
|
172
177
|
|
178
|
+
|
173
179
|
if bytes.to_i == 0
|
174
180
|
# Mark the session itself as dead
|
175
181
|
self.alive = false
|
176
182
|
|
177
|
-
# Indicate that the dispatcher should shut down too
|
178
|
-
@finish = true
|
179
|
-
|
180
183
|
# Reraise the error to the top-level caller
|
181
184
|
raise err if err
|
182
185
|
end
|
@@ -188,15 +191,16 @@ module PacketDispatcher
|
|
188
191
|
#
|
189
192
|
# Sends a packet and waits for a timeout for the given time interval.
|
190
193
|
#
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
response = send_packet_wait_response(packet, t)
|
194
|
+
# @param packet [Packet] request to send
|
195
|
+
# @param timeout [Fixnum,nil] seconds to wait for response, or nil to ignore the
|
196
|
+
# response and return immediately
|
197
|
+
# @return (see #send_packet_wait_response)
|
198
|
+
def send_request(packet, timeout = self.response_timeout)
|
199
|
+
response = send_packet_wait_response(packet, timeout)
|
198
200
|
|
199
|
-
if
|
201
|
+
if timeout.nil?
|
202
|
+
return nil
|
203
|
+
elsif response.nil?
|
200
204
|
raise TimeoutError.new("Send timed out")
|
201
205
|
elsif (response.result != 0)
|
202
206
|
einfo = lookup_error(response.result)
|
@@ -213,26 +217,58 @@ module PacketDispatcher
|
|
213
217
|
#
|
214
218
|
# Transmits a packet and waits for a response.
|
215
219
|
#
|
216
|
-
|
220
|
+
# @param packet [Packet] the request packet to send
|
221
|
+
# @param timeout [Fixnum,nil] number of seconds to wait, or nil to wait
|
222
|
+
# forever
|
223
|
+
def send_packet_wait_response(packet, timeout)
|
217
224
|
# First, add the waiter association for the supplied packet
|
218
225
|
waiter = add_response_waiter(packet)
|
219
226
|
|
227
|
+
bytes_written = send_packet(packet)
|
228
|
+
|
220
229
|
# Transmit the packet
|
221
|
-
if (
|
230
|
+
if (bytes_written.to_i <= 0)
|
222
231
|
# Remove the waiter if we failed to send the packet.
|
223
232
|
remove_response_waiter(waiter)
|
224
233
|
return nil
|
225
234
|
end
|
226
235
|
|
236
|
+
if not timeout
|
237
|
+
return nil
|
238
|
+
end
|
239
|
+
|
227
240
|
# Wait for the supplied time interval
|
228
|
-
waiter.wait(
|
241
|
+
response = waiter.wait(timeout)
|
229
242
|
|
230
243
|
# Remove the waiter from the list of waiters in case it wasn't
|
231
|
-
# removed
|
244
|
+
# removed. This happens if the waiter timed out above.
|
232
245
|
remove_response_waiter(waiter)
|
233
246
|
|
234
247
|
# Return the response packet, if any
|
235
|
-
return
|
248
|
+
return response
|
249
|
+
end
|
250
|
+
|
251
|
+
# Send a ping to the server.
|
252
|
+
#
|
253
|
+
# Our 'ping' is a check for eof on channel id 0. This method has no side
|
254
|
+
# effects and always returns an answer (regardless of the existence of chan
|
255
|
+
# 0), which is all that's needed for a liveness check. The answer itself is
|
256
|
+
# unimportant and is ignored.
|
257
|
+
#
|
258
|
+
# @return [void]
|
259
|
+
def keepalive
|
260
|
+
if @ping_sent
|
261
|
+
if Time.now.to_i - last_checkin.to_i > PING_TIME*2
|
262
|
+
dlog("No response to ping, session #{self.sid} is dead", LEV_3)
|
263
|
+
self.alive = false
|
264
|
+
end
|
265
|
+
else
|
266
|
+
pkt = Packet.create_request('core_channel_eof')
|
267
|
+
pkt.add_tlv(TLV_TYPE_CHANNEL_ID, 0)
|
268
|
+
add_response_waiter(pkt, Proc.new { @ping_sent = false })
|
269
|
+
send_packet(pkt)
|
270
|
+
@ping_sent = true
|
271
|
+
end
|
236
272
|
end
|
237
273
|
|
238
274
|
##
|
@@ -253,59 +289,23 @@ module PacketDispatcher
|
|
253
289
|
|
254
290
|
self.waiters = []
|
255
291
|
|
256
|
-
@pqueue =
|
257
|
-
@finish = false
|
258
|
-
@last_recvd = Time.now
|
292
|
+
@pqueue = ::Queue.new
|
259
293
|
@ping_sent = false
|
260
294
|
|
261
|
-
self.alive = true
|
262
|
-
|
263
295
|
# Spawn a thread for receiving packets
|
264
296
|
self.receiver_thread = Rex::ThreadFactory.spawn("MeterpreterReceiver", false) do
|
265
297
|
while (self.alive)
|
266
298
|
begin
|
267
|
-
rv = Rex::ThreadSafe.select([ self.sock.fd ], nil, nil,
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
# If the queue is empty and we've already sent a
|
274
|
-
# keepalive without getting a reply, then this
|
275
|
-
# session is hosed, and we should give up on it.
|
276
|
-
if @ping_sent and @pqueue.empty? and (Time.now - @last_recvd > ping_time * 2)
|
277
|
-
dlog("No response to ping, session #{self.sid} is dead", LEV_3)
|
278
|
-
self.alive = false
|
279
|
-
@finish = true
|
280
|
-
break
|
281
|
-
end
|
282
|
-
# Let the packet queue processor finish up before
|
283
|
-
# we send a ping.
|
284
|
-
if not @ping_sent and @pqueue.empty?
|
285
|
-
# Our 'ping' is actually just a check for eof on
|
286
|
-
# channel id 0. This method has no side effects
|
287
|
-
# and always returns an answer (regardless of the
|
288
|
-
# existence of chan 0), which is all that's
|
289
|
-
# needed for a liveness check. The answer itself
|
290
|
-
# is unimportant and is ignored.
|
291
|
-
pkt = Packet.create_request('core_channel_eof')
|
292
|
-
pkt.add_tlv(TLV_TYPE_CHANNEL_ID, 0)
|
293
|
-
waiter = Proc.new { |response, param|
|
294
|
-
@ping_sent = false
|
295
|
-
@last_recvd = Time.now
|
296
|
-
}
|
297
|
-
send_packet(pkt, waiter)
|
298
|
-
@ping_sent = true
|
299
|
-
end
|
300
|
-
next
|
299
|
+
rv = Rex::ThreadSafe.select([ self.sock.fd ], nil, nil, PING_TIME)
|
300
|
+
if rv
|
301
|
+
packet = receive_packet
|
302
|
+
@pqueue << packet if packet
|
303
|
+
elsif self.send_keepalives && @pqueue.empty?
|
304
|
+
keepalive
|
301
305
|
end
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
@last_recvd = Time.now
|
306
|
-
rescue ::Exception
|
307
|
-
dlog("Exception caught in monitor_socket: #{$!}", 'meterpreter', LEV_1)
|
308
|
-
@finish = true
|
306
|
+
rescue ::Exception => e
|
307
|
+
dlog("Exception caught in monitor_socket: #{e.class}: #{e}", 'meterpreter', LEV_1)
|
308
|
+
dlog("Call stack: #{e.backtrace.join("\n")}", 'meterpreter', LEV_2)
|
309
309
|
self.alive = false
|
310
310
|
break
|
311
311
|
end
|
@@ -315,19 +315,13 @@ module PacketDispatcher
|
|
315
315
|
# Spawn a new thread that monitors the socket
|
316
316
|
self.dispatcher_thread = Rex::ThreadFactory.spawn("MeterpreterDispatcher", false) do
|
317
317
|
begin
|
318
|
-
|
319
|
-
# thread above.
|
320
|
-
while(not @finish)
|
321
|
-
if(@pqueue.empty?)
|
322
|
-
::IO.select(nil, nil, nil, 0.10)
|
323
|
-
next
|
324
|
-
end
|
325
|
-
|
318
|
+
while (self.alive)
|
326
319
|
incomplete = []
|
327
320
|
backlog = []
|
328
321
|
|
322
|
+
backlog << @pqueue.pop
|
329
323
|
while(@pqueue.length > 0)
|
330
|
-
backlog << @pqueue.
|
324
|
+
backlog << @pqueue.pop
|
331
325
|
end
|
332
326
|
|
333
327
|
#
|
@@ -356,7 +350,6 @@ module PacketDispatcher
|
|
356
350
|
backlog.push(*tmp_channel)
|
357
351
|
backlog.push(*tmp_close)
|
358
352
|
|
359
|
-
|
360
353
|
#
|
361
354
|
# Process the message queue
|
362
355
|
#
|
@@ -367,12 +360,12 @@ module PacketDispatcher
|
|
367
360
|
if ! dispatch_inbound_packet(pkt)
|
368
361
|
# Keep Packets in the receive queue until a handler is registered
|
369
362
|
# for them. Packets will live in the receive queue for up to
|
370
|
-
#
|
363
|
+
# PACKET_TIMEOUT seconds, after which they will be dropped.
|
371
364
|
#
|
372
365
|
# A common reason why there would not immediately be a handler for
|
373
366
|
# a received Packet is in channels, where a connection may
|
374
367
|
# open and receive data before anything has asked to read.
|
375
|
-
if (::Time.now.to_i - pkt.created_at.to_i <
|
368
|
+
if (::Time.now.to_i - pkt.created_at.to_i < PACKET_TIMEOUT)
|
376
369
|
incomplete << pkt
|
377
370
|
end
|
378
371
|
end
|
@@ -393,11 +386,16 @@ module PacketDispatcher
|
|
393
386
|
::IO.select(nil, nil, nil, 0.10)
|
394
387
|
end
|
395
388
|
|
396
|
-
|
389
|
+
while incomplete.length > 0
|
390
|
+
@pqueue << incomplete.shift
|
391
|
+
end
|
397
392
|
|
398
393
|
if(@pqueue.length > 100)
|
399
|
-
|
400
|
-
|
394
|
+
removed = []
|
395
|
+
(1..25).each {
|
396
|
+
removed << @pqueue.pop
|
397
|
+
}
|
398
|
+
dlog("Backlog has grown to over 100 in monitor_socket, dropping older packets: #{removed.map{|x| x.inspect}.join(" - ")}", 'meterpreter', LEV_1)
|
401
399
|
end
|
402
400
|
end
|
403
401
|
rescue ::Exception => e
|
@@ -454,15 +452,16 @@ module PacketDispatcher
|
|
454
452
|
# if anyone.
|
455
453
|
#
|
456
454
|
def notify_response_waiter(response)
|
455
|
+
handled = false
|
457
456
|
self.waiters.each() { |waiter|
|
458
457
|
if (waiter.waiting_for?(response))
|
459
458
|
waiter.notify(response)
|
460
|
-
|
461
459
|
remove_response_waiter(waiter)
|
462
|
-
|
460
|
+
handled = true
|
463
461
|
break
|
464
462
|
end
|
465
463
|
}
|
464
|
+
return handled
|
466
465
|
end
|
467
466
|
|
468
467
|
#
|
@@ -491,21 +490,15 @@ module PacketDispatcher
|
|
491
490
|
# Otherwise, the packet is passed onto any registered dispatch
|
492
491
|
# handlers until one returns success.
|
493
492
|
#
|
494
|
-
def dispatch_inbound_packet(packet
|
493
|
+
def dispatch_inbound_packet(packet)
|
495
494
|
handled = false
|
496
495
|
|
497
|
-
# If no client context was provided, return self as PacketDispatcher
|
498
|
-
# is a mixin for the Client instance
|
499
|
-
if (client == nil)
|
500
|
-
client = self
|
501
|
-
end
|
502
|
-
|
503
496
|
# Update our last reply time
|
504
|
-
|
497
|
+
self.last_checkin = Time.now
|
505
498
|
|
506
499
|
# If the packet is a response, try to notify any potential
|
507
500
|
# waiters
|
508
|
-
if
|
501
|
+
if packet.response?
|
509
502
|
if (notify_response_waiter(packet))
|
510
503
|
return true
|
511
504
|
end
|
@@ -518,11 +511,11 @@ module PacketDispatcher
|
|
518
511
|
handled = nil
|
519
512
|
begin
|
520
513
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
514
|
+
if packet.response?
|
515
|
+
handled = handler.response_handler(self, packet)
|
516
|
+
else
|
517
|
+
handled = handler.request_handler(self, packet)
|
518
|
+
end
|
526
519
|
|
527
520
|
rescue ::Exception => e
|
528
521
|
dlog("Exception caught in dispatch_inbound_packet: handler=#{handler} #{e.class} #{e} #{e.backtrace}", 'meterpreter', LEV_1)
|