cms_scanner 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b776de3125da0037eef520d8cf0f69caa17a9f22
4
- data.tar.gz: 1f328394f7c5395b8b3191ee37e98627f0b90d0c
3
+ metadata.gz: e4c298cb52add0fd3b06836ec3d5f5acc7fcc06c
4
+ data.tar.gz: 32c3dec825b5d3641b86938ea2641bafb34cc0bd
5
5
  SHA512:
6
- metadata.gz: f1b3aa71d953d878b8bbebdf70372ecaf7eb89352638008748d7b5cad16f4378c9ee26534042bf2c1ed32268c5f4b4e4a95ed1b88eab0186dfd0ef2bc4133d7b
7
- data.tar.gz: 1cfa9bb846e83bdf8702295f62049c175d850a9e19eae1bdc73d8a882690b298ab127056866355792f37126bd0a4257756128c5e4878d46835096f77913dcc19
6
+ metadata.gz: 4444cb50bf62d3b2715bd49054a539ae058aa234b4f27d013b6dda5fa5bfcc4664fd270e85a00f82d3de99add49729223f4f5333146262f92ad67360ea4d6665
7
+ data.tar.gz: dbd2746ebc6b5912d4bf3c828dbc413499d0b1e306dc2826dc8572017a5025adfa9a1b0c4528a49bd44ae5a704a3cee0c04e719376907679e97926913d88166d
data/.rubocop.yml CHANGED
@@ -5,6 +5,6 @@ ClassVars:
5
5
  MethodLength:
6
6
  Max: 15
7
7
  Metrics/AbcSize:
8
- Max: 20
8
+ Max: 22
9
9
  Metrics/CyclomaticComplexity:
10
10
  Max: 10
@@ -14,6 +14,8 @@ module CMSScanner
14
14
  end
15
15
 
16
16
  def before_scan
17
+ output('banner')
18
+
17
19
  setup_cache
18
20
 
19
21
  fail "The url supplied '#{target.url}' seems to be down" unless target.online?
@@ -1,4 +1,3 @@
1
- <%= render('banner') -%>
2
1
  <%= green('[+]') %> URL: <%= @url %>
3
2
  <%= green('[+]') %> Started: <%= @start_time.asctime %>
4
3
 
data/cms_scanner.gemspec CHANGED
@@ -21,12 +21,13 @@ 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.8'
24
+ s.add_dependency 'opt_parse_validator', '~> 0.0.9'
25
25
  s.add_dependency 'typhoeus', '~> 0.7'
26
26
  s.add_dependency 'nokogiri', '~> 1.6'
27
27
  s.add_dependency 'addressable', '~> 2.3'
28
28
  s.add_dependency 'activesupport', '~> 4.2'
29
29
  s.add_dependency 'public_suffix', '~> 1.4'
30
+ s.add_dependency 'ruby-progressbar', '~> 1.7.1'
30
31
 
31
32
  s.add_development_dependency 'rake', '~> 10.4'
32
33
  s.add_development_dependency 'rspec', '~> 3.2'
data/lib/cms_scanner.rb CHANGED
@@ -5,6 +5,7 @@ require 'nokogiri'
5
5
  require 'active_support/inflector'
6
6
  require 'addressable/uri'
7
7
  require 'public_suffix'
8
+ require 'ruby-progressbar'
8
9
  # Standard Libs
9
10
  require 'erb'
10
11
  require 'fileutils'
@@ -57,6 +58,10 @@ module CMSScanner
57
58
  trace: e.backtrace,
58
59
  verbose: controllers.first.parsed_options[:verbose])
59
60
  ensure
61
+ # Ensures a clean abort of Hydra
62
+ Browser.instance.hydra.abort
63
+ Browser.instance.hydra.run
64
+
60
65
  formatter.beautify
61
66
  end
62
67
 
@@ -61,6 +61,11 @@ module CMSScanner
61
61
  formatter.render(*tpl_params(tpl, vars))
62
62
  end
63
63
 
64
+ # @return [ Boolean ]
65
+ def user_interaction?
66
+ formatter.user_interaction? && !parsed_options[:output]
67
+ end
68
+
64
69
  protected
65
70
 
66
71
  # @param [ String ] tpl
@@ -1,4 +1,5 @@
1
1
  require 'cms_scanner/finders/finder/smart_url_checker'
2
+ require 'cms_scanner/finders/finder/enumerator'
2
3
 
