cms_scanner 0.0.13 → 0.0.14
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/app/controllers/core/cli_options.rb +2 -1
- data/app/models/version.rb +27 -1
- data/cms_scanner.gemspec +1 -1
- data/lib/cms_scanner/browser/options.rb +0 -9
- data/lib/cms_scanner/finders.rb +2 -0
- data/lib/cms_scanner/finders/same_type_finder.rb +17 -0
- data/lib/cms_scanner/finders/same_type_finders.rb +25 -0
- data/lib/cms_scanner/version.rb +1 -1
- data/lib/cms_scanner/vulnerability/references.rb +1 -1
- data/spec/app/models/version_spec.rb +28 -10
- data/spec/lib/finders/same_type_finder_spec.rb +24 -0
- data/spec/lib/finders/same_type_finders_spec.rb +81 -0
- data/spec/lib/vulnerability/references_spec.rb +12 -0
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b776de3125da0037eef520d8cf0f69caa17a9f22
|
|
4
|
+
data.tar.gz: 1f328394f7c5395b8b3191ee37e98627f0b90d0c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1b3aa71d953d878b8bbebdf70372ecaf7eb89352638008748d7b5cad16f4378c9ee26534042bf2c1ed32268c5f4b4e4a95ed1b88eab0186dfd0ef2bc4133d7b
|
|
7
|
+
data.tar.gz: 1cfa9bb846e83bdf8702295f62049c175d850a9e19eae1bdc73d8a882690b298ab127056866355792f37126bd0a4257756128c5e4878d46835096f77913dcc19
|
|
@@ -26,7 +26,8 @@ module CMSScanner
|
|
|
26
26
|
[
|
|
27
27
|
OptString.new(['--user-agent VALUE', '--ua']),
|
|
28
28
|
OptCredentials.new(['--http-auth login:password']),
|
|
29
|
-
OptPositiveInteger.new(['--max-threads VALUE', '-t', 'The max threads to use']
|
|
29
|
+
OptPositiveInteger.new(['--max-threads VALUE', '-t', 'The max threads to use'],
|
|
30
|
+
default: 5),
|
|
30
31
|
OptPositiveInteger.new(['--request-timeout SECONDS', 'The request timeout in seconds']),
|
|
31
32
|
OptPositiveInteger.new(['--connect-timeout SECONDS',
|
|
32
33
|
'The connection timeout in seconds'])
|
data/app/models/version.rb
CHANGED
|
@@ -7,11 +7,37 @@ module CMSScanner
|
|
|
7
7
|
|
|
8
8
|
def initialize(number, opts = {})
|
|
9
9
|
@number = number.to_s
|
|
10
|
+
@number = "0#{number}" if @number[0, 1] == '.'
|
|
11
|
+
|
|
10
12
|
parse_finding_options(opts)
|
|
11
13
|
end
|
|
12
14
|
|
|
15
|
+
# @param [ Version, String ] other
|
|
13
16
|
def ==(other)
|
|
14
|
-
|
|
17
|
+
(self <=> other) == 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param [ Version, String ] other
|
|
21
|
+
def <(other)
|
|
22
|
+
(self <=> other) == -1
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param [ Version, String ] other
|
|
26
|
+
def >(other)
|
|
27
|
+
(self <=> other) == 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param [ Version, String ] other
|
|
31
|
+
def <=>(other)
|
|
32
|
+
other = self.class.new(other) unless other.is_a?(self.class) # handle potential '.1' version
|
|
33
|
+
|
|
34
|
+
Gem::Version.new(number) <=> Gem::Version.new(other.number)
|
|
35
|
+
rescue
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_s
|
|
40
|
+
number
|
|
15
41
|
end
|
|
16
42
|
end
|
|
17
43
|
end
|
data/cms_scanner.gemspec
CHANGED
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
|
21
21
|
s.test_files = s.files.grep(/^(test|spec|features)\//)
|
|
22
22
|
s.require_path = 'lib'
|
|
23
23
|
|
|
24
|
-
s.add_dependency 'opt_parse_validator', '~> 0.0.
|
|
24
|
+
s.add_dependency 'opt_parse_validator', '~> 0.0.8'
|
|
25
25
|
s.add_dependency 'typhoeus', '~> 0.7'
|
|
26
26
|
s.add_dependency 'nokogiri', '~> 1.6'
|
|
27
27
|
s.add_dependency 'addressable', '~> 2.3'
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
module Typhoeus
|
|
2
|
-
# Hack to have a setter for the :max_concurrency
|
|
3
|
-
# Which will be officially added in the next version
|
|
4
|
-
# See: https://github.com/typhoeus/typhoeus/issues/366
|
|
5
|
-
class Hydra
|
|
6
|
-
attr_accessor :max_concurrency
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
1
|
module CMSScanner
|
|
11
2
|
# Options available in the Browser
|
|
12
3
|
class Browser
|
data/lib/cms_scanner/finders.rb
CHANGED
|
@@ -5,3 +5,5 @@ require 'cms_scanner/finders/independent_finders'
|
|
|
5
5
|
require 'cms_scanner/finders/independent_finder'
|
|
6
6
|
require 'cms_scanner/finders/unique_finders'
|
|
7
7
|
require 'cms_scanner/finders/unique_finder'
|
|
8
|
+
require 'cms_scanner/finders/same_type_finders'
|
|
9
|
+
require 'cms_scanner/finders/same_type_finder'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module CMSScanner
|
|
2
|
+
module Finders
|
|
3
|
+
# Same Type Finder
|
|
4
|
+
module SameTypeFinder
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.class_eval do
|
|
7
|
+
include IndependentFinder
|
|
8
|
+
|
|
9
|
+
# @return [ Array ]
|
|
10
|
+
def finders
|
|
11
|
+
@finders ||= NS::Finders::SameTypeFinders.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module CMSScanner
|
|
2
|
+
module Finders
|
|
3
|
+
# Same Type Finders container
|
|
4
|
+
#
|
|
5
|
+
# This class is designed to handle same type results, such as enumeration of plugins,
|
|
6
|
+
# themes etc.
|
|
7
|
+
class SameTypeFinders < IndependentFinders
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
# @option opts [ Symbol ] :mode :mixed, :passive or :aggressive
|
|
10
|
+
#
|
|
11
|
+
# @return [ Findings ]
|
|
12
|
+
def run(opts = {})
|
|
13
|
+
symbols_from_mode(opts[:mode]).each do |symbol|
|
|
14
|
+
each do |finder|
|
|
15
|
+
[*finder.send(symbol, opts)].compact.each do |found|
|
|
16
|
+
findings << found
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
findings
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/cms_scanner/version.rb
CHANGED
|
@@ -3,7 +3,7 @@ module CMSScanner
|
|
|
3
3
|
class Vulnerability
|
|
4
4
|
# @return [ Array<String> ] All the references URLs
|
|
5
5
|
def references_urls
|
|
6
|
-
cve_urls + secunia_urls + osvdb_urls + exploitdb_urls + msf_urls + packetstorm_urls
|
|
6
|
+
cve_urls + secunia_urls + osvdb_urls + exploitdb_urls + urls + msf_urls + packetstorm_urls
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
# @return [ Array<String> ] The CVEs
|
|
@@ -7,27 +7,45 @@ describe CMSScanner::Version do
|
|
|
7
7
|
let(:opts) { {} }
|
|
8
8
|
let(:number) { '1.0' }
|
|
9
9
|
|
|
10
|
+
its(:to_s) { should eql '1.0' }
|
|
11
|
+
|
|
10
12
|
describe '#number' do
|
|
11
13
|
its(:number) { should eql '1.0' }
|
|
12
14
|
|
|
13
15
|
context 'when float number supplied' do
|
|
14
16
|
let(:number) { 2.0 }
|
|
15
17
|
|
|
16
|
-
its(:number) { should
|
|
18
|
+
its(:number) { should eql '2.0' }
|
|
19
|
+
its(:to_s) { should eql '2.0' }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'when starting with a dot' do
|
|
23
|
+
let(:number) { '.2' }
|
|
24
|
+
|
|
25
|
+
its(:number) { should eql '0.2' }
|
|
17
26
|
end
|
|
18
27
|
end
|
|
19
28
|
|
|
20
|
-
describe '
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
describe '#<=>, #==, #>, #<' do
|
|
30
|
+
it 'returns true' do
|
|
31
|
+
expect(version == '1.0').to be true
|
|
32
|
+
expect(version == 1.0).to be true
|
|
33
|
+
expect(version == described_class.new('1.0')).to be true
|
|
34
|
+
expect(version > '0.9').to be true
|
|
35
|
+
expect(version < '2').to be true
|
|
36
|
+
|
|
37
|
+
expect(described_class.new('0.1') == '.1').to be true
|
|
38
|
+
expect(described_class.new('.1') == '0.1').to be true
|
|
25
39
|
end
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
it 'returns false' do
|
|
42
|
+
expect(version == '2.0').to be false
|
|
43
|
+
expect(version == described_class.new('2')).to be false
|
|
44
|
+
expect(version > '2.0').to be false
|
|
45
|
+
expect(version < '1.0').to be false
|
|
46
|
+
|
|
47
|
+
expect(version < 'gg').to be false
|
|
48
|
+
expect(version == '').to be false
|
|
31
49
|
end
|
|
32
50
|
end
|
|
33
51
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module CMSScanner
|
|
4
|
+
module Finders
|
|
5
|
+
# Dummy Class to test the module
|
|
6
|
+
class PluginsFinderSpec
|
|
7
|
+
include SameTypeFinder
|
|
8
|
+
|
|
9
|
+
def initialize(_target)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe CMSScanner::Finders::PluginsFinderSpec do
|
|
16
|
+
it_behaves_like CMSScanner::Finders::IndependentFinder do
|
|
17
|
+
let(:expected_finders) { [] }
|
|
18
|
+
let(:expected_finders_class) { CMSScanner::Finders::SameTypeFinders }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subject(:plugins) { described_class.new(target) }
|
|
22
|
+
let(:target) { CMSScanner::Target.new(url) }
|
|
23
|
+
let(:url) { 'http://example.com/' }
|
|
24
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'dummy_independent_finders' # will use those for convenience
|
|
3
|
+
|
|
4
|
+
describe CMSScanner::Finders::SameTypeFinders do
|
|
5
|
+
subject(:finders) { described_class.new }
|
|
6
|
+
let(:independent_finders) { CMSScanner::Finders::Independent }
|
|
7
|
+
|
|
8
|
+
describe '#run' do
|
|
9
|
+
let(:target) { 'target' }
|
|
10
|
+
let(:finding) { CMSScanner::DummyFinding }
|
|
11
|
+
let(:opts) { {} }
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
finders <<
|
|
15
|
+
independent_finders::DummyFinder.new(target) <<
|
|
16
|
+
independent_finders::NoAggressiveResult.new(target)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
after do
|
|
20
|
+
result = finders.run(opts)
|
|
21
|
+
|
|
22
|
+
expect(result).to be_a CMSScanner::Finders::Findings
|
|
23
|
+
expect(result).to eql @expected
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Used to be able to test the calls order and returned result at the same time
|
|
27
|
+
let(:dummy_passive) { independent_finders::DummyFinder.new(target).passive(opts) }
|
|
28
|
+
let(:dummy_aggresssive) { independent_finders::DummyFinder.new(target).aggressive(opts) }
|
|
29
|
+
let(:noaggressive) { independent_finders::NoAggressiveResult.new(target).passive(opts) }
|
|
30
|
+
|
|
31
|
+
context 'when :mixed mode' do
|
|
32
|
+
let(:opts) { super().merge(mode: :mixed) }
|
|
33
|
+
|
|
34
|
+
it 'calls all #passive then #aggressive on finders and returns the best result' do
|
|
35
|
+
expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
|
|
36
|
+
expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
|
|
37
|
+
expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
|
|
38
|
+
expect(finders[1]).to receive(:aggressive).ordered
|
|
39
|
+
|
|
40
|
+
@expected = []
|
|
41
|
+
|
|
42
|
+
@expected << finding.new('test', confidence: 100,
|
|
43
|
+
found_by: 'Dummy Finder (Passive Detection)')
|
|
44
|
+
|
|
45
|
+
@expected.first.confirmed_by << finding.new('test', confidence: 100, found_by: 'override')
|
|
46
|
+
|
|
47
|
+
@expected << finding.new('spotted', confidence: 10,
|
|
48
|
+
found_by: 'No Aggressive Result (Passive Detection)')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when :passive mode' do
|
|
53
|
+
let(:opts) { super().merge(mode: :passive) }
|
|
54
|
+
|
|
55
|
+
it 'calls #passive on all finders and returns the best result' do
|
|
56
|
+
expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
|
|
57
|
+
expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
|
|
58
|
+
|
|
59
|
+
finders.each { |f| expect(f).to_not receive(:aggressive) }
|
|
60
|
+
|
|
61
|
+
@expected = []
|
|
62
|
+
@expected << finding.new('test', found_by: 'Dummy Finder (Passive Detection)')
|
|
63
|
+
@expected << finding.new('spotted', confidence: 10,
|
|
64
|
+
found_by: 'No Aggressive Result (Passive Detection)')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when :aggressive mode' do
|
|
69
|
+
let(:opts) { super().merge(mode: :aggressive) }
|
|
70
|
+
|
|
71
|
+
it 'calls #aggressive on all finders and returns the best result' do
|
|
72
|
+
finders.each { |f| expect(f).to_not receive(:passive) }
|
|
73
|
+
|
|
74
|
+
expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
|
|
75
|
+
expect(finders[1]).to receive(:aggressive).ordered
|
|
76
|
+
|
|
77
|
+
@expected = [finding.new('test', confidence: 100, found_by: 'override')]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -54,6 +54,18 @@ describe CMSScanner::Vulnerability do
|
|
|
54
54
|
|
|
55
55
|
its(:packetstorm_ids) { should eq %w(15) }
|
|
56
56
|
its(:packetstorm_urls) { should eql %w(http://packetstormsecurity.com/files/15/) }
|
|
57
|
+
|
|
58
|
+
its(:references_urls) do
|
|
59
|
+
should eql [
|
|
60
|
+
'http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-11',
|
|
61
|
+
'https://secunia.com/advisories/12',
|
|
62
|
+
'http://osvdb.org/13',
|
|
63
|
+
'http://www.exploit-db.com/exploits/14/',
|
|
64
|
+
'single-url',
|
|
65
|
+
'http://www.rapid7.com/db/modules/exploit/yolo',
|
|
66
|
+
'http://packetstormsecurity.com/files/15/'
|
|
67
|
+
]
|
|
68
|
+
end
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
context 'when references provided as array' do
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cms_scanner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- WPScanTeam - Erwan Le Rousseau
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-02-
|
|
11
|
+
date: 2015-02-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: opt_parse_validator
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.0.
|
|
19
|
+
version: 0.0.8
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.0.
|
|
26
|
+
version: 0.0.8
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: typhoeus
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -259,6 +259,8 @@ files:
|
|
|
259
259
|
- lib/cms_scanner/finders/findings.rb
|
|
260
260
|
- lib/cms_scanner/finders/independent_finder.rb
|
|
261
261
|
- lib/cms_scanner/finders/independent_finders.rb
|
|
262
|
+
- lib/cms_scanner/finders/same_type_finder.rb
|
|
263
|
+
- lib/cms_scanner/finders/same_type_finders.rb
|
|
262
264
|
- lib/cms_scanner/finders/unique_finder.rb
|
|
263
265
|
- lib/cms_scanner/finders/unique_finders.rb
|
|
264
266
|
- lib/cms_scanner/formatter.rb
|
|
@@ -337,6 +339,8 @@ files:
|
|
|
337
339
|
- spec/lib/finders/finder/smart_url_checker_spec.rb
|
|
338
340
|
- spec/lib/finders/findings_spec.rb
|
|
339
341
|
- spec/lib/finders/independent_finders_spec.rb
|
|
342
|
+
- spec/lib/finders/same_type_finder_spec.rb
|
|
343
|
+
- spec/lib/finders/same_type_finders_spec.rb
|
|
340
344
|
- spec/lib/finders/unique_finder_spec.rb
|
|
341
345
|
- spec/lib/finders/unique_finders_spec.rb
|
|
342
346
|
- spec/lib/formatter_spec.rb
|
|
@@ -454,6 +458,8 @@ test_files:
|
|
|
454
458
|
- spec/lib/finders/finder/smart_url_checker_spec.rb
|
|
455
459
|
- spec/lib/finders/findings_spec.rb
|
|
456
460
|
- spec/lib/finders/independent_finders_spec.rb
|
|
461
|
+
- spec/lib/finders/same_type_finder_spec.rb
|
|
462
|
+
- spec/lib/finders/same_type_finders_spec.rb
|
|
457
463
|
- spec/lib/finders/unique_finder_spec.rb
|
|
458
464
|
- spec/lib/finders/unique_finders_spec.rb
|
|
459
465
|
- spec/lib/formatter_spec.rb
|