cms_scanner 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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