Skip to content

Commit e8a92eb

Browse files
committed
Keep better track of resources
[See rapid7#1623] [SeeRM rapid7#7692]
1 parent 469d7b9 commit e8a92eb

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

lib/msf/core/exploit/http/server.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def initialize(info = {})
3636
], Exploit::Remote::HttpServer
3737
)
3838

39+
@my_resources = []
3940
@service_path = nil
4041
end
4142

@@ -202,6 +203,16 @@ def start_service(opts = {})
202203
add_resource(uopts)
203204
end
204205

206+
# Take care of removing any resources that we created
207+
def cleanup
208+
@my_resources.delete_if do |resource|
209+
remove_resource(resource)
210+
true
211+
end
212+
213+
super
214+
end
215+
205216
#
206217
# Return a Hash containing a best guess at the actual browser and operating
207218
# system versions, based on the User-Agent header.
@@ -358,9 +369,15 @@ def report_user_agent(address, request, client_opts={})
358369
# NOTE: Calling #add_resource will change the results of subsequent calls
359370
# to #get_resource!
360371
#
372+
# @return (see Rex::Service#add_resource)
361373
def add_resource(opts)
362374
@service_path = opts['Path']
363-
service.add_resource(opts['Path'], opts)
375+
res = service.add_resource(opts['Path'], opts)
376+
377+
# This has to go *after* the call to add_resource in case it raises
378+
@my_resources.push(opts['Path'])
379+
380+
res
364381
end
365382

366383
#
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
# -*- coding:binary -*-
3+
require 'spec_helper'
4+
5+
require 'msf/core'
6+
require 'msf/core/exploit/http/server'
7+
8+
describe Msf::Exploit::Remote::HttpServer do
9+
subject(:server_module) do
10+
mod = Msf::Exploit.allocate
11+
mod.extend described_class
12+
mod.send(:initialize, {})
13+
14+
mod
15+
end
16+
17+
let(:mock_service) do
18+
mock_service = mock("service")
19+
mock_service.stub(:server_name=)
20+
mock_service.stub(:add_resource)
21+
22+
mock_service
23+
end
24+
25+
before do
26+
Rex::ServiceManager.stub(:start => mock_service)
27+
end
28+
29+
describe "#add_resource" do
30+
it "should call the ServiceManager's add_resource" do
31+
server_module.start_service
32+
33+
mock_service.should_receive(:add_resource)
34+
server_module.add_resource('Path' => 'foo')
35+
end
36+
37+
it "should re-raise if the resource has already been added" do
38+
server_module.start_service
39+
40+
mock_service.should_receive(:add_resource).ordered
41+
mock_service.should_receive(:add_resource).ordered.and_raise(RuntimeError)
42+
43+
server_module.add_resource('Path' => 'foo')
44+
45+
expect { server_module.add_resource('Path' => 'foo') }.to raise_error
46+
end
47+
48+
end
49+
50+
describe "#cleanup" do
51+
it "should not remove resources if none were successfully added" do
52+
server_module.should_not_receive(:remove_resource)
53+
server_module.cleanup
54+
end
55+
56+
it "should remove successfully-added resources" do
57+
# setup
58+
server_module.start_service
59+
resources = [ 'a', 'b', 'c' ]
60+
resources.each { |r| server_module.add_resource('Path' => r) }
61+
62+
# The service will add one resource as part of #start_service, so
63+
# add that to the number that we added manually
64+
server_module.should_receive(:remove_resource).exactly(resources.count + 1).times
65+
server_module.cleanup
66+
end
67+
68+
end
69+
70+
end
71+
72+

0 commit comments

Comments
 (0)