3
4
  module CMSScanner
4
5
  module Finders
@@ -0,0 +1,72 @@
1
+ module CMSScanner
2
+ module Finders
3
+ class Finder
4
+ # Module to provide an easy way to enumerate items such as plugins, themes etc
5
+ module Enumerator
6
+ # @param [ Hash ] opts
7
+ # @option opts [ Boolean ] :show_progression Wether or not to display the progress bar
8
+ # @option opts [ Regexp ] :exclude_content
9
+ #
10
+ # @yield [ Typhoeus::Response, String ]
11
+ def enumerate(opts = {})
12
+ targets = target_urls(opts)
13
+ bar = progress_bar(targets.size) if opts[:show_progression]
14
+
15
+ targets.each do |url, id|
16
+ request = browser.forge_request(url, request_params)
17
+
18
+ request.on_complete do |res|
19
+ bar.progress += 1 if opts[:show_progression]
20
+
21
+ next if target.homepage_or_404?(res)
22
+ next if opts[:exclude_content] && res.body.match(opts[:exclude_content])
23
+
24
+ yield res, id
25
+ end
26
+
27
+ hydra.queue(request)
28
+ end
29
+
30
+ hydra.run
31
+ end
32
+
33
+ # @param [ Hash ] opts
34
+ #
35
+ # @return [ Hash ]
36
+ def target_urls(_opts = {})
37
+ fail NotImplementedError
38
+ end
39
+
40
+ # @param [ Integer ] total
41
+ #
42
+ # @return [ ProgressBar ]
43
+ # :nocov:
44
+ def progress_bar(total)
45
+ ProgressBar.create(
46
+ format: '%t %a <%B> (%c / %C) %P%% %e',
47
+ title: ' ', # Used to craete a left margin
48
+ total: total
49
+ )
50
+ end
51
+ # :nocov:
52
+
53
+ # @return [ CMSScanner::Browser ]
54
+ def browser
55
+ @browser ||= NS::Browser.instance
56
+ end
57
+
58
+ def request_params
59
+ # disabling the cache, as it causes a 'stack level too deep' exception
60
+ # with a large number of requests :/
61
+ # See https://github.com/typhoeus/typhoeus/issues/408
62
+ { cache_ttl: 0 }
63
+ end
64
+
65
+ # @return [ Typhoeus::Hydra ]
66
+ def hydra
67
+ @hydra ||= browser.hydra
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -58,6 +58,11 @@ module CMSScanner
58
58
  self.class.name.demodulize.underscore
59
59
  end
60
60
 
61
+ # @return [ Boolean ]
62
+ def user_interaction?
63
+ format == 'cli'
64
+ end
65
+
61
66
  # @return [ String ] The underscored format to use as a base
62
67
  def base_format; end
63
68
 
@@ -14,13 +14,13 @@ module CMSScanner
14
14
 
15
15
  # @return [ String ] The hash of the homepage
16
16
  def homepage_hash
17
- @homepage_hash ||= Target.page_hash(url)
17
+ @homepage_hash ||= self.class.page_hash(url)
18
18
  end
19
19
 
20
20
  # @note This is used to detect potential custom 404 responding with a 200
21
21
  # @return [ String ] The hash of a 404
22
22
  def error_404_hash
23
- @error_404_hash ||= Target.page_hash(non_existant_page_url)
23
+ @error_404_hash ||= self.class.page_hash(non_existant_page_url)
24
24
  end
25
25
 
26
26
  # @return [ String ] The URL of an unlikely existant page
@@ -31,7 +31,7 @@ module CMSScanner
31
31
  # @param [ Typhoeus::Response, String ] page
32
32
  # @return [ Boolean ] Wether or not the page is a the homepage or a 404 based on its md5sum
33
33
  def homepage_or_404?(page)
34
- md5sum = Target.page_hash(page)
34
+ md5sum = self.class.page_hash(page)
35
35
 
36
36
  md5sum == homepage_hash || md5sum == error_404_hash
37
37
  end
@@ -1,4 +1,4 @@
1
1
  # Version
2
2
  module CMSScanner
3
- VERSION = '0.0.14'
3
+ VERSION = '0.0.15'
4
4
  end
@@ -36,6 +36,8 @@ describe CMSScanner::Controller::Core do
36
36
  end
37
37
 
38
38
  describe '#before_scan' do
