rex 2.0.9 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|