cms_scanner 0.0.6 → 0.0.7

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/finders/interesting_files/xml_rpc.rb +1 -3
  3. data/app/models.rb +1 -0
  4. data/app/models/interesting_file.rb +0 -4
  5. data/app/models/version.rb +17 -0
  6. data/app/views/cli/core/finished.erb +0 -1
  7. data/app/views/cli/interesting_files/findings.erb +1 -1
  8. data/cms_scanner.gemspec +2 -2
  9. data/lib/cms_scanner.rb +1 -0
  10. data/lib/cms_scanner/finders.rb +2 -0
  11. data/lib/cms_scanner/finders/finding.rb +4 -0
  12. data/lib/cms_scanner/finders/independent_finders.rb +1 -1
  13. data/lib/cms_scanner/finders/unique_finder.rb +17 -0
  14. data/lib/cms_scanner/finders/unique_finders.rb +39 -0
  15. data/lib/cms_scanner/target.rb +1 -0
  16. data/lib/cms_scanner/target/platform/wordpress.rb +2 -4
  17. data/lib/cms_scanner/target/platform/wordpress/custom_directories.rb +1 -2
  18. data/lib/cms_scanner/target/server/apache.rb +3 -2
  19. data/lib/cms_scanner/target/server/iis.rb +1 -2
  20. data/lib/cms_scanner/typhoeus/response.rb +9 -0
  21. data/lib/cms_scanner/version.rb +1 -1
  22. data/spec/app/controllers/core_spec.rb +0 -2
  23. data/spec/app/controllers/interesting_files_spec.rb +0 -2
  24. data/spec/app/finders/interesting_files/fantastico_fileslist_spec.rb +0 -2
  25. data/spec/app/finders/interesting_files/headers_spec.rb +0 -2
  26. data/spec/app/finders/interesting_files/robots_txt_spec.rb +0 -2
  27. data/spec/app/finders/interesting_files/search_replace_db_2_spec.rb +0 -2
  28. data/spec/app/finders/interesting_files/xml_rpc_spec.rb +0 -2
  29. data/spec/app/finders/interesting_files_spec.rb +1 -2
  30. data/spec/app/formatters/cli_no_colour_spec.rb +0 -2
  31. data/spec/app/formatters/cli_spec.rb +0 -2
  32. data/spec/app/formatters/json_spec.rb +0 -2
  33. data/spec/app/models/fantastico_fileslist_spec.rb +0 -1
  34. data/spec/app/models/headers_spec.rb +0 -1
  35. data/spec/app/models/interesting_file_spec.rb +0 -2
  36. data/spec/app/models/robots_txt_spec.rb +0 -1
  37. data/spec/app/models/version_spec.rb +23 -0
  38. data/spec/app/models/xml_rpc_spec.rb +0 -1
  39. data/spec/app/views_spec.rb +0 -2
  40. data/spec/dummy_finding.rb +21 -0
  41. data/spec/dummy_independent_finders.rb +25 -0
  42. data/spec/dummy_unique_finders.rb +32 -0
  43. data/spec/lib/browser_spec.rb +0 -1
  44. data/spec/lib/cache/file_store_spec.rb +0 -1
  45. data/spec/lib/cache/typhoeus_spec.rb +0 -2
  46. data/spec/lib/cms_scanner_spec.rb +0 -1
  47. data/spec/lib/controller_spec.rb +0 -2
  48. data/spec/lib/controllers_spec.rb +0 -2
  49. data/spec/lib/finders/findings_spec.rb +1 -3
  50. data/spec/lib/finders/independent_finders_spec.rb +4 -6
  51. data/spec/lib/finders/unique_finder_spec.rb +24 -0
  52. data/spec/lib/finders/unique_finders_spec.rb +133 -0
  53. data/spec/lib/formatter_spec.rb +0 -3
  54. data/spec/lib/target_spec.rb +0 -2
  55. data/spec/lib/web_site_spec.rb +0 -3
  56. data/spec/output/core/finished.cli_no_colour +0 -1
  57. data/spec/output/interesting_files/empty.cli_no_colour +1 -0
  58. data/spec/output/interesting_files/findings.cli_no_colour +1 -0
  59. data/spec/shared_examples/browser_actions.rb +0 -2
  60. data/spec/shared_examples/finding.rb +21 -1
  61. data/spec/shared_examples/formatter_buffer.rb +0 -2
  62. data/spec/shared_examples/independent_finder.rb +1 -3
  63. data/spec/shared_examples/target/platform/php.rb +0 -1
  64. data/spec/shared_examples/target/platform/wordpress.rb +0 -2
  65. data/spec/shared_examples/target/server/apache.rb +0 -1
  66. data/spec/shared_examples/target/server/generic.rb +0 -1
  67. data/spec/shared_examples/target/server/iis.rb +0 -1
  68. data/spec/shared_examples/views/core.rb +0 -1
  69. data/spec/shared_examples/views/interesting_files.rb +0 -1
  70. metadata +21 -7
  71. data/spec/dummy_finders.rb +0 -41
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Headers do
4
-
5
4
  subject(:file) { described_class.new(url) }