39
+ before { expect(core.formatter).to receive(:output) }
40
+
39
41
  it 'does not raise an error when everything is fine' do
40
42
  stub_request(:get, target_url).to_return(status: 200)
41
43
 
@@ -3,9 +3,8 @@ require 'spec_helper'
3
3
  describe CMSScanner::Formatter::CliNoColour do
4
4
  subject(:formatter) { described_class.new }
5
5
 
6
- describe '#format' do
7
- its(:format) { should eq 'cli' }
8
- end
6
+ its(:format) { should eq 'cli' }
7
+ its(:user_interaction?) { should be true }
9
8
 
10
9
  describe '#colorize' do
11
10
  it 'returns the text w/o any colour' do
@@ -3,9 +3,8 @@ require 'spec_helper'
3
3
  describe CMSScanner::Formatter::Cli do
4
4
  subject(:formatter) { described_class.new }
5
5
 
6
- describe '#format' do
7
- its(:format) { should eq 'cli' }
8
- end
6
+ its(:format) { should eq 'cli' }
7
+ its(:user_interaction?) { should be true }
9
8
 
10
9
  describe '#bold, #red, #green, #amber, #blue, #colorize' do
11
10
  it 'returns the correct bold string' do
@@ -8,9 +8,8 @@ describe CMSScanner::Formatter::Json do
8
8
 
9
9
  before { formatter.views_directories << FIXTURES_VIEWS }
10
10
 
11
- describe '#format' do
12
- its(:format) { should eq 'json' }
13
- end
11
+ its(:format) { should eq 'json' }
12
+ its(:user_interaction?) { should be false }
14
13
 
15
14
  describe '#output' do
16
15
  it 'puts the rendered text in the buffer' do
@@ -21,8 +21,13 @@ describe CMSScanner::Scan do
21
21
 
22
22
  describe '#run' do
23
23
  it 'runs the controlllers and calls the formatter#beautify' do
24
+ hydra = CMSScanner::Browser.instance.hydra
25
+
24
26
  expect(scanner.controllers).to receive(:run).ordered
27
+ expect(hydra).to receive(:abort).ordered
28
+ expect(hydra).to receive(:run).ordered
25
29
  expect(scanner.formatter).to receive(:beautify).ordered
30
+
26
31
  scanner.run
27
32
  end
28
33
 
@@ -10,9 +10,16 @@ describe CMSScanner::Controller do
10
10
 
11
11
  its(:parsed_options) { should eq(parsed_options) }
12
12
  its(:formatter) { should be_a CMSScanner::Formatter::Cli }
13
+ its(:user_interaction?) { should be true }
13
14
  its(:target) { should be_a CMSScanner::Target }
14
15
  its('target.scope.domains') { should eq [PublicSuffix.parse('example.com')] }
15
16
 
17
+ context 'when output option' do
18
+ let(:parsed_options) { super().merge(output: '/tmp/spec.txt') }
19
+
20
+ its(:user_interaction?) { should be false }
21
+ end
22
+
16
23
  describe '#render' do
17
24
  it 'calls the formatter#render' do
