Skip to content

Commit 7f01048

Browse files
committed
Add some more LoginScanner tests
1 parent 21b441e commit 7f01048

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

lib/metasploit/framework/login_scanner.rb

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,7 @@ module LoginScanner
1919
# classes that will probably give useful results when run
2020
# against `service`.
2121
def self.classes_for_service(service)
22-
23-
unless @required
24-
# Make sure we've required all the scanner classes
25-
dir = File.expand_path("../login_scanner/", __FILE__)
26-
Dir.glob(File.join(dir, "*.rb")).each do |f|
27-
require f if File.file?(f)
28-
end
29-
@required = true
30-
end
22+
require_login_scanners
3123

3224
self.constants.map{|sym| const_get(sym)}.select do |const|
3325
next unless const.kind_of?(Class)
@@ -42,6 +34,34 @@ def self.classes_for_service(service)
4234
end
4335
end
4436

37+
def self.all_service_names
38+
require_login_scanners
39+
40+
service_names = Set.new
41+
self.constants.map{|sym| const_get(sym)}.select do |const|
42+
next unless const.kind_of?(Class)
43+
next unless const.const_defined?(:LIKELY_SERVICE_NAMES)
44+
45+
const.const_get(:LIKELY_SERVICE_NAMES).each do |service_name|
46+
service_names << service_name
47+
end
48+
end
49+
50+
service_names
51+
end
52+
53+
private
54+
55+
def self.require_login_scanners
56+
unless @required
57+
# Make sure we've required all the scanner classes
58+
dir = File.expand_path("../login_scanner/", __FILE__)
59+
Dir.glob(File.join(dir, "*.rb")).each do |f|
60+
require f if File.file?(f)
61+
end
62+
@required = true
63+
end
64+
end
4565
end
4666
end
4767
end

spec/lib/metasploit/framework/login_scanner_spec.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,57 @@
5353
end
5454
end
5555

56+
describe '.all_service_names' do
57+
let(:service_names) { described_class.all_service_names }
58+
59+
it 'returns a set of service names' do
60+
expect(service_names).to be_a Set
61+
end
62+
63+
it 'returns a populated set' do
64+
expect(service_names).to_not be_empty
65+
end
66+
67+
it 'includes common services names' do
68+
expect(service_names).to include 'http'
69+
expect(service_names).to include 'https'
70+
expect(service_names).to include 'smb'
71+
end
72+
end
73+
74+
describe '.classes_for_service' do
75+
described_class.all_service_names.each do |service_name|
76+
context "with service #{service_name}" do
77+
let(:name) { service_name }
78+
let(:login_scanners) { described_class.classes_for_service(service) }
79+
80+
it 'returns at least one class' do
81+
expect(login_scanners).to_not be_empty
82+
end
83+
84+
85+
MockService = Struct.new(:name, :port)
86+
87+
described_class.classes_for_service(MockService.new(name: service_name)).each do |login_scanner|
88+
context "when the login scanner is #{login_scanner.name}" do
89+
it 'is a LoginScanner' do
90+
expect(login_scanner).to include Metasploit::Framework::LoginScanner::Base
91+
end
92+
93+
it 'can be initialized with a single argument' do
94+
expect {
95+
# here we emulate how Pro will initialize the class by passing a single configuration hash argument
96+
login_scanner.new({
97+
bruteforce_speed: 5,
98+
host: '192.0.2.1',
99+
port: 1234,
100+
stop_on_success: true
101+
})
102+
}.to_not raise_error
103+
end
104+
end
105+
end
106+
end
107+
end
108+
end
56109
end

0 commit comments

Comments
 (0)