6
5
  let(:url) { 'http://example.com/' }
7
6
  let(:fixtures) { File.join(FIXTURES, 'interesting_files', 'headers') }
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::InterestingFile do
4
-
5
4
  it_behaves_like CMSScanner::Finders::Finding
6
5
 
7
6
  subject(:file) { described_class.new(url, opts) }
@@ -47,5 +46,4 @@ describe CMSScanner::InterestingFile do
47
46
  end
48
47
  end
49
48
  end
50
-
51
49
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::RobotsTxt do
4
-
5
4
  subject(:file) { described_class.new(url) }
6
5
  let(:url) { 'http://example.com/robots.txt' }
7
6
  let(:fixtures) { File.join(FIXTURES, 'interesting_files', 'robots_txt') }
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe CMSScanner::Version do
4
+ it_behaves_like CMSScanner::Finders::Finding
5
+
6
+ subject(:version) { described_class.new(number, opts) }
7
+ let(:opts) { {} }
8
+ let(:number) { '1.0' }
9
+
10
+ describe '#==' do
11
+ context 'when same @number' do
12
+ it 'returns true' do
13
+ expect(version == described_class.new(number)).to be true
14
+ end
15
+ end
16
+
17
+ context 'when not the same @number' do
18
+ it 'returns false' do
19
+ expect(version == described_class.new('3.0')).to be false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::XMLRPC do
4
-
5
4
  subject(:xml_rpc) { described_class.new(url) }
6
5
  let(:url) { 'http://example.com/xmlrpc' }
7
6
 
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'App::Views' do
4
-
5
4
  let(:target_url) { 'http://ex.lo/' }
6
5
  let(:fixtures) { File.join(SPECS, 'output') }
7
6
 
@@ -9,7 +8,6 @@ describe 'App::Views' do
9
8
  # in the expected output.
10
9
  [:JSON, :CliNoColour].each do |formatter|
11
10
  context "when #{formatter}" do
12
-
13
11
  it_behaves_like 'App::Views::Core'
14
12
  it_behaves_like 'App::Views::InterestingFiles'
15
13
 
@@ -0,0 +1,21 @@
1
+ module CMSScanner
2
+ # Dummy Finding
3
+ class DummyFinding
4
+ include Finders::Finding
5
+
6
+ attr_reader :r
7
+
8
+ def initialize(r, opts = {})
9
+ @r = r
10
+ parse_finding_options(opts)
11
+ end
12
+
13
+ def ==(other)
14
+ r == other.r
15
+ end
16
+
17
+ def eql?(other)
18
+ r == other.r && confidence == other.confidence && found_by == other.found_by
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'dummy_finding'
2
+
3
+ module CMSScanner
4
+ module Finders
5
+ module Independent
6
+ # Dummy Test Finder
7
+ class DummyFinder < Finder
8
+ def passive(_opts = {})
9
+ DummyFinding.new('test', found_by: found_by)
10
+ end
11
+
12
+ def aggressive(_opts = {})
13
+ DummyFinding.new('test', confidence: 100, found_by: 'override')
14
+ end
15
+ end
16
+
17
+ # No aggressive result finder
18
+ class NoAggressiveResult < Finder
19
+ def passive(_opts = {})
20
+ DummyFinding.new('spotted', confidence: 10, found_by: found_by)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ require 'dummy_finding'
2
+
3
+ module CMSScanner
4
+ module Finders
5
+ module Unique
6
+ # Dummy Test Finder
7
+ class Dummy < Finder
8
+ def passive(_opts = {})
9
+ DummyFinding.new('v1', found_by: found_by)
10
+ end
11
+
12
+ def aggressive(_opts = {})
13
+ DummyFinding.new('v1', confidence: 100, found_by: 'override')
14
+ end
15
+ end
16
+
17
+ # No aggressive result
18
+ class NoAggressive < Finder
19
+ def passive(_opts = {})
20
+ DummyFinding.new('v2', confidence: 10, found_by: found_by)
21
+ end
22
+ end
23
+
24
+ # Dummy2
25
+ class Dummy2 < Finder
26
+ def aggressive(_opts = {})
27
+ DummyFinding.new('v1', confidence: 90)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Browser do
4
-
5
4
  it_behaves_like described_class::Actions
6
5
 
7
6
  subject(:browser) { described_class.instance(options) }
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Cache::FileStore do
4
-
5
4
  let(:cache_dir) { File.join(CACHE, 'cache_file_store') }