18
25
  expect(controller.formatter).to receive(:render).with('test', { verbose: nil }, 'base')
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe CMSScanner::Finders::Finder::Enumerator do
4
+ # Dummy class to test the module
5
+ class DummyFinder < CMSScanner::Finders::Finder
6
+ include CMSScanner::Finders::Finder::Enumerator
7
+ end
8
+
9
+ subject(:finder) { DummyFinder.new(target) }
10
+ let(:target) { CMSScanner::Target.new('http://e.org') }
11
+
12
+ context 'when #target_urls not implemented' do
13
+ it 'raises errors' do
14
+ expect { finder.target_urls }.to raise_error NotImplementedError
15
+ end
16
+ end
17
+
18
+ describe '#progress_bar' do
19
+ it 'returns a ProgressBar' do
20
+ expect(finder.progress_bar(2)).to be_a ProgressBar::Base
21
+ end
22
+ end
23
+
24
+ its(:browser) { should be_a CMSScanner::Browser }
25
+
26
+ its(:request_params) { should eql(cache_ttl: 0) }
27
+
28
+ its(:hydra) { should be_a Typhoeus::Hydra }
29
+
30
+ describe '#aggressive' do
31
+ before do
32
+ expect(finder).to receive(:target_urls).and_return(target_urls)
33
+ target_urls.each { |url, _| stub_request(:get, url).to_return(status: 200, body: 'rspec') }
34
+ end
35
+
36
+ let(:target_urls) do
37
+ {
38
+ target.url('1') => 1,
39
+ target.url('2') => 2
40
+ }
41
+ end
42
+
43
+ context 'when no opts' do
44
+ let(:opts) { {} }
45
+
46
+ context 'when response are the homepage or custom 404' do
47
+ before { expect(finder.target).to receive(:homepage_or_404?).twice.and_return(true) }
48
+
49
+ it 'does not yield anything' do
50
+ expect { |b| finder.enumerate(opts, &b) }.to_not yield_control
51
+ end
52
+ end
53
+
54
+ context 'when not the hompage or 404' do
55
+ before { expect(finder.target).to receive(:homepage_or_404?).twice }
56
+
57
+ it 'yield the expected items' do
58
+ expect { |b| finder.enumerate(opts, &b) }.to yield_successive_args(
59
+ [Typhoeus::Response, 1], [Typhoeus::Response, 2]
60
+ )
61
+ end
62
+ end
63
+ end
64
+
65
+ context 'when opts' do
66
+ context 'when :exclude_content' do
67
+ before { expect(finder.target).to receive(:homepage_or_404?).twice }
68
+
69
+ context 'when it matches' do
70
+ let(:opts) { { exclude_content: /spec/i } }
71
+
72
+ it 'does not yield anything' do
73
+ expect { |b| finder.enumerate(opts, &b) }.to_not yield_control
74
+ end
75
+ end
76
+
77
+ context 'when it does not match' do
78
+ let(:opts) { { exclude_content: /not/i } }
79
+
80
+ it 'yield the expected items' do
81
+ expect { |b| finder.enumerate(opts, &b) }.to yield_successive_args(
82
+ [Typhoeus::Response, 1], [Typhoeus::Response, 2]
83
+ )
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -33,6 +33,18 @@ describe CMSScanner::Formatter::Base do
33
33
  its(:format) { should eq 'base' }
34
34
  end
35
35
 
36
+ describe '#user_interaction?' do
37
+ context 'when not a cli format' do
38
+ its(:user_interaction?) { should be false }
39
+ end
40
+
41
+ context 'when a cli format' do
42
+ before { expect(formatter).to receive(:format).and_return('cli') }
43
+
44
+ its(:user_interaction?) { should be true }
45
+ end
46
+ end
47
+
36
48
  describe '#render, output' do
37
49
  before { formatter.views_directories << FIXTURES_VIEWS }
38
50
 
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.14
4
+ version: 0.0.15
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-18 00:00:00.000000000 Z
11
+ date: 2015-02-21 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.8
19
+ version: 0.0.9
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.8
26
+ version: 0.0.9
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: typhoeus
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-progressbar
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.7.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.7.1
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rake
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -253,6 +267,7 @@ files:
253
267
  - lib/cms_scanner/finders.rb
254
268
  - lib/cms_scanner/finders/confidence.rb
255
269
  - lib/cms_scanner/finders/finder.rb
270
+ - lib/cms_scanner/finders/finder/enumerator.rb
256
271
  - lib/cms_scanner/finders/finder/smart_url_checker.rb
257
272
  - lib/cms_scanner/finders/finder/smart_url_checker/findings.rb
258
273
  - lib/cms_scanner/finders/finding.rb
@@ -335,6 +350,7 @@ files:
335
350
  - spec/lib/controller_spec.rb
336
351
  - spec/lib/controllers_spec.rb
337
352
  - spec/lib/finders/confidence_spec.rb
353
+ - spec/lib/finders/finder/enumerator_spec.rb
338
354
  - spec/lib/finders/finder/smart_url_checker/findings_spec.rb
339
355
  - spec/lib/finders/finder/smart_url_checker_spec.rb
340
356
  - spec/lib/finders/findings_spec.rb
@@ -454,6 +470,7 @@ test_files:
454
470
  - spec/lib/controller_spec.rb
455
471
  - spec/lib/controllers_spec.rb
456
472
  - spec/lib/finders/confidence_spec.rb
473
+ - spec/lib/finders/finder/enumerator_spec.rb
457
474
  - spec/lib/finders/finder/smart_url_checker/findings_spec.rb
458
475
  - spec/lib/finders/finder/smart_url_checker_spec.rb
459
476
  - spec/lib/finders/findings_spec.rb