Skip to content

Commit 9a35c32

Browse files
committed
Land rapid7#9352, Pull out HTTP-specific code from PacketDispatcher
2 parents d1569f8 + f1a1e1a commit 9a35c32

File tree

3 files changed

+73
-53
lines changed

3 files changed

+73
-53
lines changed

lib/msf/core/handler/reverse_http.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ def on_request(cli, req)
384384

385385
create_session(cli, {
386386
:passive_dispatcher => self.service,
387+
:dispatch_ext => [Rex::Post::Meterpreter::HttpPacketDispatcher],
387388
:conn_id => conn_id,
388389
:url => url,
389390
:expiration => datastore['SessionExpirationTimeout'].to_i,

lib/rex/post/meterpreter/client.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ def init_meterpreter(sock,opts={})
165165
end
166166
end
167167

168+
# Protocol specific dispatch mixins go here, this may be neader with explicit Client classes
169+
opts[:dispatch_ext].each {|dx| self.extend(dx)} if opts[:dispatch_ext]
168170
initialize_passive_dispatcher if opts[:passive_dispatcher]
169171

170172
register_extension_alias('core', ClientCore.new(self))

lib/rex/post/meterpreter/packet_dispatcher.rb

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -80,71 +80,23 @@ def initialize_passive_dispatcher
8080
self.recv_queue = []
8181
self.waiters = []
8282
self.alive = true
83-
84-
# Ensure that there is only one leading and trailing slash on the URI
85-
resource_uri = "/" + self.conn_id.to_s.gsub(/(^\/|\/$)/, '') + "/"
86-
87-
self.passive_service = self.passive_dispatcher
88-
self.passive_service.remove_resource(resource_uri)
89-
self.passive_service.add_resource(resource_uri,
90-
'Proc' => Proc.new { |cli, req| on_passive_request(cli, req) },
91-
'VirtualDirectory' => true
92-
)
9383
end
9484

9585
def shutdown_passive_dispatcher
96-
return if not self.passive_service
97-
98-
# Ensure that there is only one leading and trailing slash on the URI
99-
resource_uri = "/" + self.conn_id.to_s.gsub(/(^\/|\/$)/, '') + "/"
100-
101-
self.passive_service.remove_resource(resource_uri)
102-
103-
# If there are no more resources registered on the service, stop it entirely
104-
if self.passive_service.resources.empty?
105-
Rex::ServiceManager.stop_service(self.passive_service)
106-
end
107-
10886
self.alive = false
10987
self.send_queue = []
11088
self.recv_queue = []
11189
self.waiters = []
112-
113-
self.passive_service = nil
11490
end
11591

11692
def on_passive_request(cli, req)
117-
11893
begin
119-
120-
resp = Rex::Proto::Http::Response.new(200, "OK")
121-
resp['Content-Type'] = 'application/octet-stream'
122-
resp['Connection'] = 'close'
123-
124-
self.last_checkin = Time.now
125-
126-
if req.method == 'GET'
127-
rpkt = send_queue.shift
128-
resp.body = rpkt || ''
129-
begin
130-
cli.send_response(resp)
131-
rescue ::Exception => e
132-
send_queue.unshift(rpkt) if rpkt
133-
elog("Exception sending a reply to the reader request: #{cli.inspect} #{e.class} #{e} #{e.backtrace}")
134-
end
135-
else
136-
resp.body = ""
137-
if req.body and req.body.length > 0
138-
packet = Packet.new(0)
139-
packet.add_raw(req.body)
140-
packet.parse_header!
141-
dispatch_inbound_packet(packet)
142-
end
94+
self.last_checkin = Time.now
95+
resp = send_queue.shift
14396
cli.send_response(resp)
144-
end
145-
146-
rescue ::Exception => e
147-
elog("Exception handling request: #{cli.inspect} #{req.inspect} #{e.class} #{e} #{e.backtrace}")
97+
rescue => e
98+
send_queue.unshift(resp) if resp
99+
elog("Exception sending a reply to the reader request: #{cli.inspect} #{e.class} #{e} #{e.backtrace}")
148100
end
149101
end
150102

@@ -625,5 +577,70 @@ def deregister_inbound_handler(handler)
625577
attr_accessor :waiters # :nodoc:
626578
end
627579

580+
module HttpPacketDispatcher
581+
def initialize_passive_dispatcher
582+
super
583+
584+
# Ensure that there is only one leading and trailing slash on the URI
585+
resource_uri = "/" + self.conn_id.to_s.gsub(/(^\/|\/$)/, '') + "/"
586+
self.passive_service = self.passive_dispatcher
587+
self.passive_service.remove_resource(resource_uri)
588+
self.passive_service.add_resource(resource_uri,
589+
'Proc' => Proc.new { |cli, req| on_passive_request(cli, req) },
590+
'VirtualDirectory' => true
591+
)
592+
end
593+
594+
def shutdown_passive_dispatcher
595+
if self.passive_service
596+
# Ensure that there is only one leading and trailing slash on the URI
597+
resource_uri = "/" + self.conn_id.to_s.gsub(/(^\/|\/$)/, '') + "/"
598+
self.passive_service.remove_resource(resource_uri) if self.passive_service
599+
600+
if self.passive_service.resources.empty?
601+
Rex::ServiceManager.stop_service(self.passive_service)
602+
end
603+
self.passive_service = nil
604+
end
605+
super
606+
end
607+
608+
def on_passive_request(cli, req)
609+
610+
begin
611+
612+
resp = Rex::Proto::Http::Response.new(200, "OK")
613+
resp['Content-Type'] = 'application/octet-stream'
614+
resp['Connection'] = 'close'
615+
616+
self.last_checkin = Time.now
617+
618+
if req.method == 'GET'
619+
rpkt = send_queue.shift
620+
resp.body = rpkt || ''
621+
begin
622+
cli.send_response(resp)
623+
rescue ::Exception => e
624+
send_queue.unshift(rpkt) if rpkt
625+
elog("Exception sending a reply to the reader request: #{cli.inspect} #{e.class} #{e} #{e.backtrace}")
626+
end
627+
else
628+
resp.body = ""
629+
if req.body and req.body.length > 0
630+
packet = Packet.new(0)
631+
packet.add_raw(req.body)
632+
packet.parse_header!
633+
dispatch_inbound_packet(packet)
634+
end
635+
cli.send_response(resp)
636+
end
637+
638+
rescue ::Exception => e
639+
elog("Exception handling request: #{cli.inspect} #{req.inspect} #{e.class} #{e} #{e.backtrace}")
640+
end
641+
end
642+
643+
end
644+
628645
end; end; end
629646

0 commit comments

Comments
 (0)