6
5
  subject(:cache) { described_class.new(cache_dir) }
7
6
 
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Cache::Typhoeus do
4
-
5
4
  subject(:cache) { described_class.new(cache_dir) }
6
5
 
7
6
  let(:cache_dir) { File.join(CACHE, 'typhoeus_cache') }
@@ -26,5 +25,4 @@ describe CMSScanner::Cache::Typhoeus do
26
25
  cache.set(request, response)
27
26
  end
28
27
  end
29
-
30
28
  end
@@ -12,7 +12,6 @@ module CMSScanner
12
12
  end
13
13
 
14
14
  describe CMSScanner::Scan do
15
-
16
15
  subject(:scanner) { described_class.new }
17
16
  let(:controller) { CMSScanner::Controller }
18
17
 
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Controller do
4
-
5
4
  subject(:controller) { described_class::Base.new }
6
5
 
7
6
  context 'when parsed_options' do
@@ -20,5 +19,4 @@ describe CMSScanner::Controller do
20
19
  end
21
20
  end
22
21
  end
23
-
24
22
  end
@@ -8,7 +8,6 @@ module CMSScanner
8
8
  end
9
9
 
10
10
  describe CMSScanner::Controllers do
11
-
12
11
  subject(:controllers) { described_class.new }
13
12
  let(:controller_mod) { CMSScanner::Controller }
14
13
 
@@ -46,5 +45,4 @@ describe CMSScanner::Controllers do
46
45
  controllers.run
47
46
  end
48
47
  end
49
-
50
48
  end
@@ -1,8 +1,7 @@
1
1
  require 'spec_helper'
2
- require 'dummy_finders'
2
+ require 'dummy_finding'
3
3
 
4
4
  describe CMSScanner::Finders::Findings do
5
-
6
5
  subject(:findings) { described_class.new }
7
6
  let(:dummy) { CMSScanner::DummyFinding }
8
7
 
@@ -45,5 +44,4 @@ describe CMSScanner::Finders::Findings do
45
44
  @expected = %w(test1 test2)
46
45
  end
47
46
  end
48
-
49
47
  end
@@ -1,8 +1,7 @@
1
1
  require 'spec_helper'
2
- require 'dummy_finders'
2
+ require 'dummy_independent_finders'
3
3
 
4
4
  describe CMSScanner::Finders::IndependentFinders do
5
-
6
5
  subject(:finders) { described_class.new }
7
6
 
8
7
  describe '#run' do
@@ -18,11 +17,11 @@ describe CMSScanner::Finders::IndependentFinders do
18
17
 
19
18
  before do
20
19
  finders <<
21
- CMSScanner::Finders::DummyFinder.new(target) <<
22
- CMSScanner::Finders::NoAggressiveResult.new(target)
20
+ CMSScanner::Finders::Independent::DummyFinder.new(target) <<
21
+ CMSScanner::Finders::Independent::NoAggressiveResult.new(target)
23
22
  end
24
23
 
25
- describe 'method call orders' do
24
+ describe 'method calls order' do
26
25
  after { finders.run(mode: mode) }
27
26
 
28
27
  [:passive, :aggressive].each do |current_mode|
@@ -130,5 +129,4 @@ describe CMSScanner::Finders::IndependentFinders do
130
129
  expect(finders.findings).to be_a CMSScanner::Finders::Findings
131
130
  end
132
131
  end
133
-
134
132
  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 VersionFinderSpec
7
+ include UniqueFinder
8
+
9
+ def initialize(_target)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ describe CMSScanner::Finders::VersionFinderSpec do
16
+ it_behaves_like CMSScanner::Finders::IndependentFinder do
17
+ let(:expected_finders) { [] }
18
+ let(:expected_finders_class) { CMSScanner::Finders::UniqueFinders }
19
+ end
20
+
21
+ subject(:version) { described_class.new(target) }
22
+ let(:target) { CMSScanner::Target.new(url) }
23
+ let(:url) { 'http://example.com/' }
24
+ end
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+ require 'dummy_unique_finders'
3
+
4
+ describe CMSScanner::Finders::UniqueFinders do
5
+ subject(:finders) { described_class.new }
6
+
7
+ describe '#run' do
8
+ let(:target) { 'target' }
9
+ let(:finding) { CMSScanner::DummyFinding }
10
+ let(:unique_finders) { CMSScanner::Finders::Unique }
11
+ let(:opts) { {} }
12
+
13
+ before do
14
+ finders <<
15
+ unique_finders::Dummy.new(target) <<
16
+ unique_finders::NoAggressive.new(target) <<
17
+ unique_finders::Dummy2.new(target)
18
+ end
19
+
20
+ after do
21
+ result = finders.run(opts)
22
+
23
+ expect(result).to be_a finding
24
+ expect(result).to eql @expected
25
+ end
26
+
27
+ # Used to be able to test the calls order and returned result at the same time
28
+ let(:dummy_passive) { unique_finders::Dummy.new(target).passive(opts) }
29
+ let(:dummy_aggresssive) { unique_finders::Dummy.new(target).aggressive(opts) }
30
+ let(:noaggressive) { unique_finders::NoAggressive.new(target).passive(opts) }
31
+ let(:dummy2_aggressive) { unique_finders::Dummy2.new(target).aggressive }
32
+
33
+ context 'when :confidence_threshold <= 0' do
34
+ let(:opts) { super().merge(confidence_threshold: 0) }
35
+
36
+ context 'when :mixed mode' do
37
+ let(:opts) { super().merge(mode: :mixed) }
38
+
39
+ it 'calls all #passive then #aggressive on finders and returns the best result' do
40
+ # Maybe there is a way to factorise this
41
+ expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
42
+ expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
43
+ expect(finders[2]).to receive(:passive).ordered
44
+ expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
45
+ expect(finders[1]).to receive(:aggressive).ordered
46
+ expect(finders[2]).to receive(:aggressive).ordered.and_return(dummy2_aggressive)
47
+
48
+ @expected = finding.new('v1', confidence: 100, found_by: 'Dummy (passive detection)')
49
+ @expected.confirmed_by << finding.new('v1', confidence: 100, found_by: 'override')
50
+ @expected.confirmed_by << finding.new('v1', confidence: 90)
51
+ end
52
+ end
53
+
54
+ context 'when :passive mode' do
55
+ let(:opts) { super().merge(mode: :passive) }
56
+
57
+ it 'calls #passive on all finders and returns the best result' do
58
+ expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
59
+ expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
60
+ expect(finders[2]).to receive(:passive).ordered
61
+
62
+ finders.each { |f| expect(f).to_not receive(:aggressive) }
63
+
64
+ @expected = finding.new('v2', confidence: 10,
65
+ found_by: 'NoAggressive (passive detection)')
66
+ end
67
+ end
68
+
69
+ context 'when :aggressive mode' do
70
+ let(:opts) { super().merge(mode: :aggressive) }
71
+
72
+ it 'calls #aggressive on all finders and returns the best result' do
73
+ finders.each { |f| expect(f).to_not receive(:passive) }
74
+
75
+ expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
76
+ expect(finders[1]).to receive(:aggressive).ordered
77
+ expect(finders[2]).to receive(:aggressive).ordered.and_return(dummy2_aggressive)
78
+
79
+ @expected = finding.new('v1', confidence: 100, found_by: 'override')
80
+ @expected.confirmed_by << finding.new('v1', confidence: 90)
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'when :confidence_threshold = 100 (default)' do
86
+ context 'when :mixed mode' do
87
+ let(:opts) { super().merge(mode: :mixed) }
88
+
89
+ it 'calls all #passive then #aggressive methods on finders and returns the '\
90
+ 'result which reaches 100% confidence during the process' do
91
+ expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
92
+ expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
93
+ expect(finders[2]).to receive(:passive).ordered
94
+ expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
95
+ expect(finders[1]).to_not receive(:aggressive)
96
+ expect(finders[2]).to_not receive(:aggressive)
97
+
98
+ @expected = finding.new('v1', confidence: 100, found_by: 'Dummy (passive detection)')
99
+ @expected.confirmed_by << finding.new('v1', confidence: 100, found_by: 'override')
100
+ end
101
+ end
102
+
103
+ context 'when :passive mode' do
104
+ let(:opts) { super().merge(mode: :passive) }
105
+
106
+ it 'calls all #passive and returns the best result' do
107
+ expect(finders[0]).to receive(:passive).ordered.and_return(dummy_passive)
108
+ expect(finders[1]).to receive(:passive).ordered.and_return(noaggressive)
109
+ expect(finders[2]).to receive(:passive).ordered
110
+
111
+ finders.each { |f| expect(f).to_not receive(:aggressive) }
112
+
113
+ @expected = finding.new('v2', confidence: 10,
114
+ found_by: 'NoAggressive (passive detection)')
115
+ end
116
+ end
117
+
118
+ context 'when :aggressive mode' do
119
+ let(:opts) { super().merge(mode: :aggressive) }
120
+
121
+ it 'calls all #aggressive and returns the result which reaches 100% confidence' do
122
+ finders.each { |f| expect(f).to_not receive(:passive) }
123
+
124
+ expect(finders[0]).to receive(:aggressive).ordered.and_return(dummy_aggresssive)
125
+ expect(finders[1]).to_not receive(:aggressive)
126
+ expect(finders[2]).to_not receive(:aggressive)
127
+
128
+ @expected = finding.new('v1', confidence: 100, found_by: 'override')